xref: /llvm-project/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp (revision 4f53b51fe7665f7f899a2fa2905d72f69ec01c4f)
1 // RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -verify %s
2 
3 template<typename T> struct A {}; // expected-note 31{{declared here}}
4 
5 // Make sure we still correctly parse cases where a template can appear without arguments.
6 namespace template_template_arg {
7   template<template<typename> typename> struct X {};
8   template<typename> struct Y {};
9 
10   X<A> xa;
11   Y<A> ya; // expected-error {{requires template arguments}}
12   X<::A> xcca;
13   Y<::A> ycca; // expected-error {{requires template arguments}}
14 
15   template<template<typename> typename = A> struct XD {};
16   template<typename = A> struct YD {}; // expected-error {{requires template arguments}}
17   template<template<typename> typename = ::A> struct XCCD {};
18   template<typename = ::A> struct YCCD {}; // expected-error {{requires template arguments}}
19 
20   // FIXME: replacing the invalid type with 'int' here is horrible
21   template <A a = A<int>()> class C { }; // expected-error {{requires template arguments}} expected-error {{not implicitly convertible to 'int'}}
22   template<typename T = A> struct G { }; // expected-error {{requires template arguments}}
23 }
24 
25 namespace injected_class_name {
26   template<typename T> struct A {
27     A(T);
28     void f(int) {
29       A a = 1;
30       injected_class_name::A b = 1; // expected-error {{not yet supported}}
31     }
32     void f(T);
33   };
34   A<short> ai = 1;
35   A<double>::A b(1); // expected-error {{constructor name}}
36 }
37 
38 struct member {
39   A a; // expected-error {{requires template arguments}}
40   A *b; // expected-error {{requires template arguments}}
41   const A c; // expected-error {{requires template arguments}}
42 
43   void f() throw (A); // expected-error {{requires template arguments}}
44 
45   friend A; // expected-error {{requires template arguments; argument deduction not allowed in friend declaration}}
46 
47   operator A(); // expected-error {{requires template arguments; argument deduction not allowed in conversion function type}}
48 
49   static A x; // expected-error {{requires an initializer}}
50   static A y = 0; // expected-error {{not yet supported}}
51 };
52 
53 namespace in_typedef {
54   typedef A *AutoPtr; // expected-error {{requires template arguments; argument deduction not allowed in typedef}}
55   typedef A (*PFun)(int a); // expected-error{{requires template arguments; argument deduction not allowed in typedef}}
56   typedef A Fun(int a) -> decltype(a + a); // expected-error{{requires template arguments; argument deduction not allowed in function return type}}
57 }
58 
59 namespace stmt {
60   void g(A a) { // expected-error{{requires template arguments; argument deduction not allowed in function prototype}}
61     try { }
62     catch (A &a) { } // expected-error{{requires template arguments; argument deduction not allowed in exception declaration}}
63     catch (const A a) { } // expected-error{{requires template arguments; argument deduction not allowed in exception declaration}}
64     try { } catch (A a) { } // expected-error{{requires template arguments; argument deduction not allowed in exception declaration}}
65 
66     // FIXME: The standard only permits class template argument deduction in a
67     // simple-declaration or cast. We also permit it in conditions,
68     // for-range-declarations, member-declarations for static data members, and
69     // new-expressions, because not doing so would be bizarre.
70     A local = 0; // expected-error {{not yet supported}}
71     static A local_static = 0; // expected-error {{not yet supported}}
72     static thread_local A thread_local_static = 0; // expected-error {{not yet supported}}
73     if (A a = 0) {} // expected-error {{not yet supported}}
74     if (A a = 0; a) {} // expected-error {{not yet supported}}
75     switch (A a = 0) {} // expected-error {{not yet supported}}
76     switch (A a = 0; a) {} // expected-error {{not yet supported}}
77     for (A a = 0; a; /**/) {} // expected-error {{not yet supported}}
78     for (/**/; A a = 0; /**/) {} // expected-error {{not yet supported}}
79     while (A a = 0) {} // expected-error {{not yet supported}}
80     int arr[3];
81     for (A a : arr) {} // expected-error {{not yet supported}}
82   }
83 
84   namespace std {
85     class type_info;
86   }
87 }
88 
89 namespace expr {
90   template<typename T> struct U {};
91   void j() {
92     (void)typeid(A); // expected-error{{requires template arguments; argument deduction not allowed here}}
93     (void)sizeof(A); // expected-error{{requires template arguments; argument deduction not allowed here}}
94     (void)__alignof(A); // expected-error{{requires template arguments; argument deduction not allowed here}}
95 
96     U<A> v; // expected-error {{requires template arguments}}
97 
98     int n;
99     (void)dynamic_cast<A&>(n); // expected-error{{requires template arguments; argument deduction not allowed here}}
100     (void)static_cast<A*>(&n); // expected-error{{requires template arguments; argument deduction not allowed here}}
101     (void)reinterpret_cast<A*>(&n); // expected-error{{requires template arguments; argument deduction not allowed here}}
102     (void)const_cast<A>(n); // expected-error{{requires template arguments; argument deduction not allowed here}}
103     (void)*(A*)(&n); // expected-error{{requires template arguments; argument deduction not allowed here}}
104 
105     (void)A(n); // expected-error {{not yet supported}}
106     (void)A{n}; // expected-error {{not yet supported}}
107     (void)new A(n); // expected-error {{not yet supported}}
108     (void)new A{n}; // expected-error {{not yet supported}}
109     // FIXME: We should diagnose the lack of an initializer here.
110     (void)new A; // expected-error {{not yet supported}}
111   }
112 }
113 
114 namespace decl {
115   enum E : A {}; // expected-error{{requires template arguments; argument deduction not allowed here}}
116   struct F : A {}; // expected-error{{expected class name}}
117 
118   using B = A; // expected-error{{requires template arguments}}
119 
120   auto k() -> A; // expected-error{{requires template arguments}}
121 
122   A a; // expected-error {{requires an initializer}}
123   A b = 0; // expected-error {{not yet supported}}
124   A (parens) = 0; // expected-error {{cannot use parentheses when declaring variable with deduced class template specialization type}}
125   A *p = 0; // expected-error {{cannot form pointer to deduced class template specialization type}}
126   A &r = *p; // expected-error {{cannot form reference to deduced class template specialization type}}
127   A arr[3] = 0; // expected-error {{cannot form array of deduced class template specialization type}}
128   A F::*pm = 0; // expected-error {{cannot form pointer to deduced class template specialization type}}
129   A (*fp)() = 0; // expected-error {{cannot form function returning deduced class template specialization type}}
130   A [x, y] = 0; // expected-error {{cannot be declared with type 'A'}} expected-error {{not yet supported}}
131 }
132