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