File: p3.cpp

package info (click to toggle)
llvm-toolchain-19 1%3A19.1.7-3
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 1,998,520 kB
  • sloc: cpp: 6,951,680; ansic: 1,486,157; asm: 913,598; python: 232,024; f90: 80,126; objc: 75,281; lisp: 37,276; pascal: 16,990; sh: 10,009; ml: 5,058; perl: 4,724; awk: 3,523; makefile: 3,167; javascript: 2,504; xml: 892; fortran: 664; cs: 573
file content (185 lines) | stat: -rw-r--r-- 5,224 bytes parent folder | download | duplicates (14)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
// RUN: %clang_cc1 -fsyntax-only -verify %s

// [class.mfct.non-static]p3:
//   When an id-expression (5.1) that is not part of a class member
//   access syntax (5.2.5) and not used to form a pointer to member
//   (5.3.1) is used in the body of a non-static member function of
//   class X, if name lookup (3.4.1) resolves the name in the
//   id-expression to a non-static non-type member of some class C,
//   the id-expression is transformed into a class member access
//   expression (5.2.5) using (*this) (9.3.2) as the
//   postfix-expression to the left of the . operator. [ Note: if C is
//   not X or a base class of X, the class member access expression is
//   ill-formed. --end note] Similarly during name lookup, when an
//   unqualified-id (5.1) used in the definition of a member function
//   for class X resolves to a static member, an enumerator or a
//   nested type of class X or of a base class of X, the
//   unqualified-id is transformed into a qualified-id (5.1) in which
//   the nested-name-specifier names the class of the member function.

namespace test0 {
  class A {
    int data_member;
    int instance_method();
    static int static_method();

    bool test() {
      return data_member + instance_method() < static_method();
    }
  };
}

namespace test1 {
  struct Opaque1 {}; struct Opaque2 {}; struct Opaque3 {};

  struct A {
    void foo(Opaque1); // expected-note {{candidate}}
    void foo(Opaque2); // expected-note {{candidate}}
  };

  struct B : A {
    void test();
  };

  struct C1 : A { };
  struct C2 : B { };

  void B::test() {
    A::foo(Opaque1());
    A::foo(Opaque2());
    A::foo(Opaque3()); // expected-error {{no matching member function}}

    C1::foo(Opaque1()); // expected-error {{call to non-static member function without an object argument}}
    C2::foo(Opaque1()); // expected-error {{call to non-static member function without an object argument}}
  }
}

namespace test2 {
  struct Unrelated {
    void foo();
  };

  template <class T> struct B;
  template <class T> struct C;

  template <class T> struct A {
    void foo();

    void test0() {
      Unrelated::foo(); // expected-error {{call to non-static member function without an object argument}}
    }

    void test1() {
      B<T>::foo(); // expected-error {{call to non-static member function without an object argument}}
    }

    static void test2() {
      B<T>::foo(); // expected-error {{call to non-static member function without an object argument}}
    }

    void test3() {
      C<T>::foo(); // expected-error {{no member named 'foo'}}
    }
  };

  template <class T> struct B : A<T> {
  };

  template <class T> struct C {
  };

  int test() {
    A<int> a;
    a.test0(); // no instantiation note here, decl is ill-formed
    a.test1(); // expected-note {{in instantiation}}
    a.test2(); // expected-note {{in instantiation}}
    a.test3(); // expected-note {{in instantiation}}
  }
}

namespace test3 {
  struct A {
    void f0();

    template<typename T>
    void f1();

    static void f2();

    template<typename T>
    static void f3();

    int x0;

    static constexpr int x1 = 0;

    template<typename T>
    static constexpr int x2 = 0;
  };

  template<typename T>
  struct B : T {
    auto g0() -> decltype(T::f0());

    auto g1() -> decltype(T::template f1<int>());

    auto g2() -> decltype(T::f2());

    auto g3() -> decltype(T::template f3<int>());

    auto g4() -> decltype(T::x0);

    auto g5() -> decltype(T::x1);

    auto g6() -> decltype(T::template x2<int>);

    decltype(T::f0()) g7(); // expected-error {{call to non-static member function without an object argument}}

    decltype(T::template f1<int>()) g8(); // expected-error {{call to non-static member function without an object argument}}

    decltype(T::f2()) g9();

    decltype(T::template f3<int>()) g10();

    decltype(T::x0) g11();

    decltype(T::x1) g12();

    decltype(T::template x2<int>) g13();
  };

  template struct B<A>; // expected-note {{in instantiation of}}

  template<typename T>
  struct C : T {
    static auto g0() -> decltype(T::f0()); // expected-error {{'this' cannot be implicitly used in a static member function declaration}}

    static auto g1() -> decltype(T::template f1<int>()); // expected-error {{'this' cannot be implicitly used in a static member function declaration}}

    static auto g2() -> decltype(T::f2());

    static auto g3() -> decltype(T::template f3<int>());

    static auto g4() -> decltype(T::x0); // expected-error {{'this' cannot be implicitly used in a static member function declaration}}

    static auto g5() -> decltype(T::x1);

    static auto g6() -> decltype(T::template x2<int>);

    static decltype(T::f0()) g7(); // expected-error {{call to non-static member function without an object argument}}

    static decltype(T::template f1<int>()) g8(); // expected-error {{call to non-static member function without an object argument}}

    static decltype(T::f2()) g9();

    static decltype(T::template f3<int>()) g10();

    static decltype(T::x0) g11();

    static decltype(T::x1) g12();

    static decltype(T::template x2<int>) g13();
  };

  template struct C<A>; // expected-note {{in instantiation of}}
}