| 1 | // RUN: %clang_cc1 -fsyntax-only -verify -Wno-c++11-extensions %s |
| 2 | // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 -Wno-c++11-extensions %s |
| 3 | // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s |
| 4 | |
| 5 | struct A {}; |
| 6 | struct B {}; |
| 7 | struct D { |
| 8 | A fizbin; // expected-note 2 {{declared here}} |
| 9 | A foobar; // expected-note 2 {{declared here}} |
| 10 | B roxbin; // expected-note 2 {{declared here}} |
| 11 | B toobad; // expected-note 2 {{declared here}} |
| 12 | void BooHoo(); |
| 13 | void FoxBox(); |
| 14 | }; |
| 15 | |
| 16 | void something(A, B); |
| 17 | void test() { |
| 18 | D obj; |
| 19 | something(obj.fixbin, // expected-error {{did you mean 'fizbin'?}} |
| 20 | obj.toobat); // expected-error {{did you mean 'toobad'?}} |
| 21 | something(obj.toobat, // expected-error {{did you mean 'foobar'?}} |
| 22 | obj.fixbin); // expected-error {{did you mean 'roxbin'?}} |
| 23 | something(obj.fixbin, // expected-error {{did you mean 'fizbin'?}} |
| 24 | obj.fixbin); // expected-error {{did you mean 'roxbin'?}} |
| 25 | something(obj.toobat, // expected-error {{did you mean 'foobar'?}} |
| 26 | obj.toobat); // expected-error {{did you mean 'toobad'?}} |
| 27 | // Both members could be corrected to methods, but that isn't valid. |
| 28 | something(obj.boohoo, // expected-error-re {{no member named 'boohoo' in 'D'{{$}}}} |
| 29 | obj.foxbox); // expected-error-re {{no member named 'foxbox' in 'D'{{$}}}} |
| 30 | // The first argument has a usable correction but the second doesn't. |
| 31 | something(obj.boobar, // expected-error-re {{no member named 'boobar' in 'D'{{$}}}} |
| 32 | obj.foxbox); // expected-error-re {{no member named 'foxbox' in 'D'{{$}}}} |
| 33 | } |
| 34 | |
| 35 | // Ensure the delayed typo correction does the right thing when trying to |
| 36 | // recover using a seemingly-valid correction for which a valid expression to |
| 37 | // replace the TypoExpr cannot be created (but which does have a second |
| 38 | // correction candidate that would be a valid and usable correction). |
| 39 | class Foo { |
| 40 | public: |
| 41 | template <> void testIt(); // expected-error {{no function template matches}} |
| 42 | void textIt(); // expected-note {{'textIt' declared here}} |
| 43 | }; |
| 44 | void testMemberExpr(Foo *f) { |
| 45 | f->TestIt(); // expected-error {{no member named 'TestIt' in 'Foo'; did you mean 'textIt'?}} |
| 46 | } |
| 47 | |
| 48 | void callee(double, double); |
| 49 | void testNoCandidates() { |
| 50 | callee(xxxxxx, // expected-error-re {{use of undeclared identifier 'xxxxxx'{{$}}}} |
| 51 | zzzzzz); // expected-error-re {{use of undeclared identifier 'zzzzzz'{{$}}}} |
| 52 | } |
| 53 | |
| 54 | class string {}; |
| 55 | struct Item { |
| 56 | void Nest(); |
| 57 | string text(); |
| 58 | Item* next(); // expected-note {{'next' declared here}} |
| 59 | }; |
| 60 | void testExprFilter(Item *i) { |
| 61 | Item *j; |
| 62 | j = i->Next(); // expected-error {{no member named 'Next' in 'Item'; did you mean 'next'?}} |
| 63 | } |
| 64 | |
| 65 | // Test that initializer expressions are handled correctly and that the type |
| 66 | // being initialized is taken into account when choosing a correction. |
| 67 | namespace initializerCorrections { |
| 68 | struct Node { |
| 69 | string text() const; |
| 70 | // Node* Next() is not implemented yet |
| 71 | }; |
| 72 | void f(Node *node) { |
| 73 | // text is only an edit distance of 1 from Next, but would trigger type |
| 74 | // conversion errors if used in this initialization expression. |
| 75 | Node *next = node->Next(); // expected-error-re {{no member named 'Next' in 'initializerCorrections::Node'{{$}}}} |
| 76 | } |
| 77 | |
| 78 | struct LinkedNode { |
| 79 | LinkedNode* next(); // expected-note {{'next' declared here}} |
| 80 | string text() const; |
| 81 | }; |
| 82 | void f(LinkedNode *node) { |
| 83 | // text and next are equidistant from Next, but only one results in a valid |
| 84 | // initialization expression. |
| 85 | LinkedNode *next = node->Next(); // expected-error {{no member named 'Next' in 'initializerCorrections::LinkedNode'; did you mean 'next'?}} |
| 86 | } |
| 87 | |
| 88 | struct NestedNode { |
| 89 | NestedNode* Nest(); |
| 90 | NestedNode* next(); |
| 91 | string text() const; |
| 92 | }; |
| 93 | void f(NestedNode *node) { |
| 94 | // There are two equidistant, usable corrections for Next: next and Nest |
| 95 | NestedNode *next = node->Next(); // expected-error-re {{no member named 'Next' in 'initializerCorrections::NestedNode'{{$}}}} |
| 96 | } |
| 97 | } |
| 98 | |
| 99 | namespace PR21669 { |
| 100 | void f(int *i) { |
| 101 | // Check that arguments to a builtin with custom type checking are corrected |
| 102 | // properly, since calls to such builtins bypass much of the normal code path |
| 103 | // for building and checking the call. |
| 104 | __atomic_load(i, i, something_something); // expected-error-re {{use of undeclared identifier 'something_something'{{$}}}} |
| 105 | } |
| 106 | } |
| 107 | |
| 108 | const int DefaultArg = 9; // expected-note {{'DefaultArg' declared here}} |
| 109 | template <int I = defaultArg> struct S {}; // expected-error {{use of undeclared identifier 'defaultArg'; did you mean 'DefaultArg'?}} |
| 110 | S<1> s; |
| 111 | |
| 112 | namespace foo {} |
| 113 | void test_paren_suffix() { |
| 114 | foo::bar({5, 6}); // expected-error-re {{no member named 'bar' in namespace 'foo'{{$}}}} |
| 115 | #if __cplusplus <= 199711L |
| 116 | // expected-error@-2 {{expected expression}} |
| 117 | #endif |
| 118 | } |
| 119 | |
| 120 | const int kNum = 10; // expected-note {{'kNum' declared here}} |
| 121 | class SomeClass { |
| 122 | int Kind; |
| 123 | public: |
| 124 | explicit SomeClass() : Kind(kSum) {} // expected-error {{use of undeclared identifier 'kSum'; did you mean 'kNum'?}} |
| 125 | }; |
| 126 | |
| 127 | // There used to be an issue with typo resolution inside overloads. |
| 128 | struct AssertionResult { ~AssertionResult(); }; |
| 129 | AssertionResult Overload(const char *a); |
| 130 | AssertionResult Overload(int a); |
| 131 | void UseOverload() { |
| 132 | // expected-note@+1 {{'result' declared here}} |
| 133 | const char *result; |
| 134 | // expected-error@+1 {{use of undeclared identifier 'resulta'; did you mean 'result'?}} |
| 135 | Overload(resulta); |
| 136 | } |
| 137 | |
| 138 | namespace PR21925 { |
| 139 | struct X { |
| 140 | int get() { return 7; } // expected-note {{'get' declared here}} |
| 141 | }; |
| 142 | void test() { |
| 143 | X variable; // expected-note {{'variable' declared here}} |
| 144 | |
| 145 | // expected-error@+2 {{use of undeclared identifier 'variableX'; did you mean 'variable'?}} |
| 146 | // expected-error@+1 {{no member named 'getX' in 'PR21925::X'; did you mean 'get'?}} |
| 147 | int x = variableX.getX(); |
| 148 | } |
| 149 | } |
| 150 | |
| 151 | namespace PR21905 { |
| 152 | int (*a) () = (void)Z; // expected-error-re {{use of undeclared identifier 'Z'{{$}}}} |
| 153 | } |
| 154 | |
| 155 | namespace PR21947 { |
| 156 | int blue; // expected-note {{'blue' declared here}} |
| 157 | __typeof blur y; // expected-error {{use of undeclared identifier 'blur'; did you mean 'blue'?}} |
| 158 | } |
| 159 | |
| 160 | namespace PR22092 { |
| 161 | a = b ? : 0; // expected-error {{C++ requires a type specifier for all declarations}} \ |
| 162 | // expected-error-re {{use of undeclared identifier 'b'{{$}}}} |
| 163 | } |
| 164 | |
| 165 | extern long clock (void); |
| 166 | struct Pointer { |
| 167 | void set_xpos(int); |
| 168 | void set_ypos(int); |
| 169 | }; |
| 170 | void MovePointer(Pointer &Click, int x, int y) { // expected-note 2 {{'Click' declared here}} |
| 171 | click.set_xpos(x); // expected-error {{use of undeclared identifier 'click'; did you mean 'Click'?}} |
| 172 | click.set_ypos(x); // expected-error {{use of undeclared identifier 'click'; did you mean 'Click'?}} |
| 173 | } |
| 174 | |
| 175 | namespace PR22250 { |
| 176 | // expected-error@+4 {{use of undeclared identifier 'size_t'; did you mean 'sizeof'?}} |
| 177 | // expected-error-re@+3 {{use of undeclared identifier 'y'{{$}}}} |
| 178 | // expected-error-re@+2 {{use of undeclared identifier 'z'{{$}}}} |
| 179 | // expected-error@+1 {{expected ';' after top level declarator}} |
| 180 | int getenv_s(size_t *y, char(&z)) {} |
| 181 | } |
| 182 | |
| 183 | namespace PR22291 { |
| 184 | template <unsigned I> void f() { |
| 185 | unsigned *prio_bits_array; // expected-note {{'prio_bits_array' declared here}} |
| 186 | // expected-error@+1 {{use of undeclared identifier 'prio_op_array'; did you mean 'prio_bits_array'?}} |
| 187 | __atomic_store_n(prio_op_array + I, false, __ATOMIC_RELAXED); |
| 188 | } |
| 189 | } |
| 190 | |
| 191 | namespace PR22297 { |
| 192 | double pow(double x, double y); |
| 193 | struct TimeTicks { |
| 194 | static void Now(); // expected-note {{'Now' declared here}} |
| 195 | }; |
| 196 | void f() { |
| 197 | TimeTicks::now(); // expected-error {{no member named 'now' in 'PR22297::TimeTicks'; did you mean 'Now'?}} |
| 198 | } |
| 199 | } |
| 200 | |
| 201 | namespace PR23005 { |
| 202 | void f() { int a = Unknown::b(c); } // expected-error {{use of undeclared identifier 'Unknown'}} |
| 203 | // expected-error@-1 {{use of undeclared identifier 'c'}} |
| 204 | } |
| 205 | |
| 206 | namespace PR23350 { |
| 207 | int z = 1 ? N : ; // expected-error {{expected expression}} |
| 208 | // expected-error-re@-1 {{use of undeclared identifier 'N'{{$}}}} |
| 209 | } |
| 210 | |
| 211 | // PR 23285. This test must be at the end of the file to avoid additional, |
| 212 | // unwanted diagnostics. |
| 213 | // expected-error-re@+2 {{use of undeclared identifier 'uintmax_t'{{$}}}} |
| 214 | // expected-error@+1 {{expected ';' after top level declarator}} |
| 215 | unsigned int a = 0(uintmax_t |
| 216 | |