1 // RUN: %clang_cc1 -fsyntax-only -fdiagnostics-show-option -verify %s
2 // RUN: %clang_cc1 -fsyntax-only -fdiagnostics-show-option -verify -std=c++98 %s
3 // RUN: %clang_cc1 -fsyntax-only -fdiagnostics-show-option -verify -std=c++11 %s
4
5 // C++98 [basic.lookup.classref]p1:
6 // In a class member access expression (5.2.5), if the . or -> token is
7 // immediately followed by an identifier followed by a <, the identifier must
8 // be looked up to determine whether the < is the beginning of a template
9 // argument list (14.2) or a less-than operator. The identifier is first
10 // looked up in the class of the object expression. If the identifier is not
11 // found, it is then looked up in the context of the entire postfix-expression
12 // and shall name a class or function template. If the lookup in the class of
13 // the object expression finds a template, the name is also looked up in the
14 // context of the entire postfix-expression and
15 // -- if the name is not found, the name found in the class of the object
16 // expression is used, otherwise
17 // -- if the name is found in the context of the entire postfix-expression
18 // and does not name a class template, the name found in the class of the
19 // object expression is used, otherwise
20 // -- if the name found is a class template, it must refer to the same
21 // entity as the one found in the class of the object expression,
22 // otherwise the program is ill-formed.
23
24 // From PR 7247
25 template<typename T>
26 struct set{};
27 #if __cplusplus <= 199711L
28 // expected-note@-2 {{lookup from the current scope refers here}}
29 #endif
30 struct Value {
31 template<typename T>
setValue32 void set(T value) {}
33 #if __cplusplus <= 199711L
34 // expected-note@-2 {{lookup in the object type 'Value' refers here}}
35 #endif
36
resolves_to_sameValue37 void resolves_to_same() {
38 Value v;
39 v.set<double>(3.2);
40 }
41 };
resolves_to_different()42 void resolves_to_different() {
43 {
44 Value v;
45 // The fact that the next line is a warning rather than an error is an
46 // extension.
47 v.set<double>(3.2);
48 #if __cplusplus <= 199711L
49 // expected-warning@-2 {{lookup of 'set' in member access expression is ambiguous; using member of 'Value'}}
50 #endif
51 }
52 {
53 int set; // Non-template.
54 Value v;
55 v.set<double>(3.2);
56 }
57 }
58
59 namespace rdar9915664 {
60 struct A {
61 template<typename T> void a();
62 };
63
64 struct B : A { };
65
66 struct C : A { };
67
68 struct D : B, C {
getArdar9915664::D69 A &getA() { return static_cast<B&>(*this); }
70
test_ardar9915664::D71 void test_a() {
72 getA().a<int>();
73 }
74 };
75 }
76
77 namespace PR11856 {
78 template<typename T> T end(T);
79
80 template <typename T>
Foo()81 void Foo() {
82 T it1;
83 if (it1->end < it1->end) {
84 }
85 }
86
87 template<typename T> T *end(T*);
88
89 class X { };
90 template <typename T>
Foo2()91 void Foo2() {
92 T it1;
93 if (it1->end < it1->end) {
94 }
95
96 X *x;
97 if (x->end < 7) { // expected-error{{no member named 'end' in 'PR11856::X'}}
98 }
99 }
100 }
101