instantiate-static-var.cpp revision 2afce7248b7a362f1e322ad18e43484d575b9c9d
13d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor// RUN: clang-cc -fsyntax-only -verify %s
23d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregortemplate<typename T, T Divisor>
33d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregorclass X {
43d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregorpublic:
53d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor  static const T value = 10 / Divisor; // expected-error{{in-class initializer is not an integral constant expression}}
63d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor};
73d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor
83d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregorint array1[X<int, 2>::value == 5? 1 : -1];
93d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas GregorX<int, 0> xi0; // expected-note{{in instantiation of template class 'class X<int, 0>' requested here}}
103d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor
113d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor
123d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregortemplate<typename T>
133d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregorclass Y {
143d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor  static const T value = 0; // expected-error{{'value' can only be initialized if it is a static const integral data member}}
153d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor};
163d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor
173d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas GregorY<float> fy; // expected-note{{in instantiation of template class 'class Y<float>' requested here}}
1865b90055dd30cfb83d8344ff62ed428257431be4Douglas Gregor
1965b90055dd30cfb83d8344ff62ed428257431be4Douglas Gregor
2065b90055dd30cfb83d8344ff62ed428257431be4Douglas Gregor// out-of-line static member variables
2165b90055dd30cfb83d8344ff62ed428257431be4Douglas Gregor
2265b90055dd30cfb83d8344ff62ed428257431be4Douglas Gregortemplate<typename T>
2365b90055dd30cfb83d8344ff62ed428257431be4Douglas Gregorstruct Z {
2465b90055dd30cfb83d8344ff62ed428257431be4Douglas Gregor  static T value;
2565b90055dd30cfb83d8344ff62ed428257431be4Douglas Gregor};
2665b90055dd30cfb83d8344ff62ed428257431be4Douglas Gregor
2765b90055dd30cfb83d8344ff62ed428257431be4Douglas Gregortemplate<typename T>
2865b90055dd30cfb83d8344ff62ed428257431be4Douglas GregorT Z<T>::value; // expected-error{{no matching constructor}}
2965b90055dd30cfb83d8344ff62ed428257431be4Douglas Gregor
3065b90055dd30cfb83d8344ff62ed428257431be4Douglas Gregorstruct DefCon {};
3165b90055dd30cfb83d8344ff62ed428257431be4Douglas Gregor
3265b90055dd30cfb83d8344ff62ed428257431be4Douglas Gregorstruct NoDefCon {
3365b90055dd30cfb83d8344ff62ed428257431be4Douglas Gregor  NoDefCon(const NoDefCon&);
3465b90055dd30cfb83d8344ff62ed428257431be4Douglas Gregor};
3565b90055dd30cfb83d8344ff62ed428257431be4Douglas Gregor
3665b90055dd30cfb83d8344ff62ed428257431be4Douglas Gregorvoid test() {
3765b90055dd30cfb83d8344ff62ed428257431be4Douglas Gregor  DefCon &DC = Z<DefCon>::value;
3865b90055dd30cfb83d8344ff62ed428257431be4Douglas Gregor  NoDefCon &NDC = Z<NoDefCon>::value; // expected-note{{instantiation}}
3908e252425ca2cbdc44ba65d9a657ed5398014e36Owen Anderson}
402afce7248b7a362f1e322ad18e43484d575b9c9dDouglas Gregor
412afce7248b7a362f1e322ad18e43484d575b9c9dDouglas Gregor// PR5609
422afce7248b7a362f1e322ad18e43484d575b9c9dDouglas Gregorstruct X1 {
432afce7248b7a362f1e322ad18e43484d575b9c9dDouglas Gregor  ~X1();  // The errors won't be triggered without this dtor.
442afce7248b7a362f1e322ad18e43484d575b9c9dDouglas Gregor};
452afce7248b7a362f1e322ad18e43484d575b9c9dDouglas Gregor
462afce7248b7a362f1e322ad18e43484d575b9c9dDouglas Gregortemplate <typename T>
472afce7248b7a362f1e322ad18e43484d575b9c9dDouglas Gregorstruct Y1 {
482afce7248b7a362f1e322ad18e43484d575b9c9dDouglas Gregor  static char Helper(T);
492afce7248b7a362f1e322ad18e43484d575b9c9dDouglas Gregor  static const int value = sizeof(Helper(T()));
502afce7248b7a362f1e322ad18e43484d575b9c9dDouglas Gregor};
512afce7248b7a362f1e322ad18e43484d575b9c9dDouglas Gregor
522afce7248b7a362f1e322ad18e43484d575b9c9dDouglas Gregorstruct X2 {
532afce7248b7a362f1e322ad18e43484d575b9c9dDouglas Gregor  virtual ~X2();
542afce7248b7a362f1e322ad18e43484d575b9c9dDouglas Gregor};
552afce7248b7a362f1e322ad18e43484d575b9c9dDouglas Gregor
562afce7248b7a362f1e322ad18e43484d575b9c9dDouglas Gregornamespace std {
572afce7248b7a362f1e322ad18e43484d575b9c9dDouglas Gregor  class type_info { };
582afce7248b7a362f1e322ad18e43484d575b9c9dDouglas Gregor}
592afce7248b7a362f1e322ad18e43484d575b9c9dDouglas Gregor
602afce7248b7a362f1e322ad18e43484d575b9c9dDouglas Gregortemplate <typename T>
612afce7248b7a362f1e322ad18e43484d575b9c9dDouglas Gregorstruct Y2 {
622afce7248b7a362f1e322ad18e43484d575b9c9dDouglas Gregor  static T &Helper();
632afce7248b7a362f1e322ad18e43484d575b9c9dDouglas Gregor  static const int value = sizeof(typeid(Helper()));
642afce7248b7a362f1e322ad18e43484d575b9c9dDouglas Gregor};
652afce7248b7a362f1e322ad18e43484d575b9c9dDouglas Gregor
662afce7248b7a362f1e322ad18e43484d575b9c9dDouglas Gregortemplate <int>
672afce7248b7a362f1e322ad18e43484d575b9c9dDouglas Gregorstruct Z1 {};
682afce7248b7a362f1e322ad18e43484d575b9c9dDouglas Gregor
692afce7248b7a362f1e322ad18e43484d575b9c9dDouglas Gregorvoid Test() {
702afce7248b7a362f1e322ad18e43484d575b9c9dDouglas Gregor  Z1<Y1<X1>::value> x;
712afce7248b7a362f1e322ad18e43484d575b9c9dDouglas Gregor  int y[Y1<X1>::value];
722afce7248b7a362f1e322ad18e43484d575b9c9dDouglas Gregor  Z1<Y2<X2>::value> x2;
732afce7248b7a362f1e322ad18e43484d575b9c9dDouglas Gregor  int y2[Y2<X2>::value];
742afce7248b7a362f1e322ad18e43484d575b9c9dDouglas Gregor}
75