Home | History | Annotate | Download | only in class.inhctor
      1 // RUN: %clang_cc1 -std=c++11 -verify %s
      2 
      3 template<int> struct X {};
      4 
      5 // Constructor characteristics are:
      6 //   - the template parameter list
      7 //   - the parameter-type-list
      8 //   - absence or presence of explicit
      9 //   - absence or presence of constexpr
     10 struct 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 
     17 A a0 { X<0>{} };
     18 A a0i = { X<0>{} };
     19 constexpr A a0c { X<0>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}}
     20 constexpr A a0ic = { X<0>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}}
     21 
     22 A a1 { X<1>{} };
     23 A a1i = { X<1>{} };
     24 constexpr A a1c { X<1>{} };
     25 constexpr A a1ic = { X<1>{} };
     26 
     27 A a2 { X<2>{} };
     28 A a2i = { X<2>{} }; // expected-error {{constructor is explicit}}
     29 constexpr A a2c { X<2>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}}
     30 constexpr A a2ic = { X<2>{} }; // expected-error {{constructor is explicit}}
     31 
     32 A a3 { X<3>{} };
     33 A a3i = { X<3>{} }; // expected-error {{constructor is explicit}}
     34 constexpr A a3c { X<3>{} };
     35 constexpr A a3ic = { X<3>{} }; // expected-error {{constructor is explicit}}
     36 
     37 
     38 struct B : A {
     39   using A::A; // expected-note 7{{here}}
     40 };
     41 
     42 B b0 { X<0>{} };
     43 B b0i = { X<0>{} };
     44 constexpr B b0c { X<0>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}}
     45 constexpr B b0ic = { X<0>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}}
     46 
     47 B b1 { X<1>{} };
     48 B b1i = { X<1>{} };
     49 constexpr B b1c { X<1>{} };
     50 constexpr B b1ic = { X<1>{} };
     51 
     52 B b2 { X<2>{} };
     53 B b2i = { X<2>{} }; // expected-error {{constructor is explicit}}
     54 constexpr B b2c { X<2>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}}
     55 constexpr B b2ic = { X<2>{} }; // expected-error {{constructor is explicit}}
     56 
     57 B b3 { X<3>{} };
     58 B b3i = { X<3>{} }; // expected-error {{constructor is explicit}}
     59 constexpr B b3c { X<3>{} };
     60 constexpr B b3ic = { X<3>{} }; // expected-error {{constructor is explicit}}
     61 
     62 
     63 // 'constexpr' is OK even if the constructor doesn't obey the constraints.
     64 struct NonLiteral { NonLiteral(); };
     65 struct NonConstexpr { NonConstexpr(); constexpr NonConstexpr(int); }; // expected-note {{here}}
     66 struct Constexpr { constexpr Constexpr(int) {} };
     67 
     68 struct BothNonLiteral : NonLiteral, Constexpr { using Constexpr::Constexpr; }; // expected-note {{base class 'NonLiteral' of non-literal type}}
     69 constexpr BothNonLiteral bothNL{42}; // expected-error {{constexpr variable cannot have non-literal type 'const BothNonLiteral'}}
     70 
     71 struct BothNonConstexpr : NonConstexpr, Constexpr { using Constexpr::Constexpr; }; // expected-note {{non-constexpr constructor 'NonConstexpr}}
     72 constexpr BothNonConstexpr bothNC{42}; // expected-error {{must be initialized by a constant expression}} expected-note {{in call to 'BothNonConstexpr(42)'}}
     73 
     74 
     75 struct ConstexprEval {
     76   constexpr ConstexprEval(int a, const char *p) : k(p[a]) {}
     77   char k;
     78 };
     79 struct ConstexprEval2 {
     80   char k2 = 'x';
     81 };
     82 struct ConstexprEval3 : ConstexprEval, ConstexprEval2 {
     83   using ConstexprEval::ConstexprEval;
     84 };
     85 constexpr ConstexprEval3 ce{4, "foobar"};
     86 static_assert(ce.k == 'a', "");
     87 static_assert(ce.k2 == 'x', "");
     88 
     89 
     90 struct 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 
     99 struct UsingTemplateCtors : TemplateCtors {
    100   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 
    111 template<int> struct Y {};
    112 constexpr UsingTemplateCtors uct1{ X<0>{}, X<0>{} };
    113 constexpr UsingTemplateCtors uct2{ X<0>{}, Y<0>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}}
    114 constexpr UsingTemplateCtors uct3{ X<1>{}, X<0>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}}
    115 constexpr UsingTemplateCtors uct4{ X<1>{}, X<1>{} };
    116 constexpr UsingTemplateCtors uct5{ X<2>{}, 0 }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}}
    117 constexpr UsingTemplateCtors uct6{ X<2>{}, X<2>{} };
    118 
    119 constexpr UsingTemplateCtors utc7{ 0 }; // expected-error {{ambiguous}}
    120 constexpr UsingTemplateCtors utc8{ 0, 0 }; // ok
    121 constexpr UsingTemplateCtors utc9{ 0, 0, 0 }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}}
    122