<p dir="ltr">This patch does indeed make us recover as if the fixit was applied. That's actually the main point of this patch, since we need the recovery in ms mode. (See the "addzeroinitialization" call.)</p>
<div class="gmail_quote">On Apr 17, 2015 8:57 AM, "David Blaikie" <<a href="mailto:dblaikie@gmail.com">dblaikie@gmail.com</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Fri, Apr 17, 2015 at 1:32 AM, Nico Weber <<a href="mailto:nicolasweber@gmx.de">nicolasweber@gmx.de</a>> wrote:<br>
> Author: nico<br>
> Date: Fri Apr 17 03:32:38 2015<br>
> New Revision: 235166<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=235166&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=235166&view=rev</a><br>
> Log:<br>
> Move fixit for const init from note to diag, weaken to warning in MS mode.<br>
<br>
There's a general rule that we don't put fixits on warnings because in<br>
-fix-it mode we need to recover exactly as if the fixit were applied<br>
(& since it's only a warning we can't change the recovery path to do<br>
something different based on the fact that the warning occurred). I'm<br>
not sure if there are exceptions to this rule.<br>
<br>
 - David<br>
<br>
><br>
> r235046 turned "extern __declspec(selectany) int a;" from a declaration into<br>
> a definition to fix PR23242 (required for compatibility with mc.exe output).<br>
> However, this broke parsing Windows headers: A  d3d11 headers contain something<br>
> like<br>
><br>
>   struct SomeStruct {};<br>
>   extern const __declspec(selectany) SomeStruct some_struct;<br>
><br>
> This is now a definition, and const objects either need an explicit default<br>
> ctor or an initializer so this errors out with<br>
><br>
>   d3d11.h(1065,48) :<br>
>     error: default initialization of an object of const type<br>
>            'const CD3D11_DEFAULT' without a user-provided default constructor<br>
><br>
> (cl.exe just doesn't implement this rule, independent of selectany.)<br>
><br>
> To work around this, weaken this error into a warning for selectany decls<br>
> in microsoft mode, and recover with zero-initialization.<br>
><br>
> Doing this is a bit hairy since it adds a fixit on an error emitted<br>
> by InitializationSequence – this means it needs to build a correct AST, which<br>
> in turn means InitializationSequence::Failed() cannot return true when this<br>
> fixit is applied. As a workaround, the patch adds a fixit member to<br>
> InitializationSequence, and InitializationSequence::Perform() prints the<br>
> diagnostic if the fixit member is set right after its call to Diagnose.<br>
> That function is usually called when InitializationSequences are used –<br>
> InitListChecker::PerformEmptyInit() doesn't call it, but the InitListChecker<br>
> case never performs default-initialization, so this is technically OK.<br>
><br>
> This is the alternative, original fix for PR20208 that got reviewed in the<br>
> thread "[patch] Improve diagnostic on default-initializing const variables<br>
> (PR20208)".  This change basically reverts r213725, adds the original fix for<br>
> PR20208, and makes the error a warning in Microsoft mode.<br>
><br>
> Modified:<br>
>     cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
>     cfe/trunk/include/clang/Sema/Initialization.h<br>
>     cfe/trunk/lib/Sema/SemaInit.cpp<br>
>     cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp<br>
>     cfe/trunk/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp<br>
>     cfe/trunk/test/CXX/dcl.decl/dcl.init/p6.cpp<br>
>     cfe/trunk/test/CXX/drs/dr0xx.cpp<br>
>     cfe/trunk/test/CXX/drs/dr4xx.cpp<br>
>     cfe/trunk/test/FixIt/fixit.cpp<br>
>     cfe/trunk/test/SemaCXX/attr-selectany.cpp<br>
>     cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp<br>
>     cfe/trunk/test/SemaCXX/constexpr-value-init.cpp<br>
>     cfe/trunk/test/SemaCXX/cxx0x-cursory-default-delete.cpp<br>
>     cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp<br>
><br>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=235166&r1=235165&r2=235166&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=235166&r1=235165&r2=235166&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)<br>
> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Apr 17 03:32:38 2015<br>
> @@ -5470,8 +5470,11 @@ def err_address_space_qualified_delete :<br>
>  def err_default_init_const : Error<<br>
>    "default initialization of an object of const type %0"<br>
>    "%select{| without a user-provided default constructor}1">;<br>
> -def note_add_initializer : Note<<br>
> -  "add an explicit initializer to initialize %0">;<br>
> +def ext_default_init_const : ExtWarn<<br>
> +  "default initialization of an object of const type %0"<br>
> +  "%select{| without a user-provided default constructor}1 "<br>
> +  "is a Microsoft extension">,<br>
> +  InGroup<Microsoft>;<br>
>  def err_delete_operand : Error<"cannot delete expression of type %0">;<br>
>  def ext_delete_void_ptr_operand : ExtWarn<<br>
>    "cannot delete expression with pointer-to-'void' type %0">,<br>
><br>
> Modified: cfe/trunk/include/clang/Sema/Initialization.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Initialization.h?rev=235166&r1=235165&r2=235166&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Initialization.h?rev=235166&r1=235165&r2=235166&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/include/clang/Sema/Initialization.h (original)<br>
> +++ cfe/trunk/include/clang/Sema/Initialization.h Fri Apr 17 03:32:38 2015<br>
> @@ -844,6 +844,21 @@ private:<br>
><br>
>    /// \brief The incomplete type that caused a failure.<br>
>    QualType FailedIncompleteType;<br>
> +<br>
> +  /// \brief The fixit that needs to be applied to make this initialization<br>
> +  /// succeed.<br>
> +  std::string ZeroInitializationFixit;<br>
> +  SourceLocation ZeroInitializationFixitLoc;<br>
> +<br>
> +public:<br>
> +  /// \brief Call for initializations are invalid but that would be valid<br>
> +  /// zero initialzations if Fixit was applied.<br>
> +  void SetZeroInitializationFixit(const std::string& Fixit, SourceLocation L) {<br>
> +    ZeroInitializationFixit = Fixit;<br>
> +    ZeroInitializationFixitLoc = L;<br>
> +  }<br>
> +<br>
> +private:<br>
><br>
>    /// \brief Prints a follow-up note that highlights the location of<br>
>    /// the initialized entity, if it's remote.<br>
><br>
> Modified: cfe/trunk/lib/Sema/SemaInit.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=235166&r1=235165&r2=235166&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=235166&r1=235165&r2=235166&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/lib/Sema/SemaInit.cpp (original)<br>
> +++ cfe/trunk/lib/Sema/SemaInit.cpp Fri Apr 17 03:32:38 2015<br>
> @@ -3101,6 +3101,28 @@ void InitializationSequence::SetOverload<br>
>  // Attempt initialization<br>
>  //===----------------------------------------------------------------------===//<br>
><br>
> +/// Tries to add a zero initializer. Returns true if that worked.<br>
> +static bool<br>
> +maybeRecoverWithZeroInitialization(Sema &S, InitializationSequence &Sequence,<br>
> +                                   const InitializedEntity &Entity) {<br>
> +  if (Entity.getKind() != InitializedEntity::EK_Variable)<br>
> +    return false;<br>
> +<br>
> +  VarDecl *VD = cast<VarDecl>(Entity.getDecl());<br>
> +  if (VD->getInit() || VD->getLocEnd().isMacroID())<br>
> +    return false;<br>
> +<br>
> +  QualType VariableTy = VD->getType().getCanonicalType();<br>
> +  SourceLocation Loc = S.getLocForEndOfToken(VD->getLocEnd());<br>
> +  std::string Init = S.getFixItZeroInitializerForType(VariableTy, Loc);<br>
> +  if (!Init.empty()) {<br>
> +    Sequence.AddZeroInitializationStep(Entity.getType());<br>
> +    Sequence.SetZeroInitializationFixit(Init, Loc);<br>
> +    return true;<br>
> +  }<br>
> +  return false;<br>
> +}<br>
> +<br>
>  static void MaybeProduceObjCObject(Sema &S,<br>
>                                     InitializationSequence &Sequence,<br>
>                                     const InitializedEntity &Entity) {<br>
> @@ -3339,7 +3361,8 @@ static void TryConstructorInitialization<br>
>    if (Kind.getKind() == InitializationKind::IK_Default &&<br>
>        Entity.getType().isConstQualified() &&<br>
>        !cast<CXXConstructorDecl>(Best->Function)->isUserProvided()) {<br>
> -    Sequence.SetFailed(InitializationSequence::FK_DefaultInitOfConst);<br>
> +    if (!maybeRecoverWithZeroInitialization(S, Sequence, Entity))<br>
> +      Sequence.SetFailed(InitializationSequence::FK_DefaultInitOfConst);<br>
>      return;<br>
>    }<br>
><br>
> @@ -4231,7 +4254,8 @@ static void TryDefaultInitialization(Sem<br>
>    //   a const-qualified type T, T shall be a class type with a user-provided<br>
>    //   default constructor.<br>
>    if (DestType.isConstQualified() && S.getLangOpts().CPlusPlus) {<br>
> -    Sequence.SetFailed(InitializationSequence::FK_DefaultInitOfConst);<br>
> +    if (!maybeRecoverWithZeroInitialization(S, Sequence, Entity))<br>
> +      Sequence.SetFailed(InitializationSequence::FK_DefaultInitOfConst);<br>
>      return;<br>
>    }<br>
><br>
> @@ -5749,6 +5773,21 @@ InitializationSequence::Perform(Sema &S,<br>
>      Diagnose(S, Entity, Kind, Args);<br>
>      return ExprError();<br>
>    }<br>
> +  if (!ZeroInitializationFixit.empty()) {<br>
> +    unsigned DiagID = diag::err_default_init_const;<br>
> +    if (Decl *D = Entity.getDecl())<br>
> +      if (S.getLangOpts().MSVCCompat && D->hasAttr<SelectAnyAttr>())<br>
> +        DiagID = diag::ext_default_init_const;<br>
> +<br>
> +    // The initialization would have succeeded with this fixit. Since the fixit<br>
> +    // is on the error, we need to build a valid AST in this case, so this isn't<br>
> +    // handled in the Failed() branch above.<br>
> +    QualType DestType = Entity.getType();<br>
> +    S.Diag(Kind.getLocation(), DiagID)<br>
> +        << DestType << (bool)DestType->getAs<RecordType>()<br>
> +        << FixItHint::CreateInsertion(ZeroInitializationFixitLoc,<br>
> +                                      ZeroInitializationFixit);<br>
> +  }<br>
><br>
>    if (getKind() == DependentSequence) {<br>
>      // If the declaration is a non-dependent, incomplete array type<br>
> @@ -6549,26 +6588,6 @@ static void diagnoseListInit(Sema &S, co<br>
>           "Inconsistent init list check result.");<br>
>  }<br>
><br>
> -/// Prints a fixit for adding a null initializer for |Entity|. Call this only<br>
> -/// right after emitting a diagnostic.<br>
> -static void maybeEmitZeroInitializationFixit(Sema &S,<br>
> -                                             InitializationSequence &Sequence,<br>
> -                                             const InitializedEntity &Entity) {<br>
> -  if (Entity.getKind() != InitializedEntity::EK_Variable)<br>
> -    return;<br>
> -<br>
> -  VarDecl *VD = cast<VarDecl>(Entity.getDecl());<br>
> -  if (VD->getInit() || VD->getLocEnd().isMacroID())<br>
> -    return;<br>
> -<br>
> -  QualType VariableTy = VD->getType().getCanonicalType();<br>
> -  SourceLocation Loc = S.getLocForEndOfToken(VD->getLocEnd());<br>
> -  std::string Init = S.getFixItZeroInitializerForType(VariableTy, Loc);<br>
> -<br>
> -  S.Diag(Loc, diag::note_add_initializer)<br>
> -      << VD << FixItHint::CreateInsertion(Loc, Init);<br>
> -}<br>
> -<br>
>  bool InitializationSequence::Diagnose(Sema &S,<br>
>                                        const InitializedEntity &Entity,<br>
>                                        const InitializationKind &Kind,<br>
> @@ -6900,7 +6919,6 @@ bool InitializationSequence::Diagnose(Se<br>
>      } else {<br>
>        S.Diag(Kind.getLocation(), diag::err_default_init_const)<br>
>            << DestType << (bool)DestType->getAs<RecordType>();<br>
> -      maybeEmitZeroInitializationFixit(S, *this, Entity);<br>
>      }<br>
>      break;<br>
><br>
><br>
> Modified: cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp?rev=235166&r1=235165&r2=235166&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp?rev=235166&r1=235165&r2=235166&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp (original)<br>
> +++ cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp Fri Apr 17 03:32:38 2015<br>
> @@ -17,7 +17,7 @@ extern int (*const d)(int);<br>
><br>
>  // A variable declaration which uses the constexpr specifier shall have an<br>
>  // initializer and shall be initialized by a constant expression.<br>
> -constexpr int ni1; // expected-error {{default initialization of an object of const type 'const int'}} expected-note {{add an explicit initializer to initialize 'ni1'}}<br>
> +constexpr int ni1; // expected-error {{default initialization of an object of const type 'const int'}}<br>
>  constexpr struct C { C(); } ni2; // expected-error {{cannot have non-literal type 'const struct C'}} expected-note 3{{has no constexpr constructors}}<br>
>  constexpr double &ni3; // expected-error {{declaration of reference variable 'ni3' requires an initializer}}<br>
><br>
> @@ -34,4 +34,4 @@ struct pixel {<br>
>    int x, y;<br>
>  };<br>
>  constexpr pixel ur = { 1294, 1024 }; // ok<br>
> -constexpr pixel origin;              // expected-error {{default initialization of an object of const type 'const pixel' without a user-provided default constructor}} expected-note {{add an explicit initializer to initialize 'origin'}}<br>
> +constexpr pixel origin;              // expected-error {{default initialization of an object of const type 'const pixel' without a user-provided default constructor}}<br>
><br>
> Modified: cfe/trunk/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp?rev=235166&r1=235165&r2=235166&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp?rev=235166&r1=235165&r2=235166&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp (original)<br>
> +++ cfe/trunk/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp Fri Apr 17 03:32:38 2015<br>
> @@ -36,7 +36,7 @@ struct S3 {<br>
>  constexpr S3 s3a = S3(0);<br>
>  constexpr S3 s3b = s3a;<br>
>  constexpr S3 s3c = S3();<br>
> -constexpr S3 s3d; // expected-error {{default initialization of an object of const type 'const S3' without a user-provided default constructor}} expected-note{{add an explicit initializer to initialize 's3d'}}<br>
> +constexpr S3 s3d; // expected-error {{default initialization of an object of const type 'const S3' without a user-provided default constructor}}<br>
><br>
>  struct S4 {<br>
>    S4() = default;<br>
> @@ -119,6 +119,6 @@ namespace PR13492 {<br>
>    };<br>
><br>
>    void f() {<br>
> -    const B b; // expected-error {{default initialization of an object of const type 'const PR13492::B' without a user-provided default constructor}} expected-note {{add an explicit initializer to initialize 'b'}}<br>
> +    const B b; // expected-error {{default initialization of an object of const type 'const PR13492::B' without a user-provided default constructor}}<br>
>    }<br>
>  }<br>
><br>
> Modified: cfe/trunk/test/CXX/dcl.decl/dcl.init/p6.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.init/p6.cpp?rev=235166&r1=235165&r2=235166&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.init/p6.cpp?rev=235166&r1=235165&r2=235166&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/test/CXX/dcl.decl/dcl.init/p6.cpp (original)<br>
> +++ cfe/trunk/test/CXX/dcl.decl/dcl.init/p6.cpp Fri Apr 17 03:32:38 2015<br>
> @@ -10,15 +10,15 @@ struct NoUserDefault : public MakeNonPOD<br>
>  struct HasUserDefault { HasUserDefault(); };<br>
><br>
>  void test_const_default_init() {<br>
> -  const NoUserDefault x1; // expected-error{{default initialization of an object of const type 'const NoUserDefault' without a user-provided default constructor}} expected-note {{add an explicit initializer to initialize 'x1'}}<br>
> +  const NoUserDefault x1; // expected-error{{default initialization of an object of const type 'const NoUserDefault' without a user-provided default constructor}}<br>
>    const HasUserDefault x2;<br>
> -  const int x3; // expected-error{{default initialization of an object of const type 'const int'}} expected-note{{add an explicit initializer to initialize 'x3'}}<br>
> +  const int x3; // expected-error{{default initialization of an object of const type 'const int'}}<br>
>  }<br>
><br>
>  // rdar://8501008<br>
>  struct s0 {};<br>
>  struct s1 { static const s0 foo; };<br>
> -const struct s0 s1::foo; // expected-error{{default initialization of an object of const type 'const struct s0' without a user-provided default constructor}} expected-note {{add an explicit initializer to initialize 'foo'}}<br>
> +const struct s0 s1::foo; // expected-error{{default initialization of an object of const type 'const struct s0' without a user-provided default constructor}}<br>
><br>
>  template<typename T><br>
>  struct s2 {<br>
><br>
> Modified: cfe/trunk/test/CXX/drs/dr0xx.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr0xx.cpp?rev=235166&r1=235165&r2=235166&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr0xx.cpp?rev=235166&r1=235165&r2=235166&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/test/CXX/drs/dr0xx.cpp (original)<br>
> +++ cfe/trunk/test/CXX/drs/dr0xx.cpp Fri Apr 17 03:32:38 2015<br>
> @@ -864,7 +864,7 @@ namespace dr77 { // dr77: yes<br>
>  namespace dr78 { // dr78: sup ????<br>
>    // Under DR78, this is valid, because 'k' has static storage duration, so is<br>
>    // zero-initialized.<br>
> -  const int k; // expected-error {{default initialization of an object of const}} expected-note{{add an explicit initializer to initialize 'k'}}<br>
> +  const int k; // expected-error {{default initialization of an object of const}}<br>
>  }<br>
><br>
>  // dr79: na<br>
><br>
> Modified: cfe/trunk/test/CXX/drs/dr4xx.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr4xx.cpp?rev=235166&r1=235165&r2=235166&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr4xx.cpp?rev=235166&r1=235165&r2=235166&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/test/CXX/drs/dr4xx.cpp (original)<br>
> +++ cfe/trunk/test/CXX/drs/dr4xx.cpp Fri Apr 17 03:32:38 2015<br>
> @@ -1202,9 +1202,9 @@ namespace dr497 { // dr497: yes<br>
>      struct S {<br>
>        mutable int i;<br>
>      };<br>
> -    const S cs; // expected-error {{default initialization}} expected-note {{add an explicit initializer}}<br>
> +    const S cs; // expected-error {{default initialization}}<br>
>      int S::*pm = &S::i;<br>
> -    cs.*pm = 88;<br>
> +    cs.*pm = 88; // expected-error {{not assignable}}<br>
>    }<br>
><br>
>    void after() {<br>
><br>
> Modified: cfe/trunk/test/FixIt/fixit.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit.cpp?rev=235166&r1=235165&r2=235166&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit.cpp?rev=235166&r1=235165&r2=235166&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/test/FixIt/fixit.cpp (original)<br>
> +++ cfe/trunk/test/FixIt/fixit.cpp Fri Apr 17 03:32:38 2015<br>
> @@ -387,3 +387,11 @@ struct conversion_operator {<br>
>    // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:32}:""<br>
>    // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:44-[[@LINE-2]]:44}:" conversion_operator::* const"<br>
>  };<br>
> +<br>
> +struct const_zero_init {<br>
> +  int a;<br>
> +};<br>
> +const const_zero_init czi; // expected-error {{default initialization of an object of const type 'const const_zero_init'}}<br>
> +// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:26-[[@LINE-1]]:26}:"{}"<br>
> +int use_czi = czi.a;<br>
> +<br>
><br>
> Modified: cfe/trunk/test/SemaCXX/attr-selectany.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-selectany.cpp?rev=235166&r1=235165&r2=235166&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-selectany.cpp?rev=235166&r1=235165&r2=235166&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/test/SemaCXX/attr-selectany.cpp (original)<br>
> +++ cfe/trunk/test/SemaCXX/attr-selectany.cpp Fri Apr 17 03:32:38 2015<br>
> @@ -1,4 +1,4 @@<br>
> -// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify -std=c++11 %s<br>
> +// RUN: %clang_cc1 -fms-compatibility -fms-extensions -fsyntax-only -verify -std=c++11 %s<br>
>  // MSVC produces similar diagnostics.<br>
><br>
>  __declspec(selectany) void foo() { } // expected-error{{'selectany' can only be applied to data items with external linkage}}<br>
> @@ -34,3 +34,13 @@ __declspec(selectany) X x(1);<br>
><br>
>  namespace { class Internal {}; }<br>
>  __declspec(selectany) auto x8 = Internal(); // expected-error {{'selectany' can only be applied to data items with external linkage}}<br>
> +<br>
> +<br>
> +// The D3D11 headers do something like this.  MSVC doesn't error on this at<br>
> +// all, even without the __declspec(selectany), in violation of the standard.<br>
> +// We fall back to a warning for selectany to accept headers.<br>
> +struct SomeStruct {};<br>
> +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}}<br>
> +<br>
> +// Without selectany, this should stay an error.<br>
> +const SomeStruct some_struct2; // expected-error {{default initialization of an object of const type 'const SomeStruct' without a user-provided default constructor}}<br>
><br>
> Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp?rev=235166&r1=235165&r2=235166&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp?rev=235166&r1=235165&r2=235166&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original)<br>
> +++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Fri Apr 17 03:32:38 2015<br>
> @@ -1179,7 +1179,7 @@ namespace ExternConstexpr {<br>
>    void f() {<br>
>      extern constexpr int i; // expected-error {{constexpr variable declaration must be a definition}}<br>
>      constexpr int j = 0;<br>
> -    constexpr int k; // expected-error {{default initialization of an object of const type}} expected-note{{add an explicit initializer to initialize 'k'}}<br>
> +    constexpr int k; // expected-error {{default initialization of an object of const type}}<br>
>    }<br>
>  }<br>
><br>
><br>
> Modified: cfe/trunk/test/SemaCXX/constexpr-value-init.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constexpr-value-init.cpp?rev=235166&r1=235165&r2=235166&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constexpr-value-init.cpp?rev=235166&r1=235165&r2=235166&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/test/SemaCXX/constexpr-value-init.cpp (original)<br>
> +++ cfe/trunk/test/SemaCXX/constexpr-value-init.cpp Fri Apr 17 03:32:38 2015<br>
> @@ -14,7 +14,7 @@ void f() {<br>
>    constexpr A a; // expected-error {{constant expression}} expected-note {{in call to 'A()'}}<br>
>  }<br>
><br>
> -constexpr B b1; // expected-error {{without a user-provided default constructor}} expected-note {{add an explicit initializer to initialize 'b1'}}<br>
> +constexpr B b1; // expected-error {{without a user-provided default constructor}}<br>
>  constexpr B b2 = B(); // ok<br>
>  static_assert(b2.a.a == 1, "");<br>
>  static_assert(b2.a.b == 2, "");<br>
> @@ -23,9 +23,9 @@ struct C {<br>
>    int c;<br>
>  };<br>
>  struct D : C { int d; };<br>
> -constexpr C c1; // expected-error {{without a user-provided default constructor}} expected-note{{add an explicit initializer to initialize 'c1'}}<br>
> +constexpr C c1; // expected-error {{without a user-provided default constructor}}<br>
>  constexpr C c2 = C(); // ok<br>
> -constexpr D d1; // expected-error {{without a user-provided default constructor}} expected-note{{add an explicit initializer to initialize 'd1'}}<br>
> +constexpr D d1; // expected-error {{without a user-provided default constructor}}<br>
>  constexpr D d2 = D(); // ok with DR1452<br>
>  static_assert(D().c == 0, "");<br>
>  static_assert(D().d == 0, "");<br>
><br>
> Modified: cfe/trunk/test/SemaCXX/cxx0x-cursory-default-delete.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-cursory-default-delete.cpp?rev=235166&r1=235165&r2=235166&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-cursory-default-delete.cpp?rev=235166&r1=235165&r2=235166&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/test/SemaCXX/cxx0x-cursory-default-delete.cpp (original)<br>
> +++ cfe/trunk/test/SemaCXX/cxx0x-cursory-default-delete.cpp Fri Apr 17 03:32:38 2015<br>
> @@ -25,7 +25,7 @@ void fn1 () {<br>
>    non_const_copy ncc2 = ncc;<br>
>    ncc = ncc2;<br>
>    const non_const_copy cncc{};<br>
> -  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}} expected-note {{add an explicit initializer to initialize 'cncc1'}}<br>
> +  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}}<br>
>    non_const_copy ncc3 = cncc; // expected-error {{no matching}}<br>
>    ncc = cncc; // expected-error {{no viable overloaded}}<br>
>  };<br>
><br>
> Modified: cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp?rev=235166&r1=235165&r2=235166&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp?rev=235166&r1=235165&r2=235166&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp (original)<br>
> +++ cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp Fri Apr 17 03:32:38 2015<br>
> @@ -58,13 +58,13 @@ namespace out_of_line {<br>
>      template<typename T, typename T0> static CONST T b = T(100);<br>
>      template<typename T> static CONST T b<T,int>;<br>
>    };<br>
> -  template<typename T, typename T0> CONST T B4::a; // expected-error {{default initialization of an object of const type 'const int'}} expected-note {{add an explicit initializer to initialize 'a<int, char>'}}<br>
> +  template<typename T, typename T0> CONST T B4::a; // expected-error {{default initialization of an object of const type 'const int'}}<br>
>    template<typename T> CONST T B4::a<T,int>;<br>
>    template CONST int B4::a<int,char>; // expected-note {{in instantiation of}}<br>
>    template CONST int B4::a<int,int>;<br>
><br>
>    template<typename T, typename T0> CONST T B4::b;<br>
> -  template<typename T> CONST T B4::b<T,int>; // expected-error {{default initialization of an object of const type 'const int'}} expected-note {{add an explicit initializer to initialize 'b<int, int>'}}<br>
> +  template<typename T> CONST T B4::b<T,int>; // expected-error {{default initialization of an object of const type 'const int'}}<br>
>    template CONST int B4::b<int,char>;<br>
>    template CONST int B4::b<int,int>; // expected-note {{in instantiation of}}<br>
>  }<br>
><br>
><br>
><br>
> _______________________________________________<br>
> cfe-commits mailing list<br>
> <a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div>