blob: d1c16ff886c38b807883c54773340a9022b4a4f6 [file] [log] [blame]
Richard Smith07b0fdc2013-03-18 21:12:30 +00001// RUN: %clang_cc1 -std=c++11 -verify %s
2
3template<int> struct X {};
4
5// Constructor characteristics are:
Richard Smith4841ca52013-04-10 05:48:59 +00006// - the template parameter list
Richard Smith07b0fdc2013-03-18 21:12:30 +00007// - the parameter-type-list
8// - absence or presence of explicit
9// - absence or presence of constexpr
10struct A {
11 A(X<0>) {} // expected-note 2{{here}}
12 constexpr A(X<1>) {}
13 explicit A(X<2>) {} // expected-note 3{{here}}
14 explicit constexpr A(X<3>) {} // expected-note 2{{here}}
15};
16
17A a0 { X<0>{} };
18A a0i = { X<0>{} };
19constexpr A a0c { X<0>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}}
20constexpr A a0ic = { X<0>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}}
21
22A a1 { X<1>{} };
23A a1i = { X<1>{} };
24constexpr A a1c { X<1>{} };
25constexpr A a1ic = { X<1>{} };
26
27A a2 { X<2>{} };
28A a2i = { X<2>{} }; // expected-error {{constructor is explicit}}
29constexpr A a2c { X<2>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}}
30constexpr A a2ic = { X<2>{} }; // expected-error {{constructor is explicit}}
31
32A a3 { X<3>{} };
33A a3i = { X<3>{} }; // expected-error {{constructor is explicit}}
34constexpr A a3c { X<3>{} };
35constexpr A a3ic = { X<3>{} }; // expected-error {{constructor is explicit}}
36
37
38struct B : A {
39 using A::A; // expected-note 7{{here}}
40};
41
42B b0 { X<0>{} };
43B b0i = { X<0>{} };
44constexpr B b0c { X<0>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}}
45constexpr B b0ic = { X<0>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}}
46
47B b1 { X<1>{} };
48B b1i = { X<1>{} };
49constexpr B b1c { X<1>{} };
50constexpr B b1ic = { X<1>{} };
51
52B b2 { X<2>{} };
53B b2i = { X<2>{} }; // expected-error {{constructor is explicit}}
54constexpr B b2c { X<2>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}}
55constexpr B b2ic = { X<2>{} }; // expected-error {{constructor is explicit}}
56
57B b3 { X<3>{} };
58B b3i = { X<3>{} }; // expected-error {{constructor is explicit}}
59constexpr B b3c { X<3>{} };
60constexpr B b3ic = { X<3>{} }; // expected-error {{constructor is explicit}}
61
62
63// 'constexpr' is OK even if the constructor doesn't obey the constraints.
64struct NonLiteral { NonLiteral(); };
65struct NonConstexpr { NonConstexpr(); constexpr NonConstexpr(int); }; // expected-note {{here}}
66struct Constexpr { constexpr Constexpr(int) {} };
67
68struct BothNonLiteral : NonLiteral, Constexpr { using Constexpr::Constexpr; }; // expected-note {{base class 'NonLiteral' of non-literal type}}
69constexpr BothNonLiteral bothNL{42}; // expected-error {{constexpr variable cannot have non-literal type 'const BothNonLiteral'}}
70
71struct BothNonConstexpr : NonConstexpr, Constexpr { using Constexpr::Constexpr; }; // expected-note {{non-constexpr constructor 'NonConstexpr}}
72constexpr BothNonConstexpr bothNC{42}; // expected-error {{must be initialized by a constant expression}} expected-note {{in call to 'BothNonConstexpr(42)'}}
73
74
75struct ConstexprEval {
76 constexpr ConstexprEval(int a, const char *p) : k(p[a]) {}
77 char k;
78};
79struct ConstexprEval2 {
80 char k2 = 'x';
81};
82struct ConstexprEval3 : ConstexprEval, ConstexprEval2 {
83 using ConstexprEval::ConstexprEval;
84};
85constexpr ConstexprEval3 ce{4, "foobar"};
86static_assert(ce.k == 'a', "");
87static_assert(ce.k2 == 'x', "");
Richard Smith4841ca52013-04-10 05:48:59 +000088
89
90struct TemplateCtors {
91 constexpr TemplateCtors() {}
92 template<template<int> class T> TemplateCtors(X<0>, T<0>);
93 template<int N> TemplateCtors(X<1>, X<N>);
94 template<typename T> TemplateCtors(X<2>, T);
95
96 template<typename T = int> TemplateCtors(int, int = 0, int = 0); // expected-note {{inherited from here}}
97};
98
Stephen Hines0e2c34f2015-03-23 12:09:02 -070099struct UsingTemplateCtors : TemplateCtors { // expected-note 2{{candidate is the implicit}}
Richard Smith4841ca52013-04-10 05:48:59 +0000100 using TemplateCtors::TemplateCtors; // expected-note 4{{here}} expected-note {{candidate}}
101
102 constexpr UsingTemplateCtors(X<0>, X<0>) {}
103 constexpr UsingTemplateCtors(X<1>, X<1>) {}
104 constexpr UsingTemplateCtors(X<2>, X<2>) {}
105
106 template<int = 0> constexpr UsingTemplateCtors(int) {} // expected-note {{candidate}}
107 template<typename T = void> constexpr UsingTemplateCtors(int, int) {}
108 template<typename T, typename U> constexpr UsingTemplateCtors(int, int, int) {}
109};
110
111template<int> struct Y {};
112constexpr UsingTemplateCtors uct1{ X<0>{}, X<0>{} };
113constexpr UsingTemplateCtors uct2{ X<0>{}, Y<0>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}}
114constexpr UsingTemplateCtors uct3{ X<1>{}, X<0>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}}
115constexpr UsingTemplateCtors uct4{ X<1>{}, X<1>{} };
116constexpr UsingTemplateCtors uct5{ X<2>{}, 0 }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}}
117constexpr UsingTemplateCtors uct6{ X<2>{}, X<2>{} };
118
119constexpr UsingTemplateCtors utc7{ 0 }; // expected-error {{ambiguous}}
120constexpr UsingTemplateCtors utc8{ 0, 0 }; // ok
121constexpr UsingTemplateCtors utc9{ 0, 0, 0 }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}}