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 23 template<typename T> 24 struct set{}; // expected-note{{lookup from the current scope refers here}} 25 struct 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 }; 34 void 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 48 namespace 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 66 namespace 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