Clang Project

clang_source_code/test/CXX/basic/basic.lookup/basic.lookup.classref/p1.cpp
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
25template<typename T>
26struct set{};
27#if __cplusplus <= 199711L
28// expected-note@-2 {{lookup from the current scope refers here}}
29#endif
30struct Value {
31  template<typename T>
32  void set(T value) {}
33#if __cplusplus <= 199711L
34  // expected-note@-2 {{lookup in the object type 'Value' refers here}}
35#endif
36
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 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
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