Home | History | Annotate | Download | only in SemaCXX
      1 // RUN: %clang_cc1 -fsyntax-only -verify -Wno-c++11-extensions %s
      2 
      3 struct errc {
      4   int v_;
      5   operator int() const {return v_;}
      6 };
      7 
      8 class error_condition
      9 {
     10   int _val_;
     11 public:
     12   error_condition() : _val_(0) {}
     13 
     14   error_condition(int _val)
     15     : _val_(_val) {}
     16 
     17   template <class E>
     18   error_condition(E _e) {
     19     // make_error_condition must not be typo corrected to error_condition
     20     // even though the first declaration of make_error_condition has not
     21     // yet been encountered. This was a bug in the first version of the type
     22     // name typo correction patch that wasn't noticed until building LLVM with
     23     // Clang failed.
     24     *this = make_error_condition(_e);
     25   }
     26 
     27 };
     28 
     29 inline error_condition make_error_condition(errc _e) {
     30   return error_condition(static_cast<int>(_e));
     31 }
     32 
     33 
     34 // Prior to the introduction of a callback object to further filter possible
     35 // typo corrections, this example would not trigger a suggestion as "base_type"
     36 // is a closer match to "basetype" than is "BaseType" but "base_type" does not
     37 // refer to a base class or non-static data member.
     38 struct BaseType { };
     39 struct Derived : public BaseType { // expected-note {{base class 'BaseType' specified here}}
     40   static int base_type; // expected-note {{'base_type' declared here}}
     41   Derived() : basetype() {} // expected-error{{initializer 'basetype' does not name a non-static data member or base class; did you mean the base class 'BaseType'?}}
     42 };
     43 
     44 // Test the improvement from passing a callback object to CorrectTypo in
     45 // the helper function LookupMemberExprInRecord.
     46 int get_type(struct Derived *st) {
     47   return st->Base_Type; // expected-error{{no member named 'Base_Type' in 'Derived'; did you mean 'base_type'?}}
     48 }
     49 
     50 // In this example, somename should not be corrected to the cached correction
     51 // "some_name" since "some_name" is a class and a namespace name is needed.
     52 class some_name {}; // expected-note {{'some_name' declared here}}
     53 somename Foo; // expected-error {{unknown type name 'somename'; did you mean 'some_name'?}}
     54 namespace SomeName {} // expected-note {{namespace 'SomeName' defined here}}
     55 using namespace somename; // expected-error {{no namespace named 'somename'; did you mean 'SomeName'?}}
     56 
     57 
     58 // Without the callback object, CorrectTypo would choose "field1" as the
     59 // correction for "fielda" as it is closer than "FieldA", but that correction
     60 // would be later discarded by the caller and no suggestion would be given.
     61 struct st {
     62   struct {
     63     int field1;
     64   };
     65   double FieldA; // expected-note{{'FieldA' declared here}}
     66 };
     67 st var = { .fielda = 0.0 }; // expected-error{{field designator 'fielda' does not refer to any field in type 'st'; did you mean 'FieldA'?}}
     68 
     69 // Test the improvement from passing a callback object to CorrectTypo in
     70 // Sema::BuildCXXNestedNameSpecifier. And also for the improvement by doing
     71 // so in Sema::getTypeName.
     72 typedef char* another_str; // expected-note{{'another_str' declared here}}
     73 namespace AnotherStd { // expected-note{{'AnotherStd' declared here}}
     74   class string {};
     75 }
     76 another_std::string str; // expected-error{{use of undeclared identifier 'another_std'; did you mean 'AnotherStd'?}}
     77 another_str *cstr = new AnotherStr; // expected-error{{unknown type name 'AnotherStr'; did you mean 'another_str'?}}
     78 
     79 // Test the improvement from passing a callback object to CorrectTypo in
     80 // Sema::ActOnSizeofParameterPackExpr.
     81 char* TireNames;
     82 template<typename ...TypeNames> struct count { // expected-note{{parameter pack 'TypeNames' declared here}}
     83   static const unsigned value = sizeof...(TyreNames); // expected-error{{'TyreNames' does not refer to the name of a parameter pack; did you mean 'TypeNames'?}}
     84 };
     85 
     86 // Test the typo-correction callback in Sema::DiagnoseUnknownTypeName.
     87 namespace unknown_type_test {
     88   class StreamOut {}; // expected-note 2 {{'StreamOut' declared here}}
     89   long stream_count; // expected-note 2 {{'stream_count' declared here}}
     90 };
     91 unknown_type_test::stream_out out; // expected-error{{no type named 'stream_out' in namespace 'unknown_type_test'; did you mean 'StreamOut'?}}
     92 
     93 // Demonstrate a case where using only the cached value returns the wrong thing
     94 // when the cached value was the result of a previous callback object that only
     95 // accepts a subset of the current callback object.
     96 namespace {
     97 using namespace unknown_type_test;
     98 void bar(long i);
     99 void before_caching_classname() {
    100   bar((stream_out)); // expected-error{{use of undeclared identifier 'stream_out'; did you mean 'stream_count'?}}
    101 }
    102 stream_out out; // expected-error{{unknown type name 'stream_out'; did you mean 'StreamOut'?}}
    103 void after_caching_classname() {
    104   bar((stream_out)); // expected-error{{use of undeclared identifier 'stream_out'; did you mean 'stream_count'?}}
    105 }
    106 }
    107 
    108 // Test the typo-correction callback in Sema::DiagnoseInvalidRedeclaration.
    109 struct BaseDecl {
    110   void add_in(int i);
    111 };
    112 struct TestRedecl : public BaseDecl {
    113   void add_it(int i); // expected-note{{'add_it' declared here}}
    114 };
    115 void TestRedecl::add_in(int i) {} // expected-error{{out-of-line definition of 'add_in' does not match any declaration in 'TestRedecl'; did you mean 'add_it'?}}
    116 
    117 // Test the improved typo correction for the Parser::ParseCastExpr =>
    118 // Sema::ActOnIdExpression => Sema::DiagnoseEmptyLookup call path.
    119 class SomeNetMessage; // expected-note 2{{'SomeNetMessage'}}
    120 class Message {};
    121 void foo(Message&);
    122 void foo(SomeNetMessage&);
    123 void doit(void *data) {
    124   Message somenetmsg; // expected-note{{'somenetmsg' declared here}}
    125   foo(somenetmessage); // expected-error{{use of undeclared identifier 'somenetmessage'; did you mean 'somenetmsg'?}}
    126   foo((somenetmessage)data); // expected-error{{unknown type name 'somenetmessage'; did you mean 'SomeNetMessage'?}} expected-error{{incomplete type}}
    127 }
    128 
    129 // Test the typo-correction callback in BuildRecoveryCallExpr.
    130 // Solves the main issue in PR 9320 of suggesting corrections that take the
    131 // wrong number of arguments.
    132 void revoke(const char*); // expected-note 2{{'revoke' declared here}}
    133 void Test() {
    134   Invoke(); // expected-error{{use of undeclared identifier 'Invoke'}}
    135   Invoke("foo"); // expected-error{{use of undeclared identifier 'Invoke'; did you mean 'revoke'?}}
    136   Invoke("foo", "bar"); // expected-error{{use of undeclared identifier 'Invoke'}}
    137 }
    138 void Test2(void (*invoke)(const char *, int)) { // expected-note{{'invoke' declared here}}
    139   Invoke(); // expected-error{{use of undeclared identifier 'Invoke'}}
    140   Invoke("foo"); // expected-error{{use of undeclared identifier 'Invoke'; did you mean 'revoke'?}}
    141   Invoke("foo", 7); // expected-error{{use of undeclared identifier 'Invoke'; did you mean 'invoke'?}}
    142   Invoke("foo", 7, 22); // expected-error{{use of undeclared identifier 'Invoke'}}
    143 }
    144 
    145 void provoke(const char *x, bool y=false) {} // expected-note 2{{'provoke' declared here}}
    146 void Test3() {
    147   Provoke(); // expected-error{{use of undeclared identifier 'Provoke'}}
    148   Provoke("foo"); // expected-error{{use of undeclared identifier 'Provoke'; did you mean 'provoke'?}}
    149   Provoke("foo", true); // expected-error{{use of undeclared identifier 'Provoke'; did you mean 'provoke'?}}
    150   Provoke("foo", 7, 22); // expected-error{{use of undeclared identifier 'Provoke'}}
    151 }
    152 
    153 // PR 11737 - Don't try to typo-correct the implicit 'begin' and 'end' in a
    154 // C++11 for-range statement.
    155 struct R {};
    156 bool begun(R);
    157 void RangeTest() {
    158   for (auto b : R()) {} // expected-error {{invalid range expression of type 'R'}}
    159 }
    160 
    161 // PR 12019 - Avoid infinite mutual recursion in DiagnoseInvalidRedeclaration
    162 // by not trying to typo-correct a method redeclaration to declarations not
    163 // in the current record.
    164 class Parent {
    165  void set_types(int index, int value);
    166  void add_types(int value);
    167 };
    168 class Child: public Parent {};
    169 void Child::add_types(int value) {} // expected-error{{out-of-line definition of 'add_types' does not match any declaration in 'Child'}}
    170 
    171 // Fix the callback based filtering of typo corrections within
    172 // Sema::ActOnIdExpression by Parser::ParseCastExpression to allow type names as
    173 // potential corrections for template arguments.
    174 namespace clash {
    175 class ConstructExpr {}; // expected-note 2{{'clash::ConstructExpr' declared here}}
    176 }
    177 class ClashTool {
    178   bool HaveConstructExpr();
    179   template <class T> T* getExprAs();
    180 
    181   void test() {
    182     ConstructExpr *expr = // expected-error{{unknown type name 'ConstructExpr'; did you mean 'clash::ConstructExpr'?}}
    183         getExprAs<ConstructExpr>(); // expected-error{{unknown type name 'ConstructExpr'; did you mean 'clash::ConstructExpr'?}}
    184   }
    185 };
    186 
    187 namespace test1 {
    188   struct S {
    189     struct Foobar *f;  // expected-note{{'Foobar' declared here}}
    190   };
    191   test1::FooBar *b;  // expected-error{{no type named 'FooBar' in namespace 'test1'; did you mean 'Foobar'?}}
    192 }
    193 
    194 namespace ImplicitInt {
    195   void f(int, unsinged); // expected-error{{did you mean 'unsigned'}}
    196   struct S {
    197     unsinged : 4; // expected-error{{did you mean 'unsigned'}}
    198   };
    199 }
    200 
    201 namespace PR12951 {
    202 // If there are two corrections that have the same identifier and edit distance
    203 // and only differ by their namespaces, don't suggest either as a correction
    204 // since both are equally likely corrections.
    205 namespace foobar { struct Thing {}; }
    206 namespace bazquux { struct Thing {}; }
    207 void f() { Thing t; } // expected-error{{unknown type name 'Thing'}}
    208 }
    209 
    210 namespace PR13051 {
    211   template<typename T> struct S {
    212     template<typename U> void f();
    213     operator bool() const;
    214   };
    215 
    216   void f() {
    217     f(&S<int>::tempalte f<int>); // expected-error{{did you mean 'template'?}}
    218     f(&S<int>::opeartor bool); // expected-error{{did you mean 'operator'?}}
    219     f(&S<int>::foo); // expected-error-re{{no member named 'foo' in 'PR13051::S<int>'$}}
    220   }
    221 }
    222 
    223 inf f(doulbe); // expected-error{{'int'}} expected-error{{'double'}}
    224 
    225 namespace PR6325 {
    226 class foo { }; // expected-note{{'foo' declared here}}
    227 // Note that for this example (pulled from the PR), if keywords are not excluded
    228 // as correction candidates then no suggestion would be given; correcting
    229 // 'boo' to 'bool' is the same edit distance as correcting 'boo' to 'foo'.
    230 class bar : boo { }; // expected-error{{unknown class name 'boo'; did you mean 'foo'?}}
    231 }
    232 
    233 namespace bogus_keyword_suggestion {
    234 void test() {
    235    status = "OK"; // expected-error-re{{use of undeclared identifier 'status'$}}
    236    return status; // expected-error-re{{use of undeclared identifier 'status'$}}
    237  }
    238 }
    239 
    240 namespace PR13387 {
    241 struct A {
    242   void CreateFoo(float, float); // expected-note {{'CreateFoo' declared here}}
    243   void CreateBar(float, float);
    244 };
    245 struct B : A {
    246   using A::CreateFoo;
    247   void CreateFoo(int, int);
    248 };
    249 void f(B &x) {
    250   x.Createfoo(0,0); // expected-error {{no member named 'Createfoo' in 'PR13387::B'; did you mean 'CreateFoo'?}}
    251 }
    252 }
    253