2011-10-14 06:29:44 +08:00
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
2011-05-18 04:44:43 +08:00
struct non_copiable {
non_copiable ( const non_copiable & ) = delete ; // expected-note {{marked deleted here}}
non_copiable & operator = ( const non_copiable & ) = delete ; // expected-note {{explicitly deleted}}
non_copiable ( ) = default ;
} ;
struct non_const_copy {
2012-05-15 12:39:51 +08:00
non_const_copy ( non_const_copy & ) ;
non_const_copy & operator = ( non_const_copy & ) & ;
non_const_copy & operator = ( non_const_copy & ) & & ;
2011-05-18 04:44:43 +08:00
non_const_copy ( ) = default ; // expected-note {{not viable}}
2016-02-19 09:52:46 +08:00
int uninit_field ;
2011-05-18 04:44:43 +08:00
} ;
2012-05-15 12:39:51 +08:00
non_const_copy : : non_const_copy ( non_const_copy & ) = default ; // expected-note {{not viable}}
non_const_copy & non_const_copy : : operator = ( non_const_copy & ) & = default ; // expected-note {{not viable}}
non_const_copy & non_const_copy : : operator = ( non_const_copy & ) & & = default ; // expected-note {{not viable}}
2011-05-18 04:44:43 +08:00
void fn1 ( ) {
non_copiable nc ;
non_copiable nc2 = nc ; // expected-error {{deleted constructor}}
nc = nc ; // expected-error {{deleted operator}}
non_const_copy ncc ;
non_const_copy ncc2 = ncc ;
ncc = ncc2 ;
2012-08-01 06:40:31 +08:00
const non_const_copy cncc { } ;
Move fixit for const init from note to diag, weaken to warning in MS mode.
r235046 turned "extern __declspec(selectany) int a;" from a declaration into
a definition to fix PR23242 (required for compatibility with mc.exe output).
However, this broke parsing Windows headers: A d3d11 headers contain something
like
struct SomeStruct {};
extern const __declspec(selectany) SomeStruct some_struct;
This is now a definition, and const objects either need an explicit default
ctor or an initializer so this errors out with
d3d11.h(1065,48) :
error: default initialization of an object of const type
'const CD3D11_DEFAULT' without a user-provided default constructor
(cl.exe just doesn't implement this rule, independent of selectany.)
To work around this, weaken this error into a warning for selectany decls
in microsoft mode, and recover with zero-initialization.
Doing this is a bit hairy since it adds a fixit on an error emitted
by InitializationSequence – this means it needs to build a correct AST, which
in turn means InitializationSequence::Failed() cannot return true when this
fixit is applied. As a workaround, the patch adds a fixit member to
InitializationSequence, and InitializationSequence::Perform() prints the
diagnostic if the fixit member is set right after its call to Diagnose.
That function is usually called when InitializationSequences are used –
InitListChecker::PerformEmptyInit() doesn't call it, but the InitListChecker
case never performs default-initialization, so this is technically OK.
This is the alternative, original fix for PR20208 that got reviewed in the
thread "[patch] Improve diagnostic on default-initializing const variables
(PR20208)". This change basically reverts r213725, adds the original fix for
PR20208, and makes the error a warning in Microsoft mode.
llvm-svn: 235166
2015-04-17 16:32:38 +08:00
const non_const_copy cncc1 ; // expected-error {{default initialization of an object of const type 'const non_const_copy' without a user-provided default constructor}}
2011-05-18 04:44:43 +08:00
non_const_copy ncc3 = cncc ; // expected-error {{no matching}}
ncc = cncc ; // expected-error {{no viable overloaded}}
} ;
2016-02-19 09:52:46 +08:00
struct no_fields { } ;
struct all_init {
int a = 0 ;
int b = 0 ;
} ;
struct some_init {
int a = 0 ;
int b ;
int c = 0 ;
} ;
struct some_init_mutable {
int a = 0 ;
mutable int b ;
int c = 0 ;
} ;
struct some_init_def {
some_init_def ( ) = default ;
int a = 0 ;
int b ;
int c = 0 ;
} ;
struct some_init_ctor {
some_init_ctor ( ) ;
int a = 0 ;
int b ;
int c = 0 ;
} ;
struct sub_some_init : public some_init_def { } ;
struct sub_some_init_ctor : public some_init_def {
sub_some_init_ctor ( ) ;
} ;
struct sub_some_init_ctor2 : public some_init_ctor {
} ;
struct some_init_container {
some_init_def sid ;
} ;
struct some_init_container_ctor {
some_init_container_ctor ( ) ;
some_init_def sid ;
} ;
struct no_fields_container {
no_fields nf ;
} ;
2016-02-25 04:58:14 +08:00
struct param_pack_ctor {
template < typename . . . T >
param_pack_ctor ( T . . . ) ;
int n ;
} ;
struct param_pack_ctor_field {
param_pack_ctor ndc ;
} ;
struct multi_param_pack_ctor {
template < typename . . . T , typename . . . U >
multi_param_pack_ctor ( T . . . , U . . . , int f = 0 ) ;
int n ;
} ;
struct ignored_template_ctor_and_def {
template < class T > ignored_template_ctor_and_def ( T * f = nullptr ) ;
ignored_template_ctor_and_def ( ) = default ;
int field ;
} ;
template < bool , typename = void > struct enable_if { } ;
template < typename T > struct enable_if < true , T > { typedef T type ; } ;
struct multi_param_pack_and_defaulted {
template < typename . . . T ,
typename enable_if < sizeof . . . ( T ) ! = 0 > : : type * = nullptr >
multi_param_pack_and_defaulted ( T . . . ) ;
multi_param_pack_and_defaulted ( ) = default ;
int n ;
} ;
2016-02-19 09:52:46 +08:00
void constobjs ( ) {
const no_fields nf ; // ok
const all_init ai ; // ok
const some_init si ; // expected-error {{default initialization of an object of const type 'const some_init' without a user-provided default constructor}}
const some_init_mutable sim ; // ok
const some_init_def sid ; // expected-error {{default initialization of an object of const type 'const some_init_def' without a user-provided default constructor}}
const some_init_ctor sic ; // ok
const sub_some_init ssi ; // expected-error {{default initialization of an object of const type 'const sub_some_init' without a user-provided default constructor}}
const sub_some_init_ctor ssic ; // ok
const sub_some_init_ctor2 ssic2 ; // ok
const some_init_container sicon ; // expected-error {{default initialization of an object of const type 'const some_init_container' without a user-provided default constructor}}
const some_init_container_ctor siconc ; // ok
const no_fields_container nfc ; // ok
2016-02-25 04:58:14 +08:00
const param_pack_ctor ppc ; // ok
const param_pack_ctor_field ppcf ; // ok
const multi_param_pack_ctor mppc ; // ok
const multi_param_pack_and_defaulted mppad ; // expected-error {{default initialization of an object of const type 'const multi_param_pack_and_defaulted' without a user-provided default constructor}}
const ignored_template_ctor_and_def itcad ; // expected-error {{default initialization of an object of const type 'const ignored_template_ctor_and_def' without a user-provided default constructor}}
2016-02-19 09:52:46 +08:00
}
2011-05-18 04:44:43 +08:00
struct non_const_derived : non_const_copy {
non_const_derived ( const non_const_derived & ) = default ; // expected-error {{requires it to be non-const}}
non_const_derived & operator = ( non_const_derived & ) = default ;
} ;
struct bad_decls {
2012-12-08 10:53:02 +08:00
bad_decls ( volatile bad_decls & ) = default ; // expected-error {{may not be volatile}}
2012-05-15 12:39:51 +08:00
bad_decls & & operator = ( bad_decls ) = default ; // expected-error {{lvalue reference}} expected-error {{must return 'bad_decls &'}}
2012-12-08 10:53:02 +08:00
bad_decls & operator = ( volatile bad_decls & ) = default ; // expected-error {{may not be volatile}}
2011-09-30 08:45:47 +08:00
bad_decls & operator = ( const bad_decls & ) const = default ; // expected-error {{may not have 'const', 'constexpr' or 'volatile' qualifiers}}
2011-05-18 04:44:43 +08:00
} ;
2015-01-17 12:14:31 +08:00
struct DefaultDelete {
DefaultDelete ( ) = default ; // expected-note {{previous declaration is here}}
DefaultDelete ( ) = delete ; // expected-error {{constructor cannot be redeclared}}
2015-01-17 12:27:09 +08:00
~ DefaultDelete ( ) = default ; // expected-note {{previous declaration is here}}
~ DefaultDelete ( ) = delete ; // expected-error {{destructor cannot be redeclared}}
DefaultDelete & operator = ( const DefaultDelete & ) = default ; // expected-note {{previous declaration is here}}
DefaultDelete & operator = ( const DefaultDelete & ) = delete ; // expected-error {{class member cannot be redeclared}}
2015-01-17 12:14:31 +08:00
} ;
struct DeleteDefault {
DeleteDefault ( ) = delete ; // expected-note {{previous definition is here}}
DeleteDefault ( ) = default ; // expected-error {{constructor cannot be redeclared}}
2015-01-17 12:27:09 +08:00
~ DeleteDefault ( ) = delete ; // expected-note {{previous definition is here}}
~ DeleteDefault ( ) = default ; // expected-error {{destructor cannot be redeclared}}
DeleteDefault & operator = ( const DeleteDefault & ) = delete ; // expected-note {{previous definition is here}}
DeleteDefault & operator = ( const DeleteDefault & ) = default ; // expected-error {{class member cannot be redeclared}}
2015-01-17 12:14:31 +08:00
} ;
2011-05-18 04:44:43 +08:00
struct A { } ; struct B { } ;
struct except_spec_a {
virtual ~ except_spec_a ( ) throw ( A ) ;
except_spec_a ( ) throw ( A ) ;
} ;
struct except_spec_b {
virtual ~ except_spec_b ( ) throw ( B ) ;
except_spec_b ( ) throw ( B ) ;
} ;
struct except_spec_d_good : except_spec_a , except_spec_b {
~ except_spec_d_good ( ) ;
} ;
except_spec_d_good : : ~ except_spec_d_good ( ) = default ;
2012-12-08 10:53:02 +08:00
struct except_spec_d_good2 : except_spec_a , except_spec_b {
~ except_spec_d_good2 ( ) = default ;
} ;
2011-05-18 04:44:43 +08:00
struct except_spec_d_bad : except_spec_a , except_spec_b {
2012-12-08 10:53:02 +08:00
~ except_spec_d_bad ( ) noexcept ;
2011-05-18 04:44:43 +08:00
} ;
2012-12-08 10:53:02 +08:00
// FIXME: This should error because this exception spec is not
// compatible with the implicit exception spec.
except_spec_d_bad : : ~ except_spec_d_bad ( ) noexcept = default ;
2011-05-18 04:44:43 +08:00
2012-12-08 10:53:02 +08:00
// FIXME: This should error because this exception spec is not
// compatible with the implicit exception spec.
2011-05-18 04:44:43 +08:00
struct except_spec_d_mismatch : except_spec_a , except_spec_b {
except_spec_d_mismatch ( ) throw ( A ) = default ;
} ;
struct except_spec_d_match : except_spec_a , except_spec_b {
except_spec_d_match ( ) throw ( A , B ) = default ;
2012-08-01 06:40:31 +08:00
} ;
2012-02-17 00:50:43 +08:00
// gcc-compatibility: allow attributes on default definitions
// (but not normal definitions)
struct S { S ( ) ; } ;
S : : S ( ) __attribute ( ( pure ) ) = default ;
2014-02-04 09:14:30 +08:00
using size_t = decltype ( sizeof ( 0 ) ) ;
void * operator new ( size_t ) = delete ; // expected-error {{deleted definition must be first declaration}} expected-note {{implicit}}
2014-02-08 06:51:16 +08:00
void operator delete ( void * ) noexcept = delete ; // expected-error {{deleted definition must be first declaration}} expected-note {{implicit}}