Home | History | Annotate | Download | only in SemaCXX
      1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s -fblocks
      2 
      3 void test_nest_lambda() {
      4   int x;
      5   int y;
      6   [&,y]() {
      7     int z;
      8     #pragma clang __debug captured
      9     {
     10       x = y; // OK
     11       y = z; // expected-error{{cannot assign to a variable captured by copy in a non-mutable lambda}}
     12       z = y; // OK
     13     }
     14   }();
     15 
     16   int a;
     17   #pragma clang __debug captured
     18   {
     19     int b;
     20     int c;
     21     [&,c]() {
     22       a = b; // OK
     23       b = c; // OK
     24       c = a; // expected-error{{cannot assign to a variable captured by copy in a non-mutable lambda}}
     25     }();
     26   }
     27 }
     28 
     29 class test_obj_capture {
     30   int a;
     31   void b();
     32   static void test() {
     33     test_obj_capture c;
     34     #pragma clang __debug captured
     35     { (void)c.a; }  // OK
     36     #pragma clang __debug captured
     37     { c.b(); }      // OK
     38   }
     39 };
     40 
     41 class test_this_capture {
     42   int a;
     43   void b();
     44   void test() {
     45     #pragma clang __debug captured
     46     { (void)this; } // OK
     47     #pragma clang __debug captured
     48     { (void)a; }    // OK
     49     #pragma clang __debug captured
     50     { b(); }        // OK
     51   }
     52 };
     53 
     54 template <typename T>
     55 void template_capture_var() {
     56   T x; // expected-error{{declaration of reference variable 'x' requires an initializer}}
     57   #pragma clang _debug captured
     58   {
     59     (void)x;
     60   }
     61 }
     62 
     63 template <typename T>
     64 class Val {
     65   T v;
     66 public:
     67   void set(const T &v0) {
     68     #pragma clang __debug captured
     69     {
     70       v = v0;
     71     }
     72   }
     73 };
     74 
     75 void test_capture_var() {
     76   template_capture_var<int>(); // OK
     77   template_capture_var<int&>(); // expected-note{{in instantiation of function template specialization 'template_capture_var<int &>' requested here}}
     78 
     79   Val<float> Obj;
     80   Obj.set(0.0f); // OK
     81 }
     82 
     83 template <typename S, typename T>
     84 S template_capture_var(S x, T y) {  // expected-note{{variable 'y' declared const here}}
     85   #pragma clang _debug captured
     86   {
     87     x++;
     88     y++;  // expected-error{{cannot assign to variable 'y' with const-qualified type 'const int'}}
     89   }
     90 
     91   return x;
     92 }
     93 
     94 // Check if can recover from a template error.
     95 void test_capture_var_error() {
     96   template_capture_var<int, int>(0, 1); // OK
     97   template_capture_var<int, const int>(0, 1); // expected-note{{in instantiation of function template specialization 'template_capture_var<int, const int>' requested here}}
     98   template_capture_var<int, int>(0, 1); // OK
     99 }
    100 
    101 template <typename T>
    102 void template_capture_in_lambda() {
    103   T x, y;
    104   [=, &y]() {
    105     #pragma clang __debug captured
    106     {
    107       y += x;
    108     }
    109   }();
    110 }
    111 
    112 void test_lambda() {
    113   template_capture_in_lambda<int>(); // OK
    114 }
    115 
    116 struct Foo {
    117   void foo() { }
    118   static void bar() { }
    119 };
    120 
    121 template <typename T>
    122 void template_capture_func(T &t) {
    123   #pragma clang __debug captured
    124   {
    125     t.foo();
    126   }
    127 
    128   #pragma clang __debug captured
    129   {
    130     T::bar();
    131   }
    132 }
    133 
    134 void test_template_capture_func() {
    135   Foo Obj;
    136   template_capture_func(Obj);
    137 }
    138 
    139 template <typename T>
    140 T captured_sum(const T &a, const T &b) {
    141   T result;
    142 
    143   #pragma clang __debug captured
    144   {
    145     result = a + b;
    146   }
    147 
    148   return result;
    149 }
    150 
    151 template <typename T, typename... Args>
    152 T captured_sum(const T &a, const Args&... args) {
    153   T result;
    154 
    155   #pragma clang __debug captured
    156   {
    157     result = a + captured_sum(args...);
    158   }
    159 
    160   return result;
    161 }
    162 
    163 void test_capture_variadic() {
    164   (void)captured_sum(1, 2, 3); // OK
    165   (void)captured_sum(1, 2, 3, 4, 5); // OK
    166 }
    167 
    168 void test_capture_with_attributes() {
    169   [[]] // expected-error {{an attribute list cannot appear here}}
    170   #pragma clang __debug captured
    171   {
    172   }
    173 }
    174