1 // P0634R3 2 // { dg-do compile { target c++17_only } } 3 4 // (5.2.1) simple-declaration or a function-definition in namespace scope 5 6 template<typename T> 7 T::X fn1 (int); // { dg-error "need .typename." } 8 9 template<typename T> fn1(int)10T::X fn1 (int) // { dg-error "need .typename." } 11 { 12 return 42; 13 } 14 15 template<typename T> 16 T::X v1; // { dg-error "need .typename." } 17 18 namespace N { 19 template<typename T> 20 T::X v2; // { dg-error "need .typename." } 21 } 22 23 // (5.2.2) member-declaration 24 25 template<typename T> 26 struct S { 27 [[noreturn]] T::X fn2 (); // { dg-error "need .typename." } 28 T::X fn3 (); // { dg-error "need .typename." } fn4S29 T::X fn4 () { return 5; } // { dg-error "need .typename." } 30 T::X fn5 () final; // { dg-error "need .typename." } 31 T::X fn6 () = 0; // { dg-error "need .typename." } 32 T::X fn8 () override; // { dg-error "need .typename." } 33 T::X v3; // { dg-error "need .typename." } 34 T::X *v4; // { dg-error "need .typename." } 35 T::X v5[5]; // { dg-error "need .typename." } 36 T::X v6 = 0; // { dg-error "need .typename." } 37 T::X v7{0}; // { dg-error "need .typename.|;" } 38 T::X v8 : 16; // { dg-error "need .typename." } 39 static constexpr T::X v9 = 0; // { dg-error "need .typename." } 40 typedef T::X T2; // { dg-error "need .typename." } 41 friend T::X fn7<int> (); // { dg-error "need .typename." } 42 static inline T::X v10; // { dg-error "need .typename." } 43 }; 44 45 // (5.2.3) parameter-declaration in a member-declaration, 46 // unless that parameter-declaration appears in a default argument 47 48 template<typename T> 49 struct S2 { 50 friend int fn1<T::X> (); // { dg-error "" } 51 int fn2 (T::X p); // { dg-error "not a type" } 52 int fn5 (int = T::X); 53 }; 54 55 // (5.2.4) parameter-declaration in a declarator of a function or function 56 // template declaration whose declarator-id is qualified, 57 // unless that parameter-declaration appears in a default argument 58 template<typename T> 59 int fn3 (T::X); 60 61 template<typename T> fn4(T::X p)62int fn4 (T::X p) { return p; } // { dg-error "" } 63 64 // (5.2.6) parameter-declaration of a (non-type) template-parameter 65 66 template<typename T, T::X N> // { dg-error "not a type" } 67 struct S3 { }; 68 69 // default argument of a type-parameter of a template 70 template<typename T, typename U = T::X> // { dg-error "need .typename." } 71 struct S4 { }; 72 73 // type-id of a static_cast, const_cast, reinterpret_cast, or dynamic_cast 74 template<typename T> 75 struct S5 { fn6S576 void fn6 (T::X p) // { dg-error "not a type" } 77 { 78 int i = static_cast<T::Y>(p); // { dg-error "need .typename." } 79 i = dynamic_cast<T::Y>(p); // { dg-error "need .typename." } 80 i = reinterpret_cast<T::Y>(p); // { dg-error "need .typename." } 81 i = const_cast<T::Y>(p); // { dg-error "need .typename." } 82 } 83 }; 84 85 template<typename T> fn7(T::X p)86void fn7 (T::X p) // { dg-error "" } 87 { 88 int i = static_cast<T::Y>(p); 89 i = dynamic_cast<T::Y>(p); 90 i = reinterpret_cast<T::Y>(p); 91 i = const_cast<T::Y>(p); 92 } 93 94 // new-type-id 95 template<typename T> 96 void fn8()97fn8 () 98 { 99 new T::X[10]; // { dg-error "need .typename." } 100 } 101 102 // defining-type-id 103 104 template<typename T> 105 struct W { typedef int M; }; 106 107 template<typename T> 108 struct S6 { 109 using TT = T::X; // { dg-error "need .typename." } 110 using TT2 = W<T>::M; // { dg-error "need .typename." } 111 }; 112 113 // trailing-return-type 114 template<typename T> 115 struct S7 { 116 auto fn9() -> W<T>::M; // { dg-error "need .typename." } 117 }; 118