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
// RUN: %clang_cc1 -fms-compatibility -fms-extensions -fsyntax-only -verify -std=c++11 %s
2013-05-20 22:02:37 +08:00
// MSVC produces similar diagnostics.
__declspec ( selectany ) void foo ( ) { } // expected-error{{'selectany' can only be applied to data items with external linkage}}
__declspec ( selectany ) int x1 = 1 ;
const __declspec ( selectany ) int x2 = 2 ; // expected-error{{'selectany' can only be applied to data items with external linkage}}
extern const __declspec ( selectany ) int x3 = 3 ;
extern const int x4 ;
const __declspec ( selectany ) int x4 = 4 ;
// MSDN says this is incorrect, but MSVC doesn't diagnose it.
extern __declspec ( selectany ) int x5 ;
static __declspec ( selectany ) int x6 = 2 ; // expected-error{{'selectany' can only be applied to data items with external linkage}}
// FIXME: MSVC accepts this and makes x7 externally visible and comdat, but keep
// it as internal and not weak/linkonce.
static int x7 ; // expected-note{{previous definition}}
extern __declspec ( selectany ) int x7 ; // expected-warning{{attribute declaration must precede definition}}
int asdf ( ) { return x7 ; }
class X {
public :
X ( int i ) { i + + ; } ;
int i ;
} ;
__declspec ( selectany ) X x ( 1 ) ;
2014-01-22 07:54:36 +08:00
namespace { class Internal { } ; }
__declspec ( selectany ) auto x8 = Internal ( ) ; // expected-error {{'selectany' can only be applied to data items with external linkage}}
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
// The D3D11 headers do something like this. MSVC doesn't error on this at
// all, even without the __declspec(selectany), in violation of the standard.
// We fall back to a warning for selectany to accept headers.
struct SomeStruct { } ;
extern const __declspec ( selectany ) SomeStruct some_struct ; // expected-warning {{default initialization of an object of const type 'const SomeStruct' without a user-provided default constructor is a Microsoft extension}}
// Without selectany, this should stay an error.
const SomeStruct some_struct2 ; // expected-error {{default initialization of an object of const type 'const SomeStruct' without a user-provided default constructor}}