Home | History | Annotate | Download | only in SemaCXX
      1 // RUN: %clang_cc1 -fsyntax-only -verify -Wbind-to-temporary-copy %s
      2 // RUN: %clang_cc1 -fsyntax-only -verify -Wbind-to-temporary-copy -std=c++98 %s
      3 // RUN: %clang_cc1 -fsyntax-only -verify -Wbind-to-temporary-copy -std=c++11 %s
      4 
      5 // Make sure we don't produce invalid IR.
      6 // RUN: %clang_cc1 -emit-llvm-only %s
      7 // RUN: %clang_cc1 -emit-llvm-only -std=c++98 %s
      8 // RUN: %clang_cc1 -emit-llvm-only -std=c++11 %s
      9 
     10 namespace test1 {
     11   static void foo(); // expected-warning {{function 'test1::foo' has internal linkage but is not defined}}
     12   template <class T> static void bar(); // expected-warning {{function 'test1::bar<int>' has internal linkage but is not defined}}
     13 
     14   void test() {
     15     foo(); // expected-note {{used here}}
     16     bar<int>(); // expected-note {{used here}}
     17   }
     18 }
     19 
     20 namespace test2 {
     21   namespace {
     22     void foo(); // expected-warning {{function 'test2::(anonymous namespace)::foo' has internal linkage but is not defined}}
     23     extern int var; // expected-warning {{variable 'test2::(anonymous namespace)::var' has internal linkage but is not defined}}
     24     template <class T> void bar(); // expected-warning {{function 'test2::(anonymous namespace)::bar<int>' has internal linkage but is not defined}}
     25   }
     26   void test() {
     27     foo(); // expected-note {{used here}}
     28     var = 0; // expected-note {{used here}}
     29     bar<int>(); // expected-note {{used here}}
     30   }
     31 }
     32 
     33 namespace test3 {
     34   namespace {
     35     void foo();
     36     extern int var;
     37     template <class T> void bar();
     38   }
     39 
     40   void test() {
     41     foo();
     42     var = 0;
     43     bar<int>();
     44   }
     45 
     46   namespace {
     47     void foo() {}
     48     int var = 0;
     49     template <class T> void bar() {}
     50   }
     51 }
     52 
     53 namespace test4 {
     54   namespace {
     55     struct A {
     56       A(); // expected-warning {{function 'test4::(anonymous namespace)::A::A' has internal linkage but is not defined}}
     57       ~A();// expected-warning {{function 'test4::(anonymous namespace)::A::~A' has internal linkage but is not defined}}
     58       virtual void foo(); // expected-warning {{function 'test4::(anonymous namespace)::A::foo' has internal linkage but is not defined}}
     59       virtual void bar() = 0;
     60       virtual void baz(); // expected-warning {{function 'test4::(anonymous namespace)::A::baz' has internal linkage but is not defined}}
     61     };
     62   }
     63 
     64   void test(A &a) {
     65     a.foo(); // expected-note {{used here}}
     66     a.bar();
     67     a.baz(); // expected-note {{used here}}
     68   }
     69 
     70   struct Test : A {
     71     Test() {} // expected-note 2 {{used here}}
     72   };
     73 }
     74 
     75 // rdar://problem/9014651
     76 namespace test5 {
     77   namespace {
     78     struct A {};
     79   }
     80 
     81   template <class N> struct B {
     82     static int var; // expected-warning {{variable 'test5::B<test5::(anonymous namespace)::A>::var' has internal linkage but is not defined}}
     83     static void foo(); // expected-warning {{function 'test5::B<test5::(anonymous namespace)::A>::foo' has internal linkage but is not defined}}
     84   };
     85   extern template int B<A>::var;
     86 
     87   void test() {
     88     B<A>::var = 0; // expected-note {{used here}}
     89     B<A>::foo(); // expected-note {{used here}}
     90   }
     91 }
     92 
     93 namespace test6 {
     94   template <class T> struct A {
     95     static const int zero = 0;
     96     static const int one = 1;
     97     static const int two = 2;
     98 
     99     int value;
    100 
    101     A() : value(zero) {
    102       value = one;
    103     }
    104   };
    105 
    106   namespace { struct Internal; }
    107 
    108   void test() {
    109     A<Internal> a;
    110     a.value = A<Internal>::two;
    111   }
    112 }
    113 
    114 // We support (as an extension) private, undefined copy constructors when
    115 // a temporary is bound to a reference even in C++98. Similarly, we shouldn't
    116 // warn about this copy constructor being used without a definition.
    117 namespace PR9323 {
    118   namespace {
    119     struct Uncopyable {
    120       Uncopyable() {}
    121     private:
    122       Uncopyable(const Uncopyable&); // expected-note {{declared private here}}
    123     };
    124   }
    125   void f(const Uncopyable&) {}
    126   void test() {
    127     f(Uncopyable());
    128 #if __cplusplus <= 199711L // C++03 or earlier modes
    129     // expected-warning@-2 {{C++98 requires an accessible copy constructor}}
    130 #else
    131     // expected-warning@-4 {{copying parameter of type 'PR9323::(anonymous namespace)::Uncopyable' when binding a reference to a temporary would invoke an inaccessible constructor in C++98}}
    132 #endif
    133   };
    134 }
    135 
    136 
    137 namespace std { class type_info; };
    138 namespace cxx11_odr_rules {
    139   // Note: the way this test is written isn't really ideal, but there really
    140   // isn't any other way to check that the odr-used logic for constants
    141   // is working without working implicit capture in lambda-expressions.
    142   // (The more accurate used-but-not-defined warning is the only other visible
    143   // effect of accurate odr-used computation.)
    144   //
    145   // Note that the warning in question can trigger in cases some people would
    146   // consider false positives; hopefully that happens rarely in practice.
    147   //
    148   // FIXME: Suppressing this test while I figure out how to fix a bug in the
    149   // odr-use marking code.
    150 
    151   namespace {
    152     struct A {
    153       static const int unused = 10;
    154       static const int used1 = 20; // xpected-warning {{internal linkage}}
    155       static const int used2 = 20; // xpected-warning {{internal linkage}}
    156       virtual ~A() {}
    157     };
    158   }
    159 
    160   void a(int,int);
    161   A& p(const int&) { static A a; return a; }
    162 
    163   // Check handling of default arguments
    164   void b(int = A::unused);
    165 
    166   void tests() {
    167     // Basic test
    168     a(A::unused, A::unused);
    169 
    170     // Check that nesting an unevaluated or constant-evaluated context does
    171     // the right thing.
    172     a(A::unused, sizeof(int[10]));
    173 
    174     // Check that the checks work with unevaluated contexts
    175     (void)sizeof(p(A::used1));
    176     (void)typeid(p(A::used1)); // expected-warning {{expression with side effects will be evaluated despite being used as an operand to 'typeid'}} xpected-note {{used here}}
    177 
    178     // Misc other testing
    179     a(A::unused, 1 ? A::used2 : A::used2); // xpected-note {{used here}}
    180     b();
    181   }
    182 }
    183 
    184 
    185 namespace OverloadUse {
    186   namespace {
    187     void f();
    188     void f(int); // expected-warning {{function 'OverloadUse::(anonymous namespace)::f' has internal linkage but is not defined}}
    189   }
    190   template<void x()> void t(int*) { x(); }
    191   template<void x(int)> void t(long*) { x(10); } // expected-note {{used here}}
    192   void g() { long a; t<f>(&a); }
    193 }
    194 
    195 namespace test7 {
    196   typedef struct {
    197     void bar();
    198     void foo() {
    199       bar();
    200     }
    201   } A;
    202 }
    203 
    204 namespace test8 {
    205   typedef struct {
    206     void bar(); // expected-warning {{function 'test8::(anonymous struct)::bar' has internal linkage but is not defined}}
    207     void foo() {
    208       bar(); // expected-note {{used here}}
    209     }
    210   } *A;
    211 }
    212 
    213 namespace test9 {
    214   namespace {
    215     struct X {
    216       virtual void notused() = 0;
    217       virtual void used() = 0; // expected-warning {{function 'test9::(anonymous namespace)::X::used' has internal linkage but is not defined}}
    218     };
    219   }
    220   void test(X &x) {
    221     x.notused();
    222     x.X::used(); // expected-note {{used here}}
    223   }
    224 }
    225 
    226 namespace test10 {
    227   namespace {
    228     struct X {
    229       virtual void notused() = 0;
    230       virtual void used() = 0; // expected-warning {{function 'test10::(anonymous namespace)::X::used' has internal linkage but is not defined}}
    231 
    232       void test() {
    233         notused();
    234         (void)&X::notused;
    235         (this->*&X::notused)();
    236         X::used();  // expected-note {{used here}}
    237       }
    238     };
    239     struct Y : X {
    240       using X::notused;
    241     };
    242   }
    243 }
    244 
    245 namespace test11 {
    246   namespace {
    247     struct A {
    248       virtual bool operator()() const = 0;
    249       virtual void operator!() const = 0;
    250       virtual bool operator+(const A&) const = 0;
    251       virtual int operator[](int) const = 0;
    252       virtual const A* operator->() const = 0;
    253       int member;
    254     };
    255 
    256     struct B {
    257       bool operator()() const;  // expected-warning {{function 'test11::(anonymous namespace)::B::operator()' has internal linkage but is not defined}}
    258       void operator!() const;  // expected-warning {{function 'test11::(anonymous namespace)::B::operator!' has internal linkage but is not defined}}
    259       bool operator+(const B&) const;  // expected-warning {{function 'test11::(anonymous namespace)::B::operator+' has internal linkage but is not defined}}
    260       int operator[](int) const;  // expected-warning {{function 'test11::(anonymous namespace)::B::operator[]' has internal linkage but is not defined}}
    261       const B* operator->() const;  // expected-warning {{function 'test11::(anonymous namespace)::B::operator->' has internal linkage but is not defined}}
    262       int member;
    263     };
    264   }
    265 
    266   void test1(A &a1, A &a2) {
    267     a1();
    268     !a1;
    269     a1 + a2;
    270     a1[0];
    271     (void)a1->member;
    272   }
    273 
    274   void test2(B &b1, B &b2) {
    275     b1();  // expected-note {{used here}}
    276     !b1;  // expected-note {{used here}}
    277     b1 + b2;  // expected-note {{used here}}
    278     b1[0];  // expected-note {{used here}}
    279     (void)b1->member;  // expected-note {{used here}}
    280   }
    281 }
    282 
    283 namespace test12 {
    284   class T1 {}; class T2 {}; class T3 {}; class T4 {}; class T5 {}; class T6 {};
    285   class T7 {};
    286 
    287   namespace {
    288     struct Cls {
    289       virtual void f(int) = 0;
    290       virtual void f(int, double) = 0;
    291       void g(int);  // expected-warning {{function 'test12::(anonymous namespace)::Cls::g' has internal linkage but is not defined}}
    292       void g(int, double);
    293       virtual operator T1() = 0;
    294       virtual operator T2() = 0;
    295       virtual operator T3&() = 0;
    296       operator T4();  // expected-warning {{function 'test12::(anonymous namespace)::Cls::operator T4' has internal linkage but is not defined}}
    297       operator T5();  // expected-warning {{function 'test12::(anonymous namespace)::Cls::operator T5' has internal linkage but is not defined}}
    298       operator T6&();  // expected-warning {{function 'test12::(anonymous namespace)::Cls::operator test12::T6 &' has internal linkage but is not defined}}
    299     };
    300 
    301     struct Cls2 {
    302       Cls2(T7);  // expected-warning {{function 'test12::(anonymous namespace)::Cls2::Cls2' has internal linkage but is not defined}}
    303     };
    304   }
    305 
    306   void test(Cls &c) {
    307     c.f(7);
    308     c.g(7);  // expected-note {{used here}}
    309     (void)static_cast<T1>(c);
    310     T2 t2 = c;
    311     T3 &t3 = c;
    312     (void)static_cast<T4>(c); // expected-note {{used here}}
    313     T5 t5 = c;  // expected-note {{used here}}
    314     T6 &t6 = c;  // expected-note {{used here}}
    315 
    316     Cls2 obj1((T7()));  // expected-note {{used here}}
    317   }
    318 }
    319 
    320 namespace test13 {
    321   namespace {
    322     struct X {
    323       virtual void f() { }
    324     };
    325 
    326     struct Y : public X {
    327       virtual void f() = 0;
    328 
    329       virtual void g() {
    330         X::f();
    331       }
    332     };
    333   }
    334 }
    335 
    336 namespace test14 {
    337   extern "C" const int foo;
    338 
    339   int f() {
    340     return foo;
    341   }
    342 }
    343