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