Home | History | Annotate | Download | only in dcl.constexpr
      1 // RUN: %clang_cc1 -verify -std=c++11 %s
      2 
      3 namespace N {
      4   typedef char C;
      5 }
      6 
      7 namespace M {
      8   typedef double D;
      9 }
     10 
     11 struct NonLiteral {
     12   NonLiteral() {}
     13   NonLiteral(int) {}
     14   operator int() const { return 0; }
     15 };
     16 struct Literal {
     17   constexpr Literal() {}
     18   operator int() const { return 0; }
     19 };
     20 
     21 struct S {
     22   virtual int ImplicitlyVirtual();
     23 };
     24 struct T {};
     25 
     26 template<typename T> struct ImplicitVirtualFromDependentBase : T {
     27   constexpr int ImplicitlyVirtual() { return 0; }
     28 };
     29 
     30 // FIXME: Can't test this until we have function invocation substitution
     31 #if 0
     32 constexpr int a = ImplicitVirtualFromDependentBase<S>().ImplicitlyVirtual(); // desired-error {{not a constant expression}}
     33 constexpr int b = ImplicitVirtualFromDependentBase<T>().ImplicitlyVirtual(); // ok
     34 #endif
     35 
     36 template<typename R> struct ConstexprMember {
     37   constexpr R F() { return 0; }
     38 };
     39 // FIXME: Can't test this until we have function invocation substitution
     40 #if 0
     41 constexpr int c = ConstexprMember<int>().F(); // ok
     42 constexpr int d = ConstexprMember<NonLiteral>().F(); // desired-error {{not a constant expression}}
     43 #endif
     44 
     45 template<typename ...P> struct ConstexprCtor { // expected-note 2{{no constexpr constructors}}
     46   constexpr ConstexprCtor(P...); // expected-note {{constructor template instantiation is not constexpr because 1st parameter type 'NonLiteral' is not a literal type}} \
     47                                     expected-note {{constructor template instantiation is not constexpr because 2nd parameter type 'NonLiteral' is not a literal type}}
     48 };
     49 constexpr ConstexprCtor<> f1(); // ok
     50 constexpr ConstexprCtor<int> f2(); // ok
     51 constexpr ConstexprCtor<NonLiteral> f3(); // expected-error {{not a literal type}}
     52 constexpr ConstexprCtor<int, NonLiteral> f4(); // expected-error {{not a literal type}}
     53 
     54 struct VirtBase : virtual S {}; // expected-note {{here}}
     55 
     56 namespace TemplateVBase {
     57   template<typename T> struct T1 : virtual Literal { // expected-note {{here}}
     58     constexpr T1(); // expected-error {{constexpr constructor not allowed in struct with virtual base class}}
     59   };
     60 
     61   template<typename T> struct T2 : virtual T { // expected-note {{struct with virtual base class is not a literal type}} expected-note {{here}}
     62     // FIXME: This is ill-formed (no diagnostic required).
     63     // We should diagnose it now rather than waiting until instantiation.
     64     constexpr T2(); // desired-error {{constexpr constructor not allowed in class with virtual base classes}}
     65   };
     66   constexpr T2<Literal> g2(); // expected-error {{not a literal type}}
     67 
     68   template<typename T> class T3 : public T { // expected-note {{class with virtual base class is not a literal type}}
     69   public:
     70     constexpr T3() {}
     71   };
     72   constexpr T3<Literal> g3(); // ok
     73   constexpr T3<VirtBase> g4(); // expected-error {{not a literal type}}
     74 }
     75