]> granicus.if.org Git - clang/commitdiff
[c++1z] Add some more tests for class template argument deduction, add
authorRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 14 Feb 2017 00:55:25 +0000 (00:55 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 14 Feb 2017 00:55:25 +0000 (00:55 +0000)
feature-test macro, and mark feature as done on status page.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@295011 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Frontend/InitPreprocessor.cpp
test/CXX/over/over.match/over.match.best/p1.cpp
test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp
test/Lexer/cxx-features.cpp
test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
www/cxx_status.html

index e5a07962d83b5c4938056f42b2d29ab93332b999..11d58ed2eb79e9ce0c1262930f40765d522abbb2 100644 (file)
@@ -522,6 +522,8 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts,
     Builder.defineMacro("__cpp_structured_bindings", "201606");
     Builder.defineMacro("__cpp_nontype_template_args", "201411");
     Builder.defineMacro("__cpp_fold_expressions", "201603");
+    // FIXME: This is not yet listed in SD-6.
+    Builder.defineMacro("__cpp_deduction_guides", "201611");
   }
   if (LangOpts.AlignedAllocation)
     Builder.defineMacro("__cpp_aligned_new", "201606");
index 59e3dac742832288518faa269d79efde1fa1f664..fad5bf9a72ee66e625c5b47a30c571b4b8e7aa3b 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z %s
 // expected-no-diagnostics
 
 template<typename T> int &f0(T*, int);
@@ -12,6 +12,28 @@ void test_f0(int* ip, void *vp) {
   float &fr = f0(vp, 0);
 }
 
+namespace deduction_guide_example {
+  template<typename T> struct A {
+    A(T, int*);
+    A(A<T>&, int*);
+    enum { value };
+  };
+
+  template<typename T> struct remove_ref_impl;
+  template<typename T> struct remove_ref_impl<T&> { using type = T; };
+  template<typename T> using remove_ref = typename remove_ref_impl<T>::type;
+
+  // FIXME: The standard's example is wrong; we add a remove_ref<...> here to
+  // fix it.
+  template<typename T, int N = remove_ref<T>::value> A(T&&, int*) -> A<T>;
+  A a{1, 0};
+  extern A<int> a;
+  A b{a, 0};
+
+  A<int> *pa = &a;
+  A<A<int>&> *pb = &b;
+}
+
 // Partial ordering of function template specializations will be tested 
 // elsewhere
 // FIXME: Initialization by user-defined conversion is tested elsewhere
index edc657c252e8d1be76d3bdde73c5d69273efa0cf..ebff0a1df4e7ba2633295d86547049433b9cb888 100644 (file)
@@ -73,4 +73,21 @@ namespace std_example {
   int n1 = f(i);
   int n2 = f(0);
   int n3 = g(i); // expected-error{{no matching function for call to 'g'}}
+
+#if __cplusplus > 201402L
+  template<class T> struct A { // expected-note {{candidate}}
+    template<class U>
+    A(T &&, U &&, int *); // expected-note {{[with T = int, U = int] not viable: no known conversion from 'int' to 'int &&'}}
+    A(T &&, int *);       // expected-note {{requires 2}}
+  };
+  template<class T> A(T &&, int *) -> A<T>; // expected-note {{requires 2}}
+
+  int *ip;
+  A a{i, 0, ip};  // expected-error {{no viable constructor or deduction guide}}
+  A a0{0, 0, ip};
+  A a2{i, ip};
+
+  A<int> &a0r = a0;
+  A<int&> &a2r = a2;
+#endif
 }
index 5fc1722e942b15a12e4527a22ec4fa999f429419..359deedbee7ad18fab4ae9a0e06002dee3d1bb83 100644 (file)
 #error "wrong value for __cpp_nontype_template_args"
 #endif
 
+#if check(template_template_args, 0, 0, 0, 0) // FIXME: should be 201611 when feature is enabled
+#error "wrong value for __cpp_template_template_args"
+#endif
+
+#if check(deduction_guides, 0, 0, 0, 201611) // FIXME: provisional name
+#error "wrong value for __cpp_deduction_guides"
+#endif
+
 // --- C++14 features ---
 
 #if check(binary_literals, 0, 0, 201304, 201304)
index 4743e38ba1c888ae44972aaddd9bcfb033e0f4d6..6b45a8bb2ae0fb9a5ba44324385ff20d6bc30f6c 100644 (file)
@@ -117,3 +117,23 @@ namespace dependent {
     g("foo"); // expected-note {{instantiation of}}
   }
 }
+
+namespace look_into_current_instantiation {
+  template<typename U> struct Q {};
+  template<typename T> struct A {
+    using U = T;
+    template<typename> using V = Q<A<T>::U>;
+    template<typename W = int> A(V<W>);
+  };
+  A a = Q<float>(); // ok, can look through class-scope typedefs and alias
+                    // templates, and members of the current instantiation
+  A<float> &r = a;
+
+  template<typename T> struct B { // expected-note {{could not match 'B<T>' against 'int'}}
+    struct X {
+      typedef T type;
+    };
+    B(typename X::type); // expected-note {{couldn't infer template argument 'T'}}
+  };
+  B b = 0; // expected-error {{no viable}}
+}
index 6adf7fda8aeecddbac48ba0e4de00746665c0faf..6216a816455b794a7ffa5bfdd540d56cdb656cff 100644 (file)
@@ -684,11 +684,11 @@ as the draft C++1z standard evolves.
     <tr>
       <td rowspan="2">Template argument deduction for class templates</td>
       <td><a href="http://wg21.link/p0091r3">P0091R3</a></td>
-      <td class="partial" align="center">Partial</td>
+      <td class="svn" align="center">SVN</td>
     </tr>
       <tr> <!-- from Issaquah -->
         <td><a href="http://wg21.link/p0512r0">P0512R0</a></td>
-        <td class="partial" align="center">Partial</td>
+        <td class="svn" align="center">SVN</td>
       </tr>
     <tr>
       <td>Non-type template parameters with <tt>auto</tt> type</td>