114 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify %s2// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s3// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s4 5// C++98 [basic.lookup.classref]p1:6// In a class member access expression (5.2.5), if the . or -> token is7// immediately followed by an identifier followed by a <, the identifier must8// be looked up to determine whether the < is the beginning of a template9// argument list (14.2) or a less-than operator. The identifier is first10// looked up in the class of the object expression. If the identifier is not11// found, it is then looked up in the context of the entire postfix-expression12// and shall name a class or function template. If the lookup in the class of13// the object expression finds a template, the name is also looked up in the14// context of the entire postfix-expression and15// -- if the name is not found, the name found in the class of the object16// expression is used, otherwise17// -- if the name is found in the context of the entire postfix-expression18// and does not name a class template, the name found in the class of the19// object expression is used, otherwise20// -- if the name found is a class template, it must refer to the same21// entity as the one found in the class of the object expression,22// otherwise the program is ill-formed.23 24// From PR 724725template<typename T>26struct set{};27#if __cplusplus <= 199711L28// expected-note@-2 {{lookup from the current scope refers here}}29#endif30struct Value {31 template<typename T>32 void set(T value) {}33#if __cplusplus <= 199711L34 // expected-note@-2 {{lookup in the object type 'Value' refers here}}35#endif36 37 void resolves_to_same() {38 Value v;39 v.set<double>(3.2);40 }41};42void resolves_to_different() {43 {44 Value v;45 // The fact that the next line is a warning rather than an error is an46 // extension.47 v.set<double>(3.2);48#if __cplusplus <= 199711L49 // expected-warning@-2 {{lookup of 'set' in member access expression is ambiguous; using member of 'Value'}}50#endif51 }52 {53 int set; // Non-template.54 Value v;55 v.set<double>(3.2);56 }57}58 59namespace 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 {69 A &getA() { return static_cast<B&>(*this); }70 71 void test_a() {72 getA().a<int>();73 }74 };75}76 77namespace PR11856 {78 template<typename T> T end(T);79 80 template <typename T>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>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 102namespace GH139226 {103 104struct Foo {105 template <class T> void LookupWithID(); // expected-note {{declared here}}106};107 108void test(Foo &f) {109 f.LookupWithId<int>();110 // expected-error@-1 {{did you mean 'LookupWithID'}}111}112 113}114