templates.cpp revision 87d948ecccffea9e9e37d0d053b246e2d6d6c47b
1// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Winvalid-noreturn %s -verify
2
3template<typename T>
4void test_attributes() {
5  // FIXME: GCC accepts [[gnu::noreturn]] here.
6  auto nrl = []() [[gnu::noreturn]] {}; // expected-warning{{attribute '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 &ti
80      = 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 &ti
91      = typeid([=,&r] () -> R& {
92          boom.tickle(); // expected-note{{in instantiation of member function}}
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 NonLocalLambdaInstantation {
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 'NonLocalLambdaInstantation::X2<int *>::x' requested here}}
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{{implicit default constructor for 'NonLocalLambdaInstantation::X2<int *>' first required here}}
149}
150