Home | History | Annotate | Download | only in SemaTemplate
      1 // RUN: %clang_cc1 -fsyntax-only -verify %s  -triple x86_64-pc-linux-gnu
      2 template<int I, int J>
      3 struct Bitfields {
      4   int simple : I; // expected-error{{bit-field 'simple' has zero width}}
      5   int parens : (J);
      6 };
      7 
      8 void test_Bitfields(Bitfields<0, 5> *b) {
      9   (void)sizeof(Bitfields<10, 5>);
     10   (void)sizeof(Bitfields<0, 1>); // expected-note{{in instantiation of template class 'Bitfields<0, 1>' requested here}}
     11 }
     12 
     13 template<int I, int J>
     14 struct BitfieldPlus {
     15   int bitfield : I + J; // expected-error{{bit-field 'bitfield' has zero width}}
     16 };
     17 
     18 void test_BitfieldPlus() {
     19   (void)sizeof(BitfieldPlus<0, 1>);
     20   (void)sizeof(BitfieldPlus<-5, 5>); // expected-note{{in instantiation of template class 'BitfieldPlus<-5, 5>' requested here}}
     21 }
     22 
     23 template<int I, int J>
     24 struct BitfieldMinus {
     25   int bitfield : I - J; // expected-error{{bit-field 'bitfield' has negative width (-1)}} \
     26   // expected-error{{bit-field 'bitfield' has zero width}}
     27 };
     28 
     29 void test_BitfieldMinus() {
     30   (void)sizeof(BitfieldMinus<5, 1>);
     31   (void)sizeof(BitfieldMinus<0, 1>); // expected-note{{in instantiation of template class 'BitfieldMinus<0, 1>' requested here}}
     32   (void)sizeof(BitfieldMinus<5, 5>); // expected-note{{in instantiation of template class 'BitfieldMinus<5, 5>' requested here}}
     33 }
     34 
     35 template<int I, int J>
     36 struct BitfieldDivide {
     37   int bitfield : I / J; // expected-error{{expression is not an integral constant expression}} \
     38                         // expected-note{{division by zero}}
     39 };
     40 
     41 void test_BitfieldDivide() {
     42   (void)sizeof(BitfieldDivide<5, 1>);
     43   (void)sizeof(BitfieldDivide<5, 0>); // expected-note{{in instantiation of template class 'BitfieldDivide<5, 0>' requested here}}
     44 }
     45 
     46 template<typename T, T I, int J>
     47 struct BitfieldDep {
     48   int bitfield : I + J;
     49 };
     50 
     51 void test_BitfieldDep() {
     52   (void)sizeof(BitfieldDep<int, 1, 5>);
     53 }
     54 
     55 template<int I>
     56 struct BitfieldNeg {
     57   int bitfield : (-I); // expected-error{{bit-field 'bitfield' has negative width (-5)}}
     58 };
     59 
     60 template<typename T, T I>
     61 struct BitfieldNeg2 {
     62   int bitfield : (-I); // expected-error{{bit-field 'bitfield' has negative width (-5)}}
     63 };
     64 
     65 void test_BitfieldNeg() {
     66   (void)sizeof(BitfieldNeg<-5>); // okay
     67   (void)sizeof(BitfieldNeg<5>); // expected-note{{in instantiation of template class 'BitfieldNeg<5>' requested here}}
     68   (void)sizeof(BitfieldNeg2<int, -5>); // okay
     69   (void)sizeof(BitfieldNeg2<int, 5>); // expected-note{{in instantiation of template class 'BitfieldNeg2<int, 5>' requested here}}
     70 }
     71 
     72 template<typename T>
     73 void increment(T &x) {
     74   (void)++x;
     75 }
     76 
     77 struct Incrementable {
     78   Incrementable &operator++();
     79 };
     80 
     81 void test_increment(Incrementable inc) {
     82   increment(inc);
     83 }
     84 
     85 template<typename T>
     86 void add(const T &x) {
     87   (void)(x + x);
     88 }
     89 
     90 namespace PR6237 {
     91   template <typename T>
     92   void f(T t) {
     93     t++;
     94   }
     95 
     96   struct B { };
     97   B operator++(B &, int);
     98 
     99   template void f(B);
    100 }
    101 
    102 struct Addable {
    103   Addable operator+(const Addable&) const;
    104 };
    105 
    106 void test_add(Addable &a) {
    107   add(a);
    108 }
    109 
    110 struct CallOperator {
    111   int &operator()(int);
    112   double &operator()(double);
    113 };
    114 
    115 template<typename Result, typename F, typename Arg1>
    116 Result test_call_operator(F f, Arg1 arg1) {
    117   // PR5266: non-dependent invocations of a function call operator.
    118   CallOperator call_op;
    119   int &ir = call_op(17);
    120   return f(arg1);
    121 }
    122 
    123 void test_call_operator(CallOperator call_op, int i, double d) {
    124   int &ir = test_call_operator<int&>(call_op, i);
    125   double &dr = test_call_operator<double&>(call_op, d);
    126 }
    127 
    128 template<typename T>
    129 void test_asm(T t) {
    130   asm ("nop" : "=r"(*t) : "r"(*t)); // expected-error {{indirection requires pointer operand ('int' invalid)}}
    131 }
    132 
    133 void test_asm() {
    134   int* a;
    135   test_asm(a);
    136 
    137   int b;
    138   test_asm(b); // expected-note {{in instantiation of function template specialization 'test_asm<int>' requested here}}
    139 }
    140 
    141 namespace PR6424 {
    142   template<int I> struct X {
    143     X() {
    144       int *ip = I; // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}}
    145     }
    146   };
    147 
    148   template<int> struct Y {
    149     typedef X<7> X7;
    150 
    151     void f() { X7(); } // expected-note{{instantiation}}
    152   };
    153 
    154   template void Y<3>::f();
    155 
    156   template<int I>
    157   struct X2 {
    158     void *operator new(__SIZE_TYPE__) {
    159       int *ip = I; // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}}
    160       return ip;
    161     }
    162   };
    163 
    164   template<int> struct Y2 {
    165     typedef X2<7> X;
    166     void f() {
    167       new X(); // expected-note{{instantiation of}}
    168     }
    169   };
    170 
    171   template void Y2<3>::f();
    172 
    173   template<typename T>
    174   void rdar10283928(int count) {
    175     (void)new char[count]();
    176   }
    177 
    178   template void rdar10283928<int>(int);
    179 }
    180 
    181 namespace PR10864 {
    182   template<typename T> class Vals {};
    183   template<> class Vals<int> { public: static const int i = 1; };
    184   template<> class Vals<float> { public: static const double i; };
    185   template<typename T> void test_asm_tied(T o) {
    186     __asm("addl $1, %0" : "=r" (o) : "0"(Vals<T>::i)); // expected-error {{input with type 'double' matching output with type 'float'}}
    187   }
    188   void test_asm_tied() {
    189     test_asm_tied(1);
    190     test_asm_tied(1.f); // expected-note {{instantiation of}}
    191   }
    192 }
    193