xref: /llvm-project/clang/test/CXX/drs/cwg11xx.cpp (revision 463e61a0013253bec1b5e7f07e7b1803b68e2b3d)
1 // RUN: %clang_cc1 -std=c++98 %s -verify=expected,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors
2 // RUN: %clang_cc1 -std=c++11 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
3 // RUN: %clang_cc1 -std=c++14 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
4 // RUN: %clang_cc1 -std=c++17 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
5 // RUN: %clang_cc1 -std=c++20 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
6 // RUN: %clang_cc1 -std=c++23 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
7 // RUN: %clang_cc1 -std=c++2c %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
8 
9 namespace cwg1110 { // cwg1110: 3.1
10 #if __cplusplus >= 201103L
11 template <typename T>
12 T return_T();
13 
14 struct A;
15 
16 template <typename>
17 struct B;
18 
19 decltype(return_T<A>())* a;
20 decltype(return_T<B<int>>())* b;
21 #endif
22 } // namespace cwg1110
23 
24 namespace cwg1111 { // cwg1111: partial
25 namespace example1 {
26 template <typename> struct set; // #cwg1111-struct-set
27 
28 struct X {
29   template <typename T> void set(const T &value); // #cwg1111-func-set
30 };
31 void foo() {
32   X x;
33   // FIXME: should we backport C++11 behavior?
34   x.set<double>(3.2);
35   // cxx98-error@-1 {{lookup of 'set' in member access expression is ambiguous; using member of 'X'}}
36   //   cxx98-note@#cwg1111-func-set {{lookup in the object type 'X' refers here}}
37   //   cxx98-note@#cwg1111-struct-set {{lookup from the current scope refers here}}
38 }
39 
40 struct Y {};
41 void bar() {
42   Y y;
43   y.set<double>(3.2);
44   // expected-error@-1 {{no member named 'set' in 'cwg1111::example1::Y'}}
45 }
46 } // namespace example1
47 
48 namespace example2 {
49 struct A {};
50 namespace N {
51 struct A {
52   void g() {}
53   template <class T> operator T();
54 };
55 } // namespace N
56 
57 void baz() {
58   N::A a;
59   a.operator A();
60 }
61 } // namespace example2
62 
63 namespace example3 {
64 struct A {
65   operator int();
66 } a;
67 void foo() {
68   typedef int T;
69   a.operator T(); // T is found using unqualified lookup
70                   // after qualified lookup in A fails.
71 }
72 } // namespace example3
73 
74 namespace example4 {
75 struct A {
76   typedef int T; // #cwg1111-A-T
77   operator T();
78 };
79 struct B : A {
80   operator T();
81 } b;
82 void foo() {
83   b.A::operator T(); // FIXME: qualified lookup should find T in A.
84   // expected-error@-1 {{unknown type name 'T'}}
85   //   expected-note@#cwg1111-A-T {{'A::T' declared here}}
86 }
87 } // namespace example4
88 
89 namespace example5 {
90 template <class T1> struct A {
91   operator T1();
92 };
93 template <class T2> struct B : A<T2> {
94   operator T2();
95   void foo() {
96     // In both cases, during instantiation, qualified lookup for T2 wouldn't be able
97     // to find anything, so T2 has to be found by unqualified lookup.
98     // After that, 'operator T2()' is found in A<T2> by qualfied lookup.
99     T2 a = A<T2>::operator T2();
100     T2 b = ((A<T2> *)this)->operator T2();
101   }
102 };
103 } // namespace example5
104 } // namespace cwg1111
105 
106 namespace cwg1113 { // cwg1113: partial
107   namespace named {
108     extern int a; // #cwg1113-a
109     static int a;
110     // expected-error@-1 {{static declaration of 'a' follows non-static}}
111     //   expected-note@#cwg1113-a {{previous declaration is here}}
112   }
113   namespace {
114     extern int a;
115     static int a; // ok, both declarations have internal linkage
116     int b = a;
117   }
118 
119   // FIXME: Per CWG1113 and CWG4, this is ill-formed due to ambiguity: the second
120   // 'f' has internal linkage, and so does not have C language linkage, so is
121   // not a redeclaration of the first 'f'.
122   //
123   // To avoid a breaking change here, Clang ignores the "internal linkage" effect
124   // of anonymous namespaces on declarations declared within an 'extern "C"'
125   // linkage-specification.
126   extern "C" void f();
127   namespace {
128     extern "C" void f();
129   }
130   void g() { f(); }
131 } // namespace cwg1113
132 
133 // cwg1150: na
134