150 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Winvalid-noreturn %s -verify2 3template<typename T>4void test_attributes() {5 // FIXME: GCC accepts [[gnu::noreturn]] here.6 auto nrl = []() [[gnu::noreturn]] {}; // expected-warning{{attribute 'gnu::noreturn' ignored}}7}8 9template void test_attributes<int>();10 11template<typename T>12void call_with_zero() {13 [](T *ptr) -> T& { return *ptr; }(0);14}15 16template void call_with_zero<int>();17 18template<typename T>19T captures(T x, T y) {20 auto lambda = [=, &y] () -> T {21 T i = x;22 return i + y;23 };24 25 return lambda();26}27 28struct X {29 X(const X&);30};31 32X operator+(X, X);33X operator-(X, X);34 35template int captures(int, int);36template X captures(X, X);37 38template<typename T>39int infer_result(T x, T y) {40 auto lambda = [=](bool b) { return x + y; };41 return lambda(true); // expected-error{{no viable conversion from returned value of type 'X' to function return type 'int'}}42}43 44template int infer_result(int, int);45template int infer_result(X, X); // expected-note{{in instantiation of function template specialization 'infer_result<X>' requested here}}46 47// Make sure that lambda's operator() can be used from templates.48template<typename F>49void accept_lambda(F f) {50 f(1);51}52 53template<typename T>54void pass_lambda(T x) {55 accept_lambda([&x](T y) { return x + y; });56}57 58template void pass_lambda(int);59 60namespace std {61 class type_info;62}63 64namespace p2 {65 struct P {66 virtual ~P();67 };68 69 template<typename T>70 struct Boom {71 Boom(const Boom&) { 72 T* x = 1; // expected-error{{cannot initialize a variable of type 'float *' with an rvalue of type 'int'}}73 }74 void tickle() const;75 };76 77 template<typename R, typename T>78 void odr_used(R &r, Boom<T> boom) {79 const std::type_info &ti80 = typeid([=,&r] () -> R& { // expected-error{{lambda expression in an unevaluated operand}}81 boom.tickle();82 return r; 83 }()); 84 }85 86 template void odr_used(int&, Boom<int>); // expected-note{{in instantiation of function template specialization}}87 88 template<typename R, typename T>89 void odr_used2(R &r, Boom<T> boom) {90 const std::type_info &ti91 = typeid([=,&r] () -> R& { // expected-note{{in instantiation of member function 'p2::Boom<float>::Boom' requested here}}92 boom.tickle();93 return r; 94 }()); 95 }96 97 template void odr_used2(P&, Boom<float>);98}99 100namespace p5 {101 struct NonConstCopy {102 NonConstCopy(const NonConstCopy&) = delete;103 NonConstCopy(NonConstCopy&);104 };105 106 template<typename T>107 void double_capture(T &nc) {108 [=] () mutable {109 [=] () mutable {110 T nc2(nc);111 }();112 }();113 }114 115 template void double_capture(NonConstCopy&);116}117 118namespace NonLocalLambdaInstantiation {119 template<typename T>120 struct X {121 static int value;122 };123 124 template<typename T>125 int X<T>::value = []{ return T(); }(); // expected-error{{cannot initialize a variable of type 'int' with an rvalue of type 'int *'}}126 127 template int X<int>::value;128 template int X<float>::value;129 template int X<int*>::value; // expected-note{{in instantiation of static data member }}130 131 template<typename T>132 void defaults(int x = []{ return T(); }()) { }; // expected-error{{cannot initialize a parameter of type 'int' with an rvalue of type 'int *'}} \133 // expected-note{{passing argument to parameter 'x' here}}134 135 void call_defaults() {136 defaults<int>();137 defaults<float>();138 defaults<int*>(); // expected-note{{in instantiation of default function argument expression for 'defaults<int *>' required here}}139 }140 141 template<typename T>142 struct X2 { // expected-note{{in instantiation of default member initializer 'NonLocalLambdaInstantiation::X2<int *>::x'}}143 int x = []{ return T(); }(); // expected-error{{cannot initialize a member subobject of type 'int' with an rvalue of type 'int *'}}144 };145 146 X2<int> x2i;147 X2<float> x2f;148 X2<int*> x2ip; // expected-note {{in evaluation of exception spec}}149}150