2011-10-15 04:48:27 +08:00
// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wc++98-compat -verify %s
2014-09-18 10:09:53 +08:00
// RUN: %clang_cc1 -fsyntax-only -std=c++14 -Wc++98-compat -verify %s -DCXX14COMPAT
2011-10-15 04:41:13 +08:00
2012-04-19 14:58:00 +08:00
namespace std {
struct type_info ;
using size_t = decltype ( sizeof ( 0 ) ) ; // expected-warning {{decltype}} expected-warning {{alias}}
template < typename T > struct initializer_list {
initializer_list ( T * , size_t ) ;
T * p ;
size_t n ;
2013-01-12 09:05:20 +08:00
T * begin ( ) ;
T * end ( ) ;
2012-04-19 14:58:00 +08:00
} ;
}
2012-02-25 18:20:59 +08:00
2011-10-15 04:41:13 +08:00
template < typename . . . T > // expected-warning {{variadic templates are incompatible with C++98}}
class Variadic1 { } ;
template < template < typename > class . . . T > // expected-warning {{variadic templates are incompatible with C++98}}
class Variadic2 { } ;
template < int . . . I > // expected-warning {{variadic templates are incompatible with C++98}}
class Variadic3 { } ;
2011-10-15 04:48:27 +08:00
2012-11-07 03:34:54 +08:00
alignas ( 8 ) int with_alignas ; // expected-warning {{'alignas' is incompatible with C++98}}
2014-01-17 08:11:48 +08:00
int with_attribute [[ ]] ; // expected-warning {{C++11 attribute syntax is incompatible with C++98}}
2011-10-15 09:18:56 +08:00
void Literals ( ) {
( void ) u8 " str " ; // expected-warning {{unicode literals are incompatible with C++98}}
( void ) u " str " ; // expected-warning {{unicode literals are incompatible with C++98}}
( void ) U " str " ; // expected-warning {{unicode literals are incompatible with C++98}}
( void ) u ' x ' ; // expected-warning {{unicode literals are incompatible with C++98}}
( void ) U ' x ' ; // expected-warning {{unicode literals are incompatible with C++98}}
( void ) u8R " X(str)X " ; // expected-warning {{raw string literals are incompatible with C++98}}
( void ) uR " X(str)X " ; // expected-warning {{raw string literals are incompatible with C++98}}
( void ) UR " X(str)X " ; // expected-warning {{raw string literals are incompatible with C++98}}
( void ) R " X(str)X " ; // expected-warning {{raw string literals are incompatible with C++98}}
( void ) LR " X(str)X " ; // expected-warning {{raw string literals are incompatible with C++98}}
}
template < typename T > struct S { } ;
2011-10-15 13:09:34 +08:00
namespace TemplateParsing {
S < : : S < void > > s ; // expected-warning {{'<::' is treated as digraph '<:' (aka '[') followed by ':' in C++98}}
S < : : S < void > > t ; // expected-warning {{consecutive right angle brackets are incompatible with C++98 (use '> >')}}
}
void Lambda ( ) {
2012-02-17 04:41:22 +08:00
[ ] { } ( ) ; // expected-warning {{lambda expressions are incompatible with C++98}}
2018-05-16 05:27:30 +08:00
// Don't warn about implicit "-> auto" here.
[ ] ( ) { } ( ) ; // expected-warning {{lambda expressions are incompatible with C++98}}
2011-10-15 13:09:34 +08:00
}
2012-04-19 14:58:00 +08:00
struct Ctor {
Ctor ( int , char ) ;
Ctor ( double , long ) ;
} ;
struct InitListCtor {
InitListCtor ( std : : initializer_list < bool > ) ;
} ;
2012-03-19 06:25:45 +08:00
int InitList ( int i = { } ) { / / expected - warning { { generalized initializer lists are incompatible with C + + 98 } } \
// expected-warning {{scalar initialized from empty initializer list is incompatible with C++98}}
2012-02-12 07:51:08 +08:00
( void ) new int { } ; / / expected - warning { { generalized initializer lists are incompatible with C + + 98 } } \
// expected-warning {{scalar initialized from empty initializer list is incompatible with C++98}}
2012-02-13 02:41:05 +08:00
( void ) int { } ; / / expected - warning { { generalized initializer lists are incompatible with C + + 98 } } \
// expected-warning {{scalar initialized from empty initializer list is incompatible with C++98}}
2011-10-19 05:39:00 +08:00
int x { 0 } ; // expected-warning {{generalized initializer lists are incompatible with C++98}}
2012-02-27 07:49:01 +08:00
S < int > s = { } ; // ok, aggregate
s = { } ; // expected-warning {{generalized initializer lists are incompatible with C++98}}
2012-04-19 14:58:00 +08:00
std : : initializer_list < int > xs = { 1 , 2 , 3 } ; // expected-warning {{initialization of initializer_list object is incompatible with C++98}}
auto ys = { 1 , 2 , 3 } ; / / expected - warning { { initialization of initializer_list object is incompatible with C + + 98 } } \
// expected-warning {{'auto' type specifier is incompatible with C++98}}
Ctor c1 = { 1 , 2 } ; // expected-warning {{constructor call from initializer list is incompatible with C++98}}
Ctor c2 = { 3.0 , 4l } ; // expected-warning {{constructor call from initializer list is incompatible with C++98}}
InitListCtor ilc = { true , false } ; // expected-warning {{initialization of initializer_list object is incompatible with C++98}}
const int & r = { 0 } ; // expected-warning {{reference initialized from initializer list is incompatible with C++98}}
2013-05-31 10:56:17 +08:00
struct { int a ; const int & r ; } rr = { 0 , { 0 } } ; // expected-warning {{reference initialized from initializer list is incompatible with C++98}}
2015-02-12 09:50:05 +08:00
return { 0 } ; // expected-warning {{generalized initializer lists are incompatible with C++98}} expected-warning {{scalar}}
2011-10-15 13:09:34 +08:00
}
2012-03-21 05:24:03 +08:00
struct DelayedDefaultArgumentParseInitList {
2015-02-12 09:50:05 +08:00
void f ( int i = { 1 } ) { // expected-warning {{generalized initializer lists are incompatible with C++98}} expected-warning {{scalar}}
2012-03-21 05:24:03 +08:00
}
} ;
2011-10-15 13:09:34 +08:00
2012-03-05 12:02:15 +08:00
int operator " " _hello ( const char * ) ; // expected-warning {{literal operators are incompatible with C++98}}
2011-10-15 13:09:34 +08:00
enum EnumFixed : int { // expected-warning {{enumeration types with a fixed underlying type are incompatible with C++98}}
} ;
enum class EnumScoped { // expected-warning {{scoped enumerations are incompatible with C++98}}
} ;
void Deleted ( ) = delete ; // expected-warning {{deleted function definitions are incompatible with C++98}}
struct Defaulted {
Defaulted ( ) = default ; // expected-warning {{defaulted function definitions are incompatible with C++98}}
} ;
int & & RvalueReference = 0 ; // expected-warning {{rvalue references are incompatible with C++98}}
struct RefQualifier {
void f ( ) & ; // expected-warning {{reference qualifiers on functions are incompatible with C++98}}
} ;
auto f ( ) - > int ; // expected-warning {{trailing return types are incompatible with C++98}}
2015-11-11 10:02:15 +08:00
# ifdef CXX14COMPAT
auto ff ( ) { return 5 ; } // expected-warning {{'auto' type specifier is incompatible with C++98}}
# endif
2011-10-15 13:09:34 +08:00
void RangeFor ( ) {
int xs [ ] = { 1 , 2 , 3 } ;
for ( int & a : xs ) { // expected-warning {{range-based for loop is incompatible with C++98}}
}
2013-01-12 09:05:20 +08:00
for ( auto & b : { 1 , 2 , 3 } ) {
// expected-warning@-1 {{range-based for loop is incompatible with C++98}}
// expected-warning@-2 {{'auto' type specifier is incompatible with C++98}}
// expected-warning@-3 {{initialization of initializer_list object is incompatible with C++98}}
2013-01-26 08:39:02 +08:00
// expected-warning@-4 {{reference initialized from initializer list is incompatible with C++98}}
2013-01-12 09:05:20 +08:00
}
2013-01-26 08:39:02 +08:00
struct Agg { int a , b ; } const & agg = { 1 , 2 } ; // expected-warning {{reference initialized from initializer list is incompatible with C++98}}
2011-10-15 13:09:34 +08:00
}
struct InClassInit {
int n = 0 ; // expected-warning {{in-class initialization of non-static data members is incompatible with C++98}}
} ;
struct OverrideControlBase {
virtual void f ( ) ;
2014-10-03 17:02:53 +08:00
virtual void g ( ) ;
2011-10-15 13:09:34 +08:00
} ;
struct OverrideControl final : OverrideControlBase { // expected-warning {{'final' keyword is incompatible with C++98}}
virtual void f ( ) override ; // expected-warning {{'override' keyword is incompatible with C++98}}
2014-10-03 17:02:53 +08:00
virtual void g ( ) final ; // expected-warning {{'final' keyword is incompatible with C++98}}
2011-10-15 13:09:34 +08:00
} ;
using AliasDecl = int ; // expected-warning {{alias declarations are incompatible with C++98}}
template < typename T > using AliasTemplate = T ; // expected-warning {{alias declarations are incompatible with C++98}}
2011-10-19 04:49:44 +08:00
inline namespace InlineNS { // expected-warning {{inline namespaces are incompatible with C++98}}
2011-10-15 13:09:34 +08:00
}
2011-10-15 13:42:01 +08:00
auto auto_deduction = 0 ; // expected-warning {{'auto' type specifier is incompatible with C++98}}
int * p = new auto ( 0 ) ; // expected-warning {{'auto' type specifier is incompatible with C++98}}
2011-10-18 07:06:20 +08:00
const int align_of = alignof ( int ) ; // expected-warning {{alignof expressions are incompatible with C++98}}
char16_t c16 = 0 ; // expected-warning {{'char16_t' type specifier is incompatible with C++98}}
char32_t c32 = 0 ; // expected-warning {{'char32_t' type specifier is incompatible with C++98}}
constexpr int const_expr = 0 ; // expected-warning {{'constexpr' specifier is incompatible with C++98}}
decltype ( const_expr ) decl_type = 0 ; // expected-warning {{'decltype' type specifier is incompatible with C++98}}
2012-02-25 02:10:23 +08:00
__decltype ( const_expr ) decl_type2 = 0 ; // ok
2011-10-18 07:06:20 +08:00
void no_except ( ) noexcept ; // expected-warning {{noexcept specifications are incompatible with C++98}}
bool no_except_expr = noexcept ( 1 + 1 ) ; // expected-warning {{noexcept expressions are incompatible with C++98}}
void * null = nullptr ; // expected-warning {{'nullptr' is incompatible with C++98}}
static_assert ( true , " ! " ) ; // expected-warning {{static_assert declarations are incompatible with C++98}}
2011-10-19 04:49:44 +08:00
struct InhCtorBase {
InhCtorBase ( int ) ;
} ;
struct InhCtorDerived : InhCtorBase {
2013-07-21 03:22:08 +08:00
using InhCtorBase : : InhCtorBase ; // expected-warning {{inheriting constructors are incompatible with C++98}}
2011-10-19 04:49:44 +08:00
} ;
struct FriendMember {
static void MemberFn ( ) ;
friend void FriendMember : : MemberFn ( ) ; // expected-warning {{friend declaration naming a member of the declaring class is incompatible with C++98}}
} ;
struct DelegCtor {
DelegCtor ( int ) : DelegCtor ( ) { } // expected-warning {{delegating constructors are incompatible with C++98}}
DelegCtor ( ) ;
} ;
template < int n = 0 > void DefaultFuncTemplateArg ( ) ; // expected-warning {{default template arguments for a function template are incompatible with C++98}}
template < typename T > int TemplateFn ( T ) { return 0 ; }
void LocalTemplateArg ( ) {
struct S { } ;
TemplateFn ( S ( ) ) ; // expected-warning {{local type 'S' as template argument is incompatible with C++98}}
}
struct { } obj_of_unnamed_type ; // expected-note {{here}}
int UnnamedTemplateArg = TemplateFn ( obj_of_unnamed_type ) ; // expected-warning {{unnamed type as template argument is incompatible with C++98}}
namespace RedundantParensInAddressTemplateParam {
int n ;
template < int * p > struct S { } ;
S < ( & n ) > s ; // expected-warning {{redundant parentheses surrounding address non-type template argument are incompatible with C++98}}
S < ( ( ( & n ) ) ) > t ; // expected-warning {{redundant parentheses surrounding address non-type template argument are incompatible with C++98}}
}
namespace TemplateSpecOutOfScopeNs {
2018-03-16 21:36:56 +08:00
template < typename T > struct S { } ;
2011-10-19 04:49:44 +08:00
}
2018-03-16 21:36:56 +08:00
template < > struct TemplateSpecOutOfScopeNs : : S < char > { } ;
2011-10-19 04:49:44 +08:00
struct Typename {
template < typename T > struct Inner { } ;
} ;
typename : : Typename TypenameOutsideTemplate ( ) ; // expected-warning {{use of 'typename' outside of a template is incompatible with C++98}}
Typename : : template Inner < int > TemplateOutsideTemplate ( ) ; // expected-warning {{use of 'template' keyword outside of a template is incompatible with C++98}}
struct TrivialButNonPOD {
int f ( int ) ;
private :
int k ;
} ;
void Ellipsis ( int n , . . . ) ;
void TrivialButNonPODThroughEllipsis ( ) {
Ellipsis ( 1 , TrivialButNonPOD ( ) ) ; // expected-warning {{passing object of trivial but non-POD type 'TrivialButNonPOD' through variadic function is incompatible with C++98}}
}
struct HasExplicitConversion {
explicit operator bool ( ) ; // expected-warning {{explicit conversion functions are incompatible with C++98}}
} ;
2011-10-19 05:39:00 +08:00
struct Struct { } ;
enum Enum { enum_val = 0 } ;
struct BadFriends {
friend enum : : Enum ; // expected-warning {{befriending enumeration type 'enum ::Enum' is incompatible with C++98}}
friend int ; // expected-warning {{non-class friend type 'int' is incompatible with C++98}}
friend Struct ; // expected-warning {{befriending 'Struct' without 'struct' keyword is incompatible with C++98}}
} ;
int n = { } ; // expected-warning {{scalar initialized from empty initializer list is incompatible with C++98}}
2011-10-19 08:07:01 +08:00
class PrivateMember {
struct ImPrivate { } ;
} ;
2014-01-11 10:37:12 +08:00
template < typename T > typename T : : ImPrivate SFINAEAccessControl ( T t ) { // expected-warning {{substitution failure due to access control is incompatible with C++98}}
2011-10-19 08:07:01 +08:00
return typename T : : ImPrivate ( ) ;
}
int SFINAEAccessControl ( . . . ) { return 0 ; }
2014-01-11 10:37:12 +08:00
int CheckSFINAEAccessControl = SFINAEAccessControl ( PrivateMember ( ) ) ; // expected-note {{while substituting deduced template arguments into function template 'SFINAEAccessControl' [with T = PrivateMember]}}
2011-10-19 08:54:10 +08:00
2011-10-20 04:41:51 +08:00
namespace UnionOrAnonStructMembers {
struct NonTrivCtor {
2012-12-08 10:53:02 +08:00
NonTrivCtor ( ) ; // expected-note 2{{user-provided default constructor}}
2011-10-20 04:41:51 +08:00
} ;
struct NonTrivCopy {
2012-12-08 10:53:02 +08:00
NonTrivCopy ( const NonTrivCopy & ) ; // expected-note 2{{user-provided copy constructor}}
2011-10-20 04:41:51 +08:00
} ;
struct NonTrivDtor {
2012-12-08 10:53:02 +08:00
~ NonTrivDtor ( ) ; // expected-note 2{{user-provided destructor}}
2011-10-20 04:41:51 +08:00
} ;
union BadUnion {
NonTrivCtor ntc ; // expected-warning {{union member 'ntc' with a non-trivial constructor is incompatible with C++98}}
NonTrivCopy ntcp ; // expected-warning {{union member 'ntcp' with a non-trivial copy constructor is incompatible with C++98}}
NonTrivDtor ntd ; // expected-warning {{union member 'ntd' with a non-trivial destructor is incompatible with C++98}}
} ;
struct Wrap {
struct {
NonTrivCtor ntc ; // expected-warning {{anonymous struct member 'ntc' with a non-trivial constructor is incompatible with C++98}}
NonTrivCopy ntcp ; // expected-warning {{anonymous struct member 'ntcp' with a non-trivial copy constructor is incompatible with C++98}}
NonTrivDtor ntd ; // expected-warning {{anonymous struct member 'ntd' with a non-trivial destructor is incompatible with C++98}}
} ;
} ;
2012-02-17 04:41:22 +08:00
union WithStaticDataMember {
static constexpr double d = 0.0 ; // expected-warning {{static data member 'd' in union is incompatible with C++98}} expected-warning {{'constexpr' specifier is incompatible with C++98}}
static const int n = 0 ; // expected-warning {{static data member 'n' in union is incompatible with C++98}}
static int k ; // expected-warning {{static data member 'k' in union is incompatible with C++98}}
} ;
2011-10-20 04:41:51 +08:00
}
2011-10-20 11:28:47 +08:00
int EnumNNS = Enum : : enum_val ; // expected-warning {{enumeration type in nested name specifier is incompatible with C++98}}
template < typename T > void EnumNNSFn ( ) {
int k = T : : enum_val ; // expected-warning {{enumeration type in nested name specifier is incompatible with C++98}}
} ;
template void EnumNNSFn < Enum > ( ) ; // expected-note {{in instantiation}}
2011-10-21 05:42:12 +08:00
void JumpDiagnostics ( int n ) {
2014-09-06 08:24:58 +08:00
goto DirectJump ; // expected-warning {{jump from this goto statement to its label is incompatible with C++98}}
2011-10-21 05:42:12 +08:00
TrivialButNonPOD tnp1 ; // expected-note {{jump bypasses initialization of non-POD variable}}
DirectJump :
void * Table [ ] = { & & DirectJump , & & Later } ;
2014-09-06 08:24:58 +08:00
goto * Table [ n ] ; // expected-warning {{jump from this indirect goto statement to one of its possible targets is incompatible with C++98}}
2011-10-21 05:42:12 +08:00
TrivialButNonPOD tnp2 ; // expected-note {{jump bypasses initialization of non-POD variable}}
2014-09-06 08:24:58 +08:00
Later : // expected-note {{possible target of indirect goto statement}}
2011-10-21 05:42:12 +08:00
switch ( n ) {
TrivialButNonPOD tnp3 ; // expected-note {{jump bypasses initialization of non-POD variable}}
2014-09-06 08:24:58 +08:00
default : // expected-warning {{jump from switch statement to this case label is incompatible with C++98}}
2011-10-21 05:42:12 +08:00
return ;
}
}
2012-02-25 18:20:59 +08:00
namespace UnevaluatedMemberAccess {
struct S {
int n ;
int f ( ) { return sizeof ( S : : n ) ; } // ok
} ;
int k = sizeof ( S : : n ) ; // expected-warning {{use of non-static data member 'n' in an unevaluated context is incompatible with C++98}}
const std : : type_info & ti = typeid ( S : : n ) ; // expected-warning {{use of non-static data member 'n' in an unevaluated context is incompatible with C++98}}
}
2012-03-10 06:27:51 +08:00
namespace LiteralUCNs {
char c1 = ' \ u001e ' ; // expected-warning {{universal character name referring to a control character is incompatible with C++98}}
wchar_t c2 = L ' \ u0041 ' ; // expected-warning {{specifying character 'A' with a universal character name is incompatible with C++98}}
const char * s1 = " foo \u0031 " ; // expected-warning {{specifying character '1' with a universal character name is incompatible with C++98}}
const wchar_t * s2 = L " bar \u0085 " ; // expected-warning {{universal character name referring to a control character is incompatible with C++98}}
}
2012-04-05 05:11:30 +08:00
namespace NonTypeTemplateArgs {
template < typename T , T v > struct S { } ;
const int k = 5 ; // expected-note {{here}}
static void f ( ) { } // expected-note {{here}}
S < const int & , k > s1 ; // expected-warning {{non-type template argument referring to object 'k' with internal linkage is incompatible with C++98}}
S < void ( & ) ( ) , f > s2 ; // expected-warning {{non-type template argument referring to function 'f' with internal linkage is incompatible with C++98}}
}
2012-04-26 09:51:03 +08:00
namespace NullPointerTemplateArg {
struct A { } ;
template < int * > struct X { } ;
template < int A : : * > struct Y { } ;
X < ( int * ) 0 > x ; // expected-warning {{use of null pointer as non-type template argument is incompatible with C++98}}
Y < ( int A : : * ) 0 > y ; // expected-warning {{use of null pointer as non-type template argument is incompatible with C++98}}
}
2012-07-30 23:53:26 +08:00
namespace PR13480 {
struct basic_iterator {
2012-12-08 10:53:02 +08:00
basic_iterator ( const basic_iterator & it ) { } // expected-note {{because type 'PR13480::basic_iterator' has a user-provided copy constructor}}
basic_iterator ( basic_iterator & it ) { }
2012-07-30 23:53:26 +08:00
} ;
union test {
basic_iterator it ; // expected-warning {{union member 'it' with a non-trivial copy constructor is incompatible with C++98}}
} ;
}
2012-07-31 00:41:40 +08:00
namespace AssignOpUnion {
struct a {
2012-12-08 10:53:02 +08:00
void operator = ( const a & it ) { } // expected-note {{because type 'AssignOpUnion::a' has a user-provided copy assignment operator}}
void operator = ( a & it ) { }
2012-07-31 00:41:40 +08:00
} ;
struct b {
2012-12-08 10:53:02 +08:00
void operator = ( const b & it ) { } // expected-note {{because type 'AssignOpUnion::b' has a user-provided copy assignment operator}}
2012-07-31 00:41:40 +08:00
} ;
union test1 {
a x ; // expected-warning {{union member 'x' with a non-trivial copy assignment operator is incompatible with C++98}}
b y ; // expected-warning {{union member 'y' with a non-trivial copy assignment operator is incompatible with C++98}}
} ;
}
2012-08-31 05:47:37 +08:00
namespace rdar11736429 {
2012-12-08 10:53:02 +08:00
struct X { // expected-note {{because type 'rdar11736429::X' has no default constructor}}
2012-08-31 05:47:37 +08:00
X ( const X & ) = delete ; / / expected - warning { { deleted function definitions are incompatible with C + + 98 } } \
2012-12-08 10:53:02 +08:00
// expected-note {{implicit default constructor suppressed by user-declared constructor}}
2012-08-31 05:47:37 +08:00
} ;
union S {
X x ; // expected-warning{{union member 'x' with a non-trivial constructor is incompatible with C++98}}
} ;
}
2013-08-06 09:03:05 +08:00
template < typename T > T var = T ( 10 ) ;
2014-08-19 23:55:55 +08:00
# ifdef CXX14COMPAT
// expected-warning@-2 {{variable templates are incompatible with C++ standards before C++14}}
2013-08-06 09:03:05 +08:00
# else
2014-08-19 23:55:55 +08:00
// expected-warning@-4 {{variable templates are a C++14 extension}}
2013-08-06 09:03:05 +08:00
# endif
2014-04-17 10:56:49 +08:00
// No diagnostic for specializations of variable templates; we will have
// diagnosed the primary template.
2013-08-06 09:03:05 +08:00
template < typename T > T * var < T * > = new T ( ) ;
template < > int var < int > = 10 ;
2016-09-01 07:23:25 +08:00
template char var < char > ;
2013-08-06 09:03:05 +08:00
float fvar = var < float > ;
2014-04-17 10:56:49 +08:00
class A {
2013-08-06 09:03:05 +08:00
template < typename T > static T var = T ( 10 ) ;
2014-08-19 23:55:55 +08:00
# ifdef CXX14COMPAT
// expected-warning@-2 {{variable templates are incompatible with C++ standards before C++14}}
2013-08-06 09:03:05 +08:00
# else
2014-08-19 23:55:55 +08:00
// expected-warning@-4 {{variable templates are a C++14 extension}}
2013-08-06 09:03:05 +08:00
# endif
2014-08-19 23:55:55 +08:00
template < typename T > static T * var < T * > = new T ( ) ;
2013-08-06 09:03:05 +08:00
} ;
struct B { template < typename T > static T v ; } ;
2014-08-19 23:55:55 +08:00
# ifdef CXX14COMPAT
// expected-warning@-2 {{variable templates are incompatible with C++ standards before C++14}}
2013-08-06 09:03:05 +08:00
# else
2014-08-19 23:55:55 +08:00
// expected-warning@-4 {{variable templates are a C++14 extension}}
2013-08-06 09:03:05 +08:00
# endif
template < typename T > T B : : v = T ( ) ;
2014-08-19 23:55:55 +08:00
# ifdef CXX14COMPAT
// expected-warning@-2 {{variable templates are incompatible with C++ standards before C++14}}
2013-08-06 09:03:05 +08:00
# else
2014-08-19 23:55:55 +08:00
// expected-warning@-4 {{variable templates are a C++14 extension}}
2013-08-06 09:03:05 +08:00
# endif
template < typename T > T * B : : v < T * > = new T ( ) ;
template < > int B : : v < int > = 10 ;
2016-09-01 07:23:25 +08:00
template char B : : v < char > ;
2013-08-06 09:03:05 +08:00
float fsvar = B : : v < float > ;
2014-08-19 23:55:55 +08:00
# ifdef CXX14COMPAT
int digit_seps = 123'456 ; // expected-warning {{digit separators are incompatible with C++ standards before C++14}}
2013-09-26 11:33:06 +08:00
# endif