1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
|
// RUN: %clang_cc1 -fsyntax-only -verify %s
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
template<typename T, T Divisor>
class X {
public:
static const T value = 10 / Divisor; // expected-error{{in-class initializer for static data member is not a constant expression}}
};
int array1[X<int, 2>::value == 5? 1 : -1];
X<int, 0> xi0; // expected-note{{in instantiation of template class 'X<int, 0>' requested here}}
template<typename T>
class Y {
static const T value = 0;
#if __cplusplus <= 199711L
// expected-warning@-2 {{in-class initializer for static data member of type 'const float' is a GNU extension}}
#else
// expected-error@-4 {{in-class initializer for static data member of type 'const float' requires 'constexpr' specifier}}
// expected-note@-5 {{add 'constexpr'}}
#endif
};
Y<float> fy; // expected-note{{in instantiation of template class 'Y<float>' requested here}}
// out-of-line static member variables
template<typename T>
struct Z {
static T value;
};
template<typename T>
T Z<T>::value; // expected-error{{no matching constructor}}
struct DefCon {};
struct NoDefCon {
NoDefCon(const NoDefCon&); // expected-note{{candidate constructor}}
};
void test() {
DefCon &DC = Z<DefCon>::value;
NoDefCon &NDC = Z<NoDefCon>::value; // expected-note{{instantiation}}
}
// PR5609
struct X1 {
~X1(); // The errors won't be triggered without this dtor.
};
template <typename T>
struct Y1 {
static char Helper(T);
static const int value = sizeof(Helper(T()));
};
struct X2 {
virtual ~X2();
};
namespace std {
class type_info { };
}
template <typename T>
struct Y2 {
static T &Helper();
static const int value = sizeof(typeid(Helper()));
};
template <int>
struct Z1 {};
void Test() {
Z1<Y1<X1>::value> x;
int y[Y1<X1>::value];
Z1<Y2<X2>::value> x2;
int y2[Y2<X2>::value];
}
// PR5672
template <int n>
struct X3 {};
class Y3 {
public:
~Y3(); // The error isn't triggered without this dtor.
void Foo(X3<1>);
};
template <typename T>
struct SizeOf {
static const int value = sizeof(T);
};
void MyTest3() {
Y3().Foo(X3<SizeOf<char>::value>());
}
namespace PR6449 {
template<typename T>
struct X0 {
static const bool var = false;
};
template<typename T>
const bool X0<T>::var;
template<typename T>
struct X1 : public X0<T> {
static const bool var = false;
};
template<typename T>
const bool X1<T>::var;
template class X0<char>;
template class X1<char>;
}
typedef char MyString[100];
template <typename T>
struct StaticVarWithTypedefString {
static MyString str;
};
template <typename T>
MyString StaticVarWithTypedefString<T>::str = "";
void testStaticVarWithTypedefString() {
(void)StaticVarWithTypedefString<int>::str;
}
namespace ArrayBound {
#if __cplusplus >= 201103L
template<typename T> void make_unique(T &&);
template<typename> struct Foo {
static constexpr char kMessage[] = "abc";
static void f() { make_unique(kMessage); }
static void g1() { const char (&ref)[4] = kMessage; } // OK
// We can diagnose this prior to instantiation because kMessage is not type-dependent.
static void g2() { const char (&ref)[5] = kMessage; } // expected-error {{could not bind}}
};
template void Foo<int>::f();
#endif
template<typename> struct Bar {
static const char kMessage[];
// Here, kMessage is type-dependent, so we don't diagnose until
// instantiation.
static void g1() { const char (&ref)[4] = kMessage; } // expected-error {{could not bind to an lvalue of type 'const char [5]'}}
static void g2() { const char (&ref)[5] = kMessage; } // expected-error {{could not bind to an lvalue of type 'const char [4]'}}
};
template<typename T> const char Bar<T>::kMessage[] = "foo";
template void Bar<int>::g1();
template void Bar<int>::g2(); // expected-note {{in instantiation of}}
template<> const char Bar<char>::kMessage[] = "foox";
template void Bar<char>::g1(); // expected-note {{in instantiation of}}
template void Bar<char>::g2();
}
|