<div dir="ltr">We're getting a few "error: mixture of designated and non-designated initializers in the same initializer list is a C99 extension [-Werror,-Wc99-designator]" after this. It looks like that's working as intended and we can either fix or start passing -Wno-c99-designator, but I'm wondering: We don't pass -pedantic; don't we usually put these kinds of warnings as Extension<>s instead of ExtWarn<>s?</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Aug 30, 2019 at 6:51 PM Richard Smith via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Author: rsmith<br>
Date: Fri Aug 30 15:52:55 2019<br>
New Revision: 370544<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=370544&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=370544&view=rev</a><br>
Log:<br>
[c++20] Implement semantic restrictions for C++20 designated<br>
initializers.<br>
<br>
This has some interesting interactions with our existing extensions to<br>
support C99 designated initializers as an extension in C++. Those are<br>
resolved as follows:<br>
<br>
 * We continue to permit the full breadth of C99 designated initializers<br>
   in C++, with the exception that we disallow a partial overwrite of an<br>
   initializer with a non-trivially-destructible type. (Full overwrite<br>
   is OK, because we won't run the first initializer at all.)<br>
<br>
 * The C99 extensions are disallowed in SFINAE contexts and during<br>
   overload resolution, where they could change the meaning of valid<br>
   programs.<br>
<br>
 * C++20 disallows reordering of initializers. We only check for that for<br>
   the simple cases that the C++20 rules permit (designators of the form<br>
   '.field_name =' and continue to allow reordering in other cases).<br>
   It would be nice to improve this behavior in future.<br>
<br>
 * All C99 designated initializer extensions produce a warning by<br>
   default in C++20 mode. People are going to learn the C++ rules based<br>
   on what Clang diagnoses, so it's important we diagnose these properly<br>
   by default.<br>
<br>
 * In C++ <= 17, we apply the C++20 rules rather than the C99 rules, and<br>
   so still diagnose C99 extensions as described above. We continue to<br>
   accept designated C++20-compatible initializers in C++ <= 17 silently<br>
   by default (but naturally still reject under -pedantic-errors).<br>
<br>
This is not a complete implementation of P0329R4. In particular, that<br>
paper introduces new non-C99-compatible syntax { .field { init } }, and<br>
we do not support that yet.<br>
<br>
This is based on a previous patch by Don Hinton, though I've made<br>
substantial changes when addressing the above interactions.<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D59754" rel="noreferrer" target="_blank">https://reviews.llvm.org/D59754</a><br>
<br>
Modified:<br>
    cfe/trunk/include/clang/Basic/DiagnosticGroups.td<br>
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
    cfe/trunk/include/clang/Sema/Sema.h<br>
    cfe/trunk/lib/Sema/SemaExpr.cpp<br>
    cfe/trunk/lib/Sema/SemaInit.cpp<br>
    cfe/trunk/lib/Sema/SemaOverload.cpp<br>
    cfe/trunk/lib/Sema/TreeTransform.h<br>
    cfe/trunk/test/Analysis/globals.cpp<br>
    cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp<br>
    cfe/trunk/test/CodeGenObjCXX/<a href="http://designated-initializers.mm" rel="noreferrer" target="_blank">designated-initializers.mm</a><br>
    cfe/trunk/test/PCH/cxx1y-default-initializer.cpp<br>
    cfe/trunk/test/Parser/cxx0x-lambda-expressions.cpp<br>
    cfe/trunk/test/Parser/objc-init.m<br>
    cfe/trunk/test/Sema/designated-initializers.c<br>
    cfe/trunk/test/Sema/static-assert.c<br>
    cfe/trunk/test/SemaCXX/aggregate-initialization.cpp<br>
    cfe/trunk/test/SemaCXX/c99.cpp<br>
    cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp<br>
    cfe/trunk/test/SemaCXX/constexpr-printing.cpp<br>
    cfe/trunk/test/SemaCXX/cxx0x-initializer-constructor.cpp<br>
    cfe/trunk/test/SemaCXX/cxx2a-initializer-aggregates.cpp<br>
    cfe/trunk/test/SemaCXX/decltype.cpp<br>
    cfe/trunk/test/SemaCXX/designated-initializers-base-class.cpp<br>
    cfe/trunk/test/SemaCXX/designated-initializers.cpp<br>
    cfe/trunk/test/SemaCXX/eval-crashes.cpp<br>
    cfe/trunk/test/SemaCXX/member-init.cpp<br>
    cfe/trunk/test/SemaObjCXX/<a href="http://message.mm" rel="noreferrer" target="_blank">message.mm</a><br>
    cfe/trunk/test/SemaTemplate/instantiate-c99.cpp<br>
    cfe/trunk/test/SemaTemplate/instantiate-init.cpp<br>
<br>
Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=370544&r1=370543&r2=370544&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=370544&r1=370543&r2=370544&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)<br>
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Fri Aug 30 15:52:55 2019<br>
@@ -100,7 +100,6 @@ def GNUComplexInteger : DiagGroup<"gnu-c<br>
 def GNUConditionalOmittedOperand : DiagGroup<"gnu-conditional-omitted-operand">;<br>
 def ConfigMacros : DiagGroup<"config-macros">;<br>
 def : DiagGroup<"ctor-dtor-privacy">;<br>
-def GNUDesignator : DiagGroup<"gnu-designator">;<br>
 def GNUStringLiteralOperatorTemplate :<br>
   DiagGroup<"gnu-string-literal-operator-template">;<br>
 def UndefinedVarTemplate : DiagGroup<"undefined-var-template">;<br>
@@ -146,6 +145,12 @@ def Deprecated : DiagGroup<"deprecated",<br>
                                           DeprecatedWritableStr]>,<br>
                  DiagCategory<"Deprecations">;<br>
<br>
+def CXX2aDesignator : DiagGroup<"c++20-designator">;<br>
+// Allow -Wno-c99-designator to be used to turn off all warnings on valid C99<br>
+// designators (including the warning controlled by -Wc++20-designator).<br>
+def C99Designator : DiagGroup<"c99-designator", [CXX2aDesignator]>;<br>
+def GNUDesignator : DiagGroup<"gnu-designator">;<br>
+<br>
 def DynamicExceptionSpec<br>
     : DiagGroup<"dynamic-exception-spec", [DeprecatedDynamicExceptionSpec]>;<br>
<br>
@@ -896,7 +901,7 @@ def CXX17 : DiagGroup<"c++17-extensions"<br>
<br>
 // A warning group for warnings about using C++2a features as extensions in<br>
 // earlier C++ versions.<br>
-def CXX2a : DiagGroup<"c++2a-extensions">;<br>
+def CXX2a : DiagGroup<"c++2a-extensions", [CXX2aDesignator]>;<br>
<br>
 def : DiagGroup<"c++0x-extensions", [CXX11]>;<br>
 def : DiagGroup<"c++1y-extensions", [CXX14]>;<br>
@@ -909,7 +914,7 @@ def DelegatingCtorCycles :<br>
 def C11 : DiagGroup<"c11-extensions">;<br>
<br>
 // A warning group for warnings about using C99 features as extensions.<br>
-def C99 : DiagGroup<"c99-extensions">;<br>
+def C99 : DiagGroup<"c99-extensions", [C99Designator]>;<br>
<br>
 // A warning group for warnings about GCC extensions.<br>
 def GNU : DiagGroup<"gnu", [GNUAlignofExpression, GNUAnonymousStruct,<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=370544&r1=370543&r2=370544&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=370544&r1=370543&r2=370544&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Aug 30 15:52:55 2019<br>
@@ -154,7 +154,7 @@ def err_variably_modified_new_type : Err<br>
<br>
 // C99 Designated Initializers<br>
 def ext_designated_init : Extension<<br>
-  "designated initializers are a C99 feature">, InGroup<C99>;<br>
+  "designated initializers are a C99 feature">, InGroup<C99Designator>;<br>
 def err_array_designator_negative : Error<<br>
   "array designator value '%0' is negative">;<br>
 def err_array_designator_empty_range : Error<<br>
@@ -173,15 +173,17 @@ def err_field_designator_nonfield : Erro<br>
 def note_field_designator_found : Note<"field designator refers here">;<br>
 def err_designator_for_scalar_init : Error<<br>
   "designator in initializer for scalar type %0">;<br>
-def warn_subobject_initializer_overrides : Warning<<br>
-  "subobject initialization overrides initialization of other fields "<br>
-  "within its enclosing subobject">, InGroup<InitializerOverrides>;<br>
 def warn_initializer_overrides : Warning<<br>
-  "initializer overrides prior initialization of this subobject">,<br>
-  InGroup<InitializerOverrides>;<br>
+  "initializer %select{partially |}0overrides prior initialization of "<br>
+  "this subobject">, InGroup<InitializerOverrides>;<br>
+def ext_initializer_overrides : ExtWarn<warn_initializer_overrides.Text>,<br>
+  InGroup<InitializerOverrides>, SFINAEFailure;<br>
+def err_initializer_overrides_destructed : Error<<br>
+  "initializer would partially override prior initialization of object of "<br>
+  "type %1 with non-trivial destruction">;<br>
 def note_previous_initializer : Note<<br>
   "previous initialization %select{|with side effects }0is here"<br>
-  "%select{| (side effects may not occur at run time)}0">;<br>
+  "%select{| (side effects will not occur at run time)}0">;<br>
 def err_designator_into_flexible_array_member : Error<<br>
   "designator into flexible array member subobject">;<br>
 def note_flexible_array_member : Note<<br>
@@ -189,6 +191,28 @@ def note_flexible_array_member : Note<<br>
 def ext_flexible_array_init : Extension<<br>
   "flexible array initialization is a GNU extension">, InGroup<GNUFlexibleArrayInitializer>;<br>
<br>
+// C++20 designated initializers<br>
+def ext_cxx_designated_init : Extension<<br>
+  "designated initializers are a C++20 extension">, InGroup<CXX2aDesignator>;<br>
+def warn_cxx17_compat_designated_init : Warning<<br>
+  "designated initializers are incompatible with C++ standards before C++20">,<br>
+  InGroup<CXXPre2aCompatPedantic>, DefaultIgnore;<br>
+def ext_designated_init_mixed : ExtWarn<<br>
+  "mixture of designated and non-designated initializers in the same "<br>
+  "initializer list is a C99 extension">, InGroup<C99Designator>;<br>
+def note_designated_init_mixed : Note<<br>
+  "first non-designated initializer is here">;<br>
+def ext_designated_init_array : ExtWarn<<br>
+  "array designators are a C99 extension">, InGroup<C99Designator>;<br>
+def ext_designated_init_nested : ExtWarn<<br>
+  "nested designators are a C99 extension">, InGroup<C99Designator>;<br>
+def ext_designated_init_reordered : ExtWarn<<br>
+  "ISO C++ requires field designators to be specified in declaration order; "<br>
+  "field %1 will be initialized after field %0">, InGroup<Reorder>,<br>
+  SFINAEFailure;<br>
+def note_previous_field_init : Note<<br>
+  "previous initialization for field %0 is here">;<br>
+<br>
 // Declarations.<br>
 def ext_plain_complex : ExtWarn<<br>
   "plain '_Complex' requires a type specifier; assuming '_Complex double'">;<br>
<br>
Modified: cfe/trunk/include/clang/Sema/Sema.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=370544&r1=370543&r2=370544&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=370544&r1=370543&r2=370544&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Sema/Sema.h (original)<br>
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Aug 30 15:52:55 2019<br>
@@ -2775,6 +2775,9 @@ public:<br>
                                              Expr *Value,<br>
                                              bool AllowNRVO = true);<br>
<br>
+  bool CanPerformAggregateInitializationForOverloadResolution(<br>
+      const InitializedEntity &Entity, InitListExpr *From);<br>
+<br>
   bool CanPerformCopyInitialization(const InitializedEntity &Entity,<br>
                                     ExprResult Init);<br>
   ExprResult PerformCopyInitialization(const InitializedEntity &Entity,<br>
@@ -4636,6 +4639,10 @@ public:<br>
                            MultiExprArg InitArgList,<br>
                            SourceLocation RBraceLoc);<br>
<br>
+  ExprResult BuildInitList(SourceLocation LBraceLoc,<br>
+                           MultiExprArg InitArgList,<br>
+                           SourceLocation RBraceLoc);<br>
+<br>
   ExprResult ActOnDesignatedInitializer(Designation &Desig,<br>
                                         SourceLocation Loc,<br>
                                         bool GNUSyntax,<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=370544&r1=370543&r2=370544&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=370544&r1=370543&r2=370544&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Aug 30 15:52:55 2019<br>
@@ -6107,6 +6107,77 @@ Sema::BuildCompoundLiteralExpr(SourceLoc<br>
 ExprResult<br>
 Sema::ActOnInitList(SourceLocation LBraceLoc, MultiExprArg InitArgList,<br>
                     SourceLocation RBraceLoc) {<br>
+  // Only produce each kind of designated initialization diagnostic once.<br>
+  SourceLocation FirstDesignator;<br>
+  bool DiagnosedArrayDesignator = false;<br>
+  bool DiagnosedNestedDesignator = false;<br>
+  bool DiagnosedMixedDesignator = false;<br>
+<br>
+  // Check that any designated initializers are syntactically valid in the<br>
+  // current language mode.<br>
+  for (unsigned I = 0, E = InitArgList.size(); I != E; ++I) {<br>
+    if (auto *DIE = dyn_cast<DesignatedInitExpr>(InitArgList[I])) {<br>
+      if (FirstDesignator.isInvalid())<br>
+        FirstDesignator = DIE->getBeginLoc();<br>
+<br>
+      if (!getLangOpts().CPlusPlus)<br>
+        break;<br>
+<br>
+      if (!DiagnosedNestedDesignator && DIE->size() > 1) {<br>
+        DiagnosedNestedDesignator = true;<br>
+        Diag(DIE->getBeginLoc(), diag::ext_designated_init_nested)<br>
+          << DIE->getDesignatorsSourceRange();<br>
+      }<br>
+<br>
+      for (auto &Desig : DIE->designators()) {<br>
+        if (!Desig.isFieldDesignator() && !DiagnosedArrayDesignator) {<br>
+          DiagnosedArrayDesignator = true;<br>
+          Diag(Desig.getBeginLoc(), diag::ext_designated_init_array)<br>
+            << Desig.getSourceRange();<br>
+        }<br>
+      }<br>
+<br>
+      if (!DiagnosedMixedDesignator &&<br>
+          !isa<DesignatedInitExpr>(InitArgList[0])) {<br>
+        DiagnosedMixedDesignator = true;<br>
+        Diag(DIE->getBeginLoc(), diag::ext_designated_init_mixed)<br>
+          << DIE->getSourceRange();<br>
+        Diag(InitArgList[0]->getBeginLoc(), diag::note_designated_init_mixed)<br>
+          << InitArgList[0]->getSourceRange();<br>
+      }<br>
+    } else if (getLangOpts().CPlusPlus && !DiagnosedMixedDesignator &&<br>
+               isa<DesignatedInitExpr>(InitArgList[0])) {<br>
+      DiagnosedMixedDesignator = true;<br>
+      auto *DIE = cast<DesignatedInitExpr>(InitArgList[0]);<br>
+      Diag(DIE->getBeginLoc(), diag::ext_designated_init_mixed)<br>
+        << DIE->getSourceRange();<br>
+      Diag(InitArgList[I]->getBeginLoc(), diag::note_designated_init_mixed)<br>
+        << InitArgList[I]->getSourceRange();<br>
+    }<br>
+  }<br>
+<br>
+  if (FirstDesignator.isValid()) {<br>
+    // Only diagnose designated initiaization as a C++20 extension if we didn't<br>
+    // already diagnose use of (non-C++20) C99 designator syntax.<br>
+    if (getLangOpts().CPlusPlus && !DiagnosedArrayDesignator &&<br>
+        !DiagnosedNestedDesignator && !DiagnosedMixedDesignator) {<br>
+      Diag(FirstDesignator, getLangOpts().CPlusPlus2a<br>
+                                ? diag::warn_cxx17_compat_designated_init<br>
+                                : diag::ext_cxx_designated_init);<br>
+    } else if (!getLangOpts().CPlusPlus && !getLangOpts().C99) {<br>
+      Diag(FirstDesignator, diag::ext_designated_init);<br>
+    }<br>
+  }<br>
+<br>
+  return BuildInitList(LBraceLoc, InitArgList, RBraceLoc);<br>
+}<br>
+<br>
+ExprResult<br>
+Sema::BuildInitList(SourceLocation LBraceLoc, MultiExprArg InitArgList,<br>
+                    SourceLocation RBraceLoc) {<br>
+  // Semantic analysis for initializers is done by ActOnDeclarator() and<br>
+  // CheckInitializer() - it requires knowledge of the object being initialized.<br>
+<br>
   // Immediately handle non-overload placeholders.  Overloads can be<br>
   // resolved contextually, but everything else here can't.<br>
   for (unsigned I = 0, E = InitArgList.size(); I != E; ++I) {<br>
@@ -6121,9 +6192,6 @@ Sema::ActOnInitList(SourceLocation LBrac<br>
     }<br>
   }<br>
<br>
-  // Semantic analysis for initializers is done by ActOnDeclarator() and<br>
-  // CheckInitializer() - it requires knowledge of the object being initialized.<br>
-<br>
   InitListExpr *E = new (Context) InitListExpr(Context, LBraceLoc, InitArgList,<br>
                                                RBraceLoc);<br>
   E->setType(Context.VoidTy); // FIXME: just a place holder for now.<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=370544&r1=370543&r2=370544&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=370544&r1=370543&r2=370544&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaInit.cpp Fri Aug 30 15:52:55 2019<br>
@@ -281,6 +281,7 @@ class InitListChecker {<br>
   bool hadError = false;<br>
   bool VerifyOnly; // No diagnostics.<br>
   bool TreatUnavailableAsInvalid; // Used only in VerifyOnly mode.<br>
+  bool InOverloadResolution;<br>
   InitListExpr *FullyStructuredList = nullptr;<br>
   NoInitExpr *DummyExpr = nullptr;<br>
<br>
@@ -372,6 +373,63 @@ class InitListChecker {<br>
   ExprResult PerformEmptyInit(SourceLocation Loc,<br>
                               const InitializedEntity &Entity);<br>
<br>
+  /// Diagnose that OldInit (or part thereof) has been overridden by NewInit.<br>
+  void diagnoseInitOverride(Expr *OldInit, SourceRange NewInitRange,<br>
+                            bool FullyOverwritten = true) {<br>
+    // Overriding an initializer via a designator is valid with C99 designated<br>
+    // initializers, but ill-formed with C++20 designated initializers.<br>
+    unsigned DiagID = SemaRef.getLangOpts().CPlusPlus<br>
+                          ? diag::ext_initializer_overrides<br>
+                          : diag::warn_initializer_overrides;<br>
+<br>
+    if (InOverloadResolution && SemaRef.getLangOpts().CPlusPlus) {<br>
+      // In overload resolution, we have to strictly enforce the rules, and so<br>
+      // don't allow any overriding of prior initializers. This matters for a<br>
+      // case such as:<br>
+      //<br>
+      //   union U { int a, b; };<br>
+      //   struct S { int a, b; };<br>
+      //   void f(U), f(S);<br>
+      //<br>
+      // Here, f({.a = 1, .b = 2}) is required to call the struct overload. For<br>
+      // consistency, we disallow all overriding of prior initializers in<br>
+      // overload resolution, not only overriding of union members.<br>
+      hadError = true;<br>
+    } else if (OldInit->getType().isDestructedType() && !FullyOverwritten) {<br>
+      // If we'll be keeping around the old initializer but overwriting part of<br>
+      // the object it initialized, and that object is not trivially<br>
+      // destructible, this can leak. Don't allow that, not even as an<br>
+      // extension.<br>
+      //<br>
+      // FIXME: It might be reasonable to allow this in cases where the part of<br>
+      // the initializer that we're overriding has trivial destruction.<br>
+      DiagID = diag::err_initializer_overrides_destructed;<br>
+    } else if (!OldInit->getSourceRange().isValid()) {<br>
+      // We need to check on source range validity because the previous<br>
+      // initializer does not have to be an explicit initializer. e.g.,<br>
+      //<br>
+      // struct P { int a, b; };<br>
+      // struct PP { struct P p } l = { { .a = 2 }, .p.b = 3 };<br>
+      //<br>
+      // There is an overwrite taking place because the first braced initializer<br>
+      // list "{ .a = 2 }" already provides value for .p.b (which is zero).<br>
+      //<br>
+      // Such overwrites are harmless, so we don't diagnose them. (Note that in<br>
+      // C++, this cannot be reached unless we've already seen and diagnosed a<br>
+      // different conformance issue, such as a mixture of designated and<br>
+      // non-designated initializers or a multi-level designator.)<br>
+      return;<br>
+    }<br>
+<br>
+    if (!VerifyOnly) {<br>
+      SemaRef.Diag(NewInitRange.getBegin(), DiagID)<br>
+          << NewInitRange << FullyOverwritten << OldInit->getType();<br>
+      SemaRef.Diag(OldInit->getBeginLoc(), diag::note_previous_initializer)<br>
+          << (OldInit->HasSideEffects(SemaRef.Context) && FullyOverwritten)<br>
+          << OldInit->getSourceRange();<br>
+    }<br>
+  }<br>
+<br>
   // Explanation on the "FillWithNoInit" mode:<br>
   //<br>
   // Assume we have the following definitions (Case#1):<br>
@@ -410,9 +468,9 @@ class InitListChecker {<br>
                                SourceLocation Loc);<br>
<br>
 public:<br>
-  InitListChecker(Sema &S, const InitializedEntity &Entity,<br>
-                  InitListExpr *IL, QualType &T, bool VerifyOnly,<br>
-                  bool TreatUnavailableAsInvalid);<br>
+  InitListChecker(Sema &S, const InitializedEntity &Entity, InitListExpr *IL,<br>
+                  QualType &T, bool VerifyOnly, bool TreatUnavailableAsInvalid,<br>
+                  bool InOverloadResolution = false);<br>
   bool HadError() { return hadError; }<br>
<br>
   // Retrieves the fully-structured initializer list used for<br>
@@ -877,9 +935,11 @@ static bool hasAnyDesignatedInits(const<br>
<br>
 InitListChecker::InitListChecker(Sema &S, const InitializedEntity &Entity,<br>
                                  InitListExpr *IL, QualType &T, bool VerifyOnly,<br>
-                                 bool TreatUnavailableAsInvalid)<br>
+                                 bool TreatUnavailableAsInvalid,<br>
+                                 bool InOverloadResolution)<br>
     : SemaRef(S), VerifyOnly(VerifyOnly),<br>
-      TreatUnavailableAsInvalid(TreatUnavailableAsInvalid) {<br>
+      TreatUnavailableAsInvalid(TreatUnavailableAsInvalid),<br>
+      InOverloadResolution(InOverloadResolution) {<br>
   if (!VerifyOnly || hasAnyDesignatedInits(IL)) {<br>
     FullyStructuredList =<br>
         createInitListExpr(T, IL->getSourceRange(), IL->getNumInits());<br>
@@ -1959,7 +2019,8 @@ void InitListChecker::CheckStructUnionTy<br>
       }<br>
<br>
     // If there's a default initializer, use it.<br>
-    if (isa<CXXRecordDecl>(RD) && cast<CXXRecordDecl>(RD)->hasInClassInitializer()) {<br>
+    if (isa<CXXRecordDecl>(RD) &&<br>
+        cast<CXXRecordDecl>(RD)->hasInClassInitializer()) {<br>
       if (!StructuredList)<br>
         return;<br>
       for (RecordDecl::field_iterator FieldEnd = RD->field_end();<br>
@@ -2276,7 +2337,9 @@ class FieldInitializerValidatorCCC final<br>
 ///<br>
 /// @param NextField  If non-NULL and the first designator in @p DIE is<br>
 /// a field, this will be set to the field declaration corresponding<br>
-/// to the field named by the designator.<br>
+/// to the field named by the designator. On input, this is expected to be<br>
+/// the next field that would be initialized in the absence of designation,<br>
+/// if the complete object being initialized is a struct.<br>
 ///<br>
 /// @param NextElementIndex  If non-NULL and the first designator in @p<br>
 /// DIE is an array designator or GNU array-range designator, this<br>
@@ -2344,53 +2407,41 @@ InitListChecker::CheckDesignatedInitiali<br>
             SourceRange(D->getBeginLoc(), DIE->getEndLoc()));<br>
       else if (InitListExpr *Result = dyn_cast<InitListExpr>(ExistingInit))<br>
         StructuredList = Result;<br>
-      else if (!VerifyOnly) {<br>
-        if (DesignatedInitUpdateExpr *E =<br>
-                dyn_cast<DesignatedInitUpdateExpr>(ExistingInit))<br>
-          StructuredList = E->getUpdater();<br>
-        else {<br>
-          DesignatedInitUpdateExpr *DIUE = new (SemaRef.Context)<br>
-              DesignatedInitUpdateExpr(SemaRef.Context, D->getBeginLoc(),<br>
-                                       ExistingInit, DIE->getEndLoc());<br>
-          StructuredList->updateInit(SemaRef.Context, StructuredIndex, DIUE);<br>
-          StructuredList = DIUE->getUpdater();<br>
-        }<br>
-<br>
-        // We need to check on source range validity because the previous<br>
-        // initializer does not have to be an explicit initializer. e.g.,<br>
+      else {<br>
+        // We are creating an initializer list that initializes the<br>
+        // subobjects of the current object, but there was already an<br>
+        // initialization that completely initialized the current<br>
+        // subobject, e.g., by a compound literal:<br>
         //<br>
-        // struct P { int a, b; };<br>
-        // struct PP { struct P p } l = { { .a = 2 }, .p.b = 3 };<br>
+        // struct X { int a, b; };<br>
+        // struct X xs[] = { [0] = (struct X) { 1, 2 }, [0].b = 3 };<br>
         //<br>
-        // There is an overwrite taking place because the first braced initializer<br>
-        // list "{ .a = 2 }" already provides value for .p.b (which is zero).<br>
-        if (ExistingInit->getSourceRange().isValid()) {<br>
-          // We are creating an initializer list that initializes the<br>
-          // subobjects of the current object, but there was already an<br>
-          // initialization that completely initialized the current<br>
-          // subobject, e.g., by a compound literal:<br>
-          //<br>
-          // struct X { int a, b; };<br>
-          // struct X xs[] = { [0] = (struct X) { 1, 2 }, [0].b = 3 };<br>
-          //<br>
-          // Here, xs[0].a == 1 and xs[0].b == 3, since the second,<br>
-          // designated initializer re-initializes only its current object<br>
-          // subobject [0].b.<br>
-          SemaRef.Diag(D->getBeginLoc(),<br>
-                       diag::warn_subobject_initializer_overrides)<br>
-              << SourceRange(D->getBeginLoc(), DIE->getEndLoc());<br>
-<br>
-          SemaRef.Diag(ExistingInit->getBeginLoc(),<br>
-                       diag::note_previous_initializer)<br>
-              << /*FIXME:has side effects=*/0 << ExistingInit->getSourceRange();<br>
+        // Here, xs[0].a == 1 and xs[0].b == 3, since the second,<br>
+        // designated initializer re-initializes only its current object<br>
+        // subobject [0].b.<br>
+        diagnoseInitOverride(ExistingInit,<br>
+                             SourceRange(D->getBeginLoc(), DIE->getEndLoc()),<br>
+                             /*FullyOverwritten=*/false);<br>
+<br>
+        if (!VerifyOnly) {<br>
+          if (DesignatedInitUpdateExpr *E =<br>
+                  dyn_cast<DesignatedInitUpdateExpr>(ExistingInit))<br>
+            StructuredList = E->getUpdater();<br>
+          else {<br>
+            DesignatedInitUpdateExpr *DIUE = new (SemaRef.Context)<br>
+                DesignatedInitUpdateExpr(SemaRef.Context, D->getBeginLoc(),<br>
+                                         ExistingInit, DIE->getEndLoc());<br>
+            StructuredList->updateInit(SemaRef.Context, StructuredIndex, DIUE);<br>
+            StructuredList = DIUE->getUpdater();<br>
+          }<br>
+        } else {<br>
+          // We don't need to track the structured representation of a<br>
+          // designated init update of an already-fully-initialized object in<br>
+          // verify-only mode. The only reason we would need the structure is<br>
+          // to determine where the uninitialized "holes" are, and in this<br>
+          // case, we know there aren't any and we can't introduce any.<br>
+          StructuredList = nullptr;<br>
         }<br>
-      } else {<br>
-        // We don't need to track the structured representation of a designated<br>
-        // init update of an already-fully-initialized object in verify-only<br>
-        // mode. The only reason we would need the structure is to determine<br>
-        // where the uninitialized "holes" are, and in this case, we know there<br>
-        // aren't any and we can't introduce any.<br>
-        StructuredList = nullptr;<br>
       }<br>
     }<br>
   }<br>
@@ -2475,10 +2526,11 @@ InitListChecker::CheckDesignatedInitiali<br>
       }<br>
     }<br>
<br>
-    unsigned FieldIndex = 0;<br>
-<br>
+    unsigned NumBases = 0;<br>
     if (auto *CXXRD = dyn_cast<CXXRecordDecl>(RT->getDecl()))<br>
-      FieldIndex = CXXRD->getNumBases();<br>
+      NumBases = CXXRD->getNumBases();<br>
+<br>
+    unsigned FieldIndex = NumBases;<br>
<br>
     for (auto *FI : RT->getDecl()->fields()) {<br>
       if (FI->isUnnamedBitfield())<br>
@@ -2504,15 +2556,10 @@ InitListChecker::CheckDesignatedInitiali<br>
                  && "A union should never have more than one initializer!");<br>
<br>
           Expr *ExistingInit = StructuredList->getInit(0);<br>
-          if (ExistingInit && !VerifyOnly) {<br>
+          if (ExistingInit) {<br>
             // We're about to throw away an initializer, emit warning.<br>
-            SemaRef.Diag(D->getFieldLoc(),<br>
-                         diag::warn_initializer_overrides)<br>
-              << D->getSourceRange();<br>
-            SemaRef.Diag(ExistingInit->getBeginLoc(),<br>
-                         diag::note_previous_initializer)<br>
-                << /*FIXME:has side effects=*/0<br>
-                << ExistingInit->getSourceRange();<br>
+            diagnoseInitOverride(<br>
+                ExistingInit, SourceRange(D->getBeginLoc(), DIE->getEndLoc()));<br>
           }<br>
<br>
           // remove existing initializer<br>
@@ -2535,6 +2582,54 @@ InitListChecker::CheckDesignatedInitiali<br>
       return true;<br>
     }<br>
<br>
+    // C++20 [dcl.init.list]p3:<br>
+    //   The ordered identifiers in the designators of the designated-<br>
+    //   initializer-list shall form a subsequence of the ordered identifiers<br>
+    //   in the direct non-static data members of T.<br>
+    //<br>
+    // Note that this is not a condition on forming the aggregate<br>
+    // initialization, only on actually performing initialization,<br>
+    // so it is not checked in VerifyOnly mode.<br>
+    //<br>
+    // FIXME: This is the only reordering diagnostic we produce, and it only<br>
+    // catches cases where we have a top-level field designator that jumps<br>
+    // backwards. This is the only such case that is reachable in an<br>
+    // otherwise-valid C++20 program, so is the only case that's required for<br>
+    // conformance, but for consistency, we should diagnose all the other<br>
+    // cases where a designator takes us backwards too.<br>
+    if (IsFirstDesignator && !VerifyOnly && SemaRef.getLangOpts().CPlusPlus &&<br>
+        NextField &&<br>
+        (*NextField == RT->getDecl()->field_end() ||<br>
+         (*NextField)->getFieldIndex() > Field->getFieldIndex() + 1)) {<br>
+      // Find the field that we just initialized.<br>
+      FieldDecl *PrevField = nullptr;<br>
+      for (auto FI = RT->getDecl()->field_begin();<br>
+           FI != RT->getDecl()->field_end(); ++FI) {<br>
+        if (FI->isUnnamedBitfield())<br>
+          continue;<br>
+        if (*NextField != RT->getDecl()->field_end() &&<br>
+            declaresSameEntity(*FI, **NextField))<br>
+          break;<br>
+        PrevField = *FI;<br>
+      }<br>
+<br>
+      if (PrevField &&<br>
+          PrevField->getFieldIndex() > KnownField->getFieldIndex()) {<br>
+        SemaRef.Diag(DIE->getBeginLoc(), diag::ext_designated_init_reordered)<br>
+            << KnownField << PrevField << DIE->getSourceRange();<br>
+<br>
+        unsigned OldIndex = NumBases + PrevField->getFieldIndex();<br>
+        if (StructuredList && OldIndex <= StructuredList->getNumInits()) {<br>
+          if (Expr *PrevInit = StructuredList->getInit(OldIndex)) {<br>
+            SemaRef.Diag(PrevInit->getBeginLoc(),<br>
+                         diag::note_previous_field_init)<br>
+                << PrevField << PrevInit->getSourceRange();<br>
+          }<br>
+        }<br>
+      }<br>
+    }<br>
+<br>
+<br>
     // Update the designator with the field declaration.<br>
     if (!VerifyOnly)<br>
       D->setField(*Field);<br>
@@ -2875,7 +2970,7 @@ InitListChecker::getStructuredSubobjectI<br>
     if (!IsFullyOverwritten)<br>
       return Result;<br>
<br>
-  if (ExistingInit && !VerifyOnly) {<br>
+  if (ExistingInit) {<br>
     // We are creating an initializer list that initializes the<br>
     // subobjects of the current object, but there was already an<br>
     // initialization that completely initialized the current<br>
@@ -2895,11 +2990,7 @@ InitListChecker::getStructuredSubobjectI<br>
     // struct X xs[] = { [0] = (struct X) { 1, 2 }, [0].b = 3 };<br>
     //<br>
     // This case is handled by CheckDesignatedInitializer.<br>
-    SemaRef.Diag(InitRange.getBegin(),<br>
-                 diag::warn_subobject_initializer_overrides)<br>
-      << InitRange;<br>
-    SemaRef.Diag(ExistingInit->getBeginLoc(), diag::note_previous_initializer)<br>
-        << /*FIXME:has side effects=*/0 << ExistingInit->getSourceRange();<br>
+    diagnoseInitOverride(ExistingInit, InitRange);<br>
   }<br>
<br>
   unsigned ExpectedNumInits = 0;<br>
@@ -2968,24 +3059,23 @@ void InitListChecker::UpdateStructuredLi<br>
   if (Expr *PrevInit = StructuredList->updateInit(SemaRef.Context,<br>
                                                   StructuredIndex, expr)) {<br>
     // This initializer overwrites a previous initializer. Warn.<br>
-    // We need to check on source range validity because the previous<br>
-    // initializer does not have to be an explicit initializer.<br>
-    // struct P { int a, b; };<br>
-    // struct PP { struct P p } l = { { .a = 2 }, .p.b = 3 };<br>
-    // There is an overwrite taking place because the first braced initializer<br>
-    // list "{ .a = 2 }' already provides value for .p.b (which is zero).<br>
-    if (PrevInit->getSourceRange().isValid() && !VerifyOnly) {<br>
-      SemaRef.Diag(expr->getBeginLoc(), diag::warn_initializer_overrides)<br>
-          << expr->getSourceRange();<br>
-<br>
-      SemaRef.Diag(PrevInit->getBeginLoc(), diag::note_previous_initializer)<br>
-          << /*FIXME:has side effects=*/0 << PrevInit->getSourceRange();<br>
-    }<br>
+    diagnoseInitOverride(PrevInit, expr->getSourceRange());<br>
   }<br>
<br>
   ++StructuredIndex;<br>
 }<br>
<br>
+/// Determine whether we can perform aggregate initialization for the purposes<br>
+/// of overload resolution.<br>
+bool Sema::CanPerformAggregateInitializationForOverloadResolution(<br>
+    const InitializedEntity &Entity, InitListExpr *From) {<br>
+  QualType Type = Entity.getType();<br>
+  InitListChecker Check(*this, Entity, From, Type, /*VerifyOnly=*/true,<br>
+                        /*TreatUnavailableAsInvalid=*/false,<br>
+                        /*InOverloadResolution=*/true);<br>
+  return !Check.HadError();<br>
+}<br>
+<br>
 /// Check that the given Index expression is a valid array designator<br>
 /// value. This is essentially just a wrapper around<br>
 /// VerifyIntegerConstantExpression that also checks for negative values<br>
@@ -3019,6 +3109,7 @@ ExprResult Sema::ActOnDesignatedInitiali<br>
   bool Invalid = false;<br>
   SmallVector<ASTDesignator, 32> Designators;<br>
   SmallVector<Expr *, 32> InitExpressions;<br>
+  bool HasArrayDesignator = false;<br>
<br>
   // Build designators and check array designator expressions.<br>
   for (unsigned Idx = 0; Idx < Desig.getNumDesignators(); ++Idx) {<br>
@@ -3042,6 +3133,7 @@ ExprResult Sema::ActOnDesignatedInitiali<br>
                                             D.getRBracketLoc()));<br>
         InitExpressions.push_back(Index);<br>
       }<br>
+      HasArrayDesignator = true;<br>
       break;<br>
     }<br>
<br>
@@ -3085,6 +3177,7 @@ ExprResult Sema::ActOnDesignatedInitiali<br>
           InitExpressions.push_back(EndIndex);<br>
         }<br>
       }<br>
+      HasArrayDesignator = true;<br>
       break;<br>
     }<br>
     }<br>
@@ -3096,17 +3189,8 @@ ExprResult Sema::ActOnDesignatedInitiali<br>
   // Clear out the expressions within the designation.<br>
   Desig.ClearExprs(*this);<br>
<br>
-  DesignatedInitExpr *DIE<br>
-    = DesignatedInitExpr::Create(Context,<br>
-                                 Designators,<br>
-                                 InitExpressions, Loc, GNUSyntax,<br>
-                                 Init.getAs<Expr>());<br>
-<br>
-  if (!getLangOpts().C99)<br>
-    Diag(DIE->getBeginLoc(), diag::ext_designated_init)<br>
-        << DIE->getSourceRange();<br>
-<br>
-  return DIE;<br>
+  return DesignatedInitExpr::Create(Context, Designators, InitExpressions, Loc,<br>
+                                    GNUSyntax, Init.getAs<Expr>());<br>
 }<br>
<br>
 //===----------------------------------------------------------------------===//<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaOverload.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=370544&r1=370543&r2=370544&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=370544&r1=370543&r2=370544&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Fri Aug 30 15:52:55 2019<br>
@@ -4920,13 +4920,11 @@ TryListConversion(Sema &S, InitListExpr<br>
     // Type is an aggregate, argument is an init list. At this point it comes<br>
     // down to checking whether the initialization works.<br>
     // FIXME: Find out whether this parameter is consumed or not.<br>
-    // FIXME: Expose SemaInit's aggregate initialization code so that we don't<br>
-    // need to call into the initialization code here; overload resolution<br>
-    // should not be doing that.<br>
     InitializedEntity Entity =<br>
         InitializedEntity::InitializeParameter(S.Context, ToType,<br>
                                                /*Consumed=*/false);<br>
-    if (S.CanPerformCopyInitialization(Entity, From)) {<br>
+    if (S.CanPerformAggregateInitializationForOverloadResolution(Entity,<br>
+                                                                 From)) {<br>
       Result.setUserDefined();<br>
       Result.UserDefined.Before.setAsIdentityConversion();<br>
       // Initializer lists don't have a type.<br>
<br>
Modified: cfe/trunk/lib/Sema/TreeTransform.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=370544&r1=370543&r2=370544&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=370544&r1=370543&r2=370544&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/TreeTransform.h (original)<br>
+++ cfe/trunk/lib/Sema/TreeTransform.h Fri Aug 30 15:52:55 2019<br>
@@ -2416,7 +2416,7 @@ public:<br>
   ExprResult RebuildInitList(SourceLocation LBraceLoc,<br>
                              MultiExprArg Inits,<br>
                              SourceLocation RBraceLoc) {<br>
-    return SemaRef.ActOnInitList(LBraceLoc, Inits, RBraceLoc);<br>
+    return SemaRef.BuildInitList(LBraceLoc, Inits, RBraceLoc);<br>
   }<br>
<br>
   /// Build a new designated initializer expression.<br>
<br>
Modified: cfe/trunk/test/Analysis/globals.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/globals.cpp?rev=370544&r1=370543&r2=370544&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/globals.cpp?rev=370544&r1=370543&r2=370544&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Analysis/globals.cpp (original)<br>
+++ cfe/trunk/test/Analysis/globals.cpp Fri Aug 30 15:52:55 2019<br>
@@ -1,4 +1,4 @@<br>
-// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s<br>
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify -std=c++2a %s<br>
<br>
<br>
 static const unsigned long long scull = 0;<br>
<br>
Modified: cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp?rev=370544&r1=370543&r2=370544&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp?rev=370544&r1=370543&r2=370544&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp (original)<br>
+++ cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp Fri Aug 30 15:52:55 2019<br>
@@ -360,7 +360,7 @@ namespace LValueToRValueUnion {<br>
   extern const U pu;<br>
   constexpr const int *pua = &pu.a;<br>
   constexpr const int *pub = &pu.b;<br>
-  constexpr U pu = { .b = 1 }; // expected-warning {{C99 feature}}<br>
+  constexpr U pu = { .b = 1 }; // expected-warning {{C++20 extension}}<br>
   constexpr const int a2 = *pua; // expected-error {{constant expression}} expected-note {{read of member 'a' of union with active member 'b'}}<br>
   constexpr const int b2 = *pub; // ok<br>
 }<br>
<br>
Modified: cfe/trunk/test/CodeGenObjCXX/<a href="http://designated-initializers.mm" rel="noreferrer" target="_blank">designated-initializers.mm</a><br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/designated-initializers.mm?rev=370544&r1=370543&r2=370544&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/designated-initializers.mm?rev=370544&r1=370543&r2=370544&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGenObjCXX/<a href="http://designated-initializers.mm" rel="noreferrer" target="_blank">designated-initializers.mm</a> (original)<br>
+++ cfe/trunk/test/CodeGenObjCXX/<a href="http://designated-initializers.mm" rel="noreferrer" target="_blank">designated-initializers.mm</a> Fri Aug 30 15:52:55 2019<br>
@@ -1,4 +1,4 @@<br>
-// RUN: %clang_cc1 -triple arm64 %s -verify -emit-llvm -o - | FileCheck %s<br>
+// RUN: %clang_cc1 -triple arm64 %s -verify -emit-llvm -o - -Wno-c99-designator | FileCheck %s<br>
 // expected-no-diagnostics<br>
<br>
 // Make sure we don't enter an infinite loop (rdar://21942503)<br>
<br>
Modified: cfe/trunk/test/PCH/cxx1y-default-initializer.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx1y-default-initializer.cpp?rev=370544&r1=370543&r2=370544&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx1y-default-initializer.cpp?rev=370544&r1=370543&r2=370544&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/PCH/cxx1y-default-initializer.cpp (original)<br>
+++ cfe/trunk/test/PCH/cxx1y-default-initializer.cpp Fri Aug 30 15:52:55 2019<br>
@@ -37,8 +37,8 @@ C<int> ci;<br>
<br>
 static_assert(A{}.z == 3, "");<br>
 static_assert(A{1}.z == 4, "");<br>
-static_assert(A{.y = 5}.z == 5, ""); // expected-warning {{C99}}<br>
-static_assert(A{3, .y = 1}.z == 4, ""); // expected-warning {{C99}}<br>
+static_assert(A{.y = 5}.z == 5, ""); // expected-warning {{C++20}}<br>
+static_assert(A{3, .y = 1}.z == 4, ""); // expected-warning {{C99}} expected-note {{here}}<br>
 static_assert(make<int>().z == 3, "");<br>
 static_assert(make<int>(12).z == 15, "");<br>
 static_assert(C<int>().c == 0, "");<br>
<br>
Modified: cfe/trunk/test/Parser/cxx0x-lambda-expressions.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-lambda-expressions.cpp?rev=370544&r1=370543&r2=370544&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-lambda-expressions.cpp?rev=370544&r1=370543&r2=370544&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Parser/cxx0x-lambda-expressions.cpp (original)<br>
+++ cfe/trunk/test/Parser/cxx0x-lambda-expressions.cpp Fri Aug 30 15:52:55 2019<br>
@@ -1,5 +1,5 @@<br>
-// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify -std=c++11 %s<br>
-// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify -std=c++2a %s<br>
+// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify -std=c++11 -Wno-c99-designator %s<br>
+// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify -std=c++2a -Wno-c99-designator %s<br>
<br>
 enum E { e };<br>
<br>
<br>
Modified: cfe/trunk/test/Parser/objc-init.m<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/objc-init.m?rev=370544&r1=370543&r2=370544&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/objc-init.m?rev=370544&r1=370543&r2=370544&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Parser/objc-init.m (original)<br>
+++ cfe/trunk/test/Parser/objc-init.m Fri Aug 30 15:52:55 2019<br>
@@ -1,7 +1,7 @@<br>
 // RUN: %clang_cc1 -fsyntax-only -fobjc-runtime=macosx-fragile -verify -pedantic -Wno-objc-root-class %s<br>
-// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime=macosx-fragile -verify -x objective-c++ -Wno-objc-root-class %s<br>
-// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime=macosx-fragile -verify -x objective-c++ -Wno-objc-root-class -std=c++98 %s<br>
-// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime=macosx-fragile -verify -x objective-c++ -Wno-objc-root-class -std=c++11 %s<br>
+// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime=macosx-fragile -verify -x objective-c++ -Wno-c99-designator -Wno-objc-root-class %s<br>
+// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime=macosx-fragile -verify -x objective-c++ -Wno-c99-designator -Wno-objc-root-class -std=c++98 %s<br>
+// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime=macosx-fragile -verify -x objective-c++ -Wno-c99-designator -Wno-objc-root-class -std=c++11 %s<br>
 // rdar://5707001<br>
<br>
 @interface NSNumber;<br>
<br>
Modified: cfe/trunk/test/Sema/designated-initializers.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/designated-initializers.c?rev=370544&r1=370543&r2=370544&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/designated-initializers.c?rev=370544&r1=370543&r2=370544&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Sema/designated-initializers.c (original)<br>
+++ cfe/trunk/test/Sema/designated-initializers.c Fri Aug 30 15:52:55 2019<br>
@@ -130,10 +130,10 @@ int get8() { ++counter; return 8; }<br>
 void test() {<br>
   struct X xs[] = { <br>
     [0] = (struct X){1, 2}, // expected-note 2 {{previous initialization is here}}<br>
-    [0].c = 3,  // expected-warning{{subobject initialization overrides initialization of other fields within its enclosing subobject}}<br>
+    [0].c = 3,  // expected-warning{{initializer partially overrides prior initialization of this subobject}}<br>
     (struct X) {4, 5, 6}, // expected-note{{previous initialization is here}}<br>
-    [1].b = get8(), // expected-warning{{subobject initialization overrides initialization of other fields within its enclosing subobject}}<br>
-    [0].b = 8   // expected-warning{{subobject initialization overrides initialization of other fields within its enclosing subobject}}<br>
+    [1].b = get8(), // expected-warning{{initializer partially overrides prior initialization of this subobject}}<br>
+    [0].b = 8   // expected-warning{{initializer partially overrides prior initialization of this subobject}}<br>
   };<br>
 }<br>
<br>
@@ -331,20 +331,20 @@ struct overwrite_string_struct {<br>
   char L[6];<br>
   int M;<br>
 } overwrite_string[] = {<br>
-  { { "foo" }, 1 }, // expected-note {{previous initialization is here}}<br>
-  [0].L[2] = 'x' // expected-warning{{subobject initialization overrides initialization of other fields}}<br>
+  { { "foo" }, 1 }, // expected-note{{previous initialization is here}}<br>
+  [0].L[2] = 'x' // expected-warning{{initializer partially overrides prior initialization of this subobject}}<br>
 };<br>
 struct overwrite_string_struct2 {<br>
   char L[6];<br>
   int M;<br>
 } overwrite_string2[] = {<br>
     { { "foo" }, 1 }, // expected-note{{previous initialization is here}}<br>
-    [0].L[4] = 'x' // expected-warning{{subobject initialization overrides initialization of other fields}}<br>
+    [0].L[4] = 'x' // expected-warning{{initializer partially overrides prior initialization of this subobject}}<br>
   };<br>
 struct overwrite_string_struct<br>
 overwrite_string3[] = {<br>
   "foo", 1,           // expected-note{{previous initialization is here}}<br>
-  [0].L[4] = 'x'  // expected-warning{{subobject initialization overrides initialization of other fields}}<br>
+  [0].L[4] = 'x'  // expected-warning{{initializer partially overrides prior initialization of this subobject}}<br>
 };<br>
 struct overwrite_string_struct<br>
 overwrite_string4[] = {<br>
<br>
Modified: cfe/trunk/test/Sema/static-assert.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/static-assert.c?rev=370544&r1=370543&r2=370544&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/static-assert.c?rev=370544&r1=370543&r2=370544&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Sema/static-assert.c (original)<br>
+++ cfe/trunk/test/Sema/static-assert.c Fri Aug 30 15:52:55 2019<br>
@@ -1,6 +1,6 @@<br>
 // RUN: %clang_cc1 -std=c11 -fsyntax-only -verify %s<br>
 // RUN: %clang_cc1 -std=c99 -pedantic -fsyntax-only -verify=expected,ext %s<br>
-// RUN: %clang_cc1 -xc++ -std=c++11 -pedantic -fsyntax-only -verify=expected,ext %s<br>
+// RUN: %clang_cc1 -xc++ -std=c++11 -pedantic -fsyntax-only -verify=expected,ext,cxx %s<br>
<br>
 _Static_assert("foo", "string is nonzero"); // ext-warning {{'_Static_assert' is a C11 extension}}<br>
 #ifndef __cplusplus<br>
@@ -42,10 +42,7 @@ struct A {<br>
   }<br>
<br>
 typedef UNION(unsigned, struct A) U1; // ext-warning 3 {{'_Static_assert' is a C11 extension}}<br>
-UNION(char[2], short) u2 = { .one = { 'a', 'b' } }; // ext-warning 3 {{'_Static_assert' is a C11 extension}}<br>
-#if defined(__cplusplus)<br>
-// ext-warning@-2 {{designated initializers are a C99 feature}}<br>
-#endif<br>
+UNION(char[2], short) u2 = { .one = { 'a', 'b' } }; // ext-warning 3 {{'_Static_assert' is a C11 extension}} cxx-warning {{designated initializers are a C++20 extension}}<br>
 typedef UNION(char, short) U3; // expected-error {{static_assert failed due to requirement 'sizeof(char) == sizeof(short)' "type size mismatch"}} \<br>
                                // ext-warning 3 {{'_Static_assert' is a C11 extension}}<br>
 typedef UNION(float, 0.5f) U4; // expected-error {{expected a type}} \<br>
<br>
Modified: cfe/trunk/test/SemaCXX/aggregate-initialization.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/aggregate-initialization.cpp?rev=370544&r1=370543&r2=370544&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/aggregate-initialization.cpp?rev=370544&r1=370543&r2=370544&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaCXX/aggregate-initialization.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/aggregate-initialization.cpp Fri Aug 30 15:52:55 2019<br>
@@ -1,6 +1,7 @@<br>
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s <br>
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++14 %s <br>
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 %s <br>
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s<br>
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++14 %s<br>
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 %s<br>
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++2a %s<br>
<br>
 // Verify that using an initializer list for a non-aggregate looks for<br>
 // constructors..<br>
<br>
Modified: cfe/trunk/test/SemaCXX/c99.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/c99.cpp?rev=370544&r1=370543&r2=370544&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/c99.cpp?rev=370544&r1=370543&r2=370544&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaCXX/c99.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/c99.cpp Fri Aug 30 15:52:55 2019<br>
@@ -1,9 +1,70 @@<br>
-// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s<br>
+// RUN: %clang_cc1 -fsyntax-only -pedantic -verify=expected,cxx17 -std=c++17 %s<br>
+// RUN: %clang_cc1 -fsyntax-only -pedantic -verify=expected,cxx20 -std=c++2a %s<br>
+<br>
+// cxx17-warning@* 0+{{designated initializers are a C++20 extension}}<br>
+<br>
 void f1(int i[static 5]) { // expected-error{{C99}}<br>
 }<br>
<br>
 struct Point { int x; int y; int z[]; }; // expected-warning{{flexible array members are a C99 feature}}<br>
<br>
-Point p1 = { .x = 17, // expected-warning{{designated initializers are a C99 feature}}<br>
-             y: 25 }; // expected-warning{{designated initializers are a C99 feature}} \<br>
-                      // expected-warning{{use of GNU old-style field designator extension}}<br>
+Point p1 = { .x = 17,<br>
+             y: 25 }; // expected-warning{{use of GNU old-style field designator extension}}<br>
+<br>
+Point p2 = {<br>
+  .x = 17, // expected-warning {{mixture of designated and non-designated initializers in the same initializer list is a C99 extension}}<br>
+  25 // expected-note {{first non-designated initializer}}<br>
+};<br>
+<br>
+Point p3 = {<br>
+  .x = 17, // expected-note {{previous initialization is here}}<br>
+  .x = 18, // expected-warning {{initializer overrides prior initialization of this subobject}}<br>
+};<br>
+<br>
+Point p4 = {<br>
+  .x = 17, // expected-warning {{mixture of designated and non-designated initializers in the same initializer list is a C99 extension}}<br>
+  25, // expected-note {{first non-designated initializer}}<br>
+  // expected-note@-1 {{previous initialization is here}}<br>
+  .y = 18, // expected-warning {{initializer overrides prior initialization of this subobject}}<br>
+};<br>
+<br>
+int arr[1] = {[0] = 0}; // expected-warning {{array designators are a C99 extension}}<br>
+<br>
+struct Pt { int x, y; };<br>
+struct Rect { Pt tl, br; };<br>
+Rect r = {<br>
+  .tl.x = 0 // expected-warning {{nested designators are a C99 extension}}<br>
+};<br>
+<br>
+struct NonTrivial {<br>
+  NonTrivial();<br>
+  ~NonTrivial();<br>
+};<br>
+struct S {<br>
+  int a;<br>
+  NonTrivial b;<br>
+};<br>
+struct T {<br>
+  S s;<br>
+};<br>
+S f();<br>
+<br>
+T t1 = {<br>
+  .s = f()<br>
+};<br>
+<br>
+// It's important that we reject this; we would not destroy the existing<br>
+// 'NonTrivial' object before overwriting it (and even calling its destructor<br>
+// would not necessarily be correct).<br>
+T t2 = {<br>
+  .s = f(), // expected-note {{previous}}<br>
+  .s.b = NonTrivial() // expected-error {{initializer would partially override prior initialization of object of type 'S' with non-trivial destruction}}<br>
+  // expected-warning@-1 {{nested}}<br>
+};<br>
+<br>
+// FIXME: It might be reasonable to accept this.<br>
+T t3 = {<br>
+  .s = f(), // expected-note {{previous}}<br>
+  .s.a = 0 // expected-error {{initializer would partially override prior initialization of object of type 'S' with non-trivial destruction}}<br>
+  // expected-warning@-1 {{nested}}<br>
+};<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=370544&r1=370543&r2=370544&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp?rev=370544&r1=370543&r2=370544&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Fri Aug 30 15:52:55 2019<br>
@@ -1,4 +1,4 @@<br>
-// RUN: %clang_cc1 -triple x86_64-linux -Wno-string-plus-int -Wno-pointer-arith -Wno-zero-length-array -fsyntax-only -fcxx-exceptions -verify -std=c++11 -pedantic %s -Wno-comment -Wno-tautological-pointer-compare -Wno-bool-conversion<br>
+// RUN: %clang_cc1 -triple x86_64-linux -Wno-string-plus-int -Wno-pointer-arith -Wno-zero-length-array -Wno-c99-designator -fsyntax-only -fcxx-exceptions -verify -std=c++11 -pedantic %s -Wno-comment -Wno-tautological-pointer-compare -Wno-bool-conversion<br>
<br>
 namespace StaticAssertFoldTest {<br>
<br>
@@ -566,7 +566,7 @@ static_assert(fail(*(&(&(*(*&(&zs[2] - 1<br>
 expected-error {{static_assert expression is not an integral constant expression}} \<br>
 expected-note {{in call to 'fail(zs[1][0][1][0])'}}<br>
<br>
-constexpr int arr[40] = { 1, 2, 3, [8] = 4 }; // expected-warning {{C99 feature}}<br>
+constexpr int arr[40] = { 1, 2, 3, [8] = 4 };<br>
 constexpr int SumNonzero(const int *p) {<br>
   return *p + (*p ? SumNonzero(p+1) : 0);<br>
 }<br>
@@ -979,7 +979,7 @@ union U {<br>
   int b;<br>
 };<br>
<br>
-constexpr U u[4] = { { .a = 0 }, { .b = 1 }, { .a = 2 }, { .b = 3 } }; // expected-warning 4{{C99 feature}}<br>
+constexpr U u[4] = { { .a = 0 }, { .b = 1 }, { .a = 2 }, { .b = 3 } };<br>
 static_assert(u[0].a == 0, "");<br>
 static_assert(u[0].b, ""); // expected-error {{constant expression}} expected-note {{read of member 'b' of union with active member 'a'}}<br>
 static_assert(u[1].b == 1, "");<br>
<br>
Modified: cfe/trunk/test/SemaCXX/constexpr-printing.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constexpr-printing.cpp?rev=370544&r1=370543&r2=370544&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constexpr-printing.cpp?rev=370544&r1=370543&r2=370544&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaCXX/constexpr-printing.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/constexpr-printing.cpp Fri Aug 30 15:52:55 2019<br>
@@ -41,11 +41,7 @@ expected-error {{constant expression}} \<br>
 expected-note {{in call to 'test_printing(12, 3.976200e+01, 3+4i, 1.290000e+01+3.600000e+00i, &u2.T::arr[4], u2.another.arr[2], {5, 1, 2, 3}, {{{}}, {{}}, &u1.T::arr[2]})'}}<br>
<br>
 struct V {<br>
-  // FIXME: when we can generate these as constexpr constructors, remove the<br>
-  // explicit definitions.<br>
-  constexpr V() : arr{[255] = 42} {}<br>
-  constexpr V(const V &v) : arr{[255] = 42} {}<br>
-  int arr[256];<br>
+  int arr[256] = {[255] = 42}; // expected-warning {{C99}}<br>
 };<br>
 constexpr V v;<br>
 constexpr int get(const int *p) { return *p; } // expected-note {{read of dereferenced one-past-the-end pointer}}<br>
<br>
Modified: cfe/trunk/test/SemaCXX/cxx0x-initializer-constructor.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-initializer-constructor.cpp?rev=370544&r1=370543&r2=370544&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-initializer-constructor.cpp?rev=370544&r1=370543&r2=370544&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaCXX/cxx0x-initializer-constructor.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/cxx0x-initializer-constructor.cpp Fri Aug 30 15:52:55 2019<br>
@@ -406,6 +406,6 @@ namespace PR11410 {<br>
     0, 1<br>
   }; // expected-error {{ambiguous}} expected-note {{in implicit initialization of array element 2}}<br>
   C c2[3] = {<br>
-    [0] = 1, [2] = 3<br>
+    [0] = 1, [2] = 3 // expected-warning {{C99}}<br>
   }; // expected-error {{ambiguous}} expected-note {{in implicit initialization of array element 1}}<br>
 }<br>
<br>
Modified: cfe/trunk/test/SemaCXX/cxx2a-initializer-aggregates.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx2a-initializer-aggregates.cpp?rev=370544&r1=370543&r2=370544&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx2a-initializer-aggregates.cpp?rev=370544&r1=370543&r2=370544&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaCXX/cxx2a-initializer-aggregates.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/cxx2a-initializer-aggregates.cpp Fri Aug 30 15:52:55 2019<br>
@@ -1,4 +1,9 @@<br>
-// RUN: %clang_cc1 -std=c++2a %s -verify<br>
+// RUN: %clang_cc1 -std=c++2a %s -verify=expected,pedantic,override,reorder -pedantic-errors<br>
+// RUN: %clang_cc1 -std=c++2a %s -verify=expected,pedantic -Werror=c99-designator -Wno-reorder -Wno-initializer-overrides<br>
+// RUN: %clang_cc1 -std=c++2a %s -verify=expected,reorder -Wno-c99-designator -Werror=reorder -Wno-initializer-overrides<br>
+// RUN: %clang_cc1 -std=c++2a %s -verify=expected,override -Wno-c99-designator -Wno-reorder -Werror=initializer-overrides<br>
+// RUN: %clang_cc1 -std=c++2a %s -verify -Wno-c99-designator -Wno-reorder -Wno-initializer-overrides<br>
+<br>
<br>
 namespace class_with_ctor {<br>
   struct A { // expected-note 6{{candidate}}<br>
@@ -21,3 +26,105 @@ namespace class_with_ctor {<br>
   C c1 = {{}, {}}; // ok, call default ctor twice<br>
   C c2 = {{1, 2}, {3, 4}}; // expected-error 2{{no matching constructor}}<br>
 }<br>
+<br>
+namespace designator {<br>
+struct A { int x, y; };<br>
+struct B { A a; };<br>
+<br>
+A a1 = {<br>
+  .y = 1, // reorder-note {{previous initialization for field 'y' is here}}<br>
+  .x = 2 // reorder-error {{ISO C++ requires field designators to be specified in declaration order; field 'y' will be initialized after field 'x'}}<br>
+};<br>
+int arr[3] = {[1] = 5}; // pedantic-error {{array designators are a C99 extension}}<br>
+B b = {.a.x = 0}; // pedantic-error {{nested designators are a C99 extension}}<br>
+A a2 = {<br>
+  .x = 1, // pedantic-error {{mixture of designated and non-designated initializers in the same initializer list is a C99 extension}}<br>
+  2 // pedantic-note {{first non-designated initializer is here}}<br>
+};<br>
+A a3 = {<br>
+  1, // pedantic-note {{first non-designated initializer is here}}<br>
+  .y = 2 // pedantic-error {{mixture of designated and non-designated initializers in the same initializer list is a C99 extension}}<br>
+};<br>
+A a4 = {<br>
+  .x = 1, // override-note {{previous}}<br>
+  .x = 1 // override-error {{overrides prior initialization}}<br>
+};<br>
+A a5 = {<br>
+  .y = 1, // override-note {{previous}}<br>
+  .y = 1 // override-error {{overrides prior initialization}}<br>
+};<br>
+struct C { int :0, x, :0, y, :0; };<br>
+C c = {<br>
+  .x = 1, // override-note {{previous}}<br>
+  .x = 1, // override-error {{overrides prior initialization}} override-note {{previous}}<br>
+  .y = 1, // override-note {{previous}}<br>
+  .y = 1, // override-error {{overrides prior initialization}}<br>
+  .x = 1, // reorder-error {{declaration order}} override-error {{overrides prior initialization}} override-note {{previous}}<br>
+  .x = 1, // override-error {{overrides prior initialization}}<br>
+};<br>
+}<br>
+<br>
+namespace base_class {<br>
+  struct base {<br>
+    int x;<br>
+  };<br>
+  struct derived : base {<br>
+    int y;<br>
+  };<br>
+  derived d = {.x = 1, .y = 2}; // expected-error {{'x' does not refer to any field}}<br>
+}<br>
+<br>
+namespace union_ {<br>
+  union U { int a, b; };<br>
+  U u = {<br>
+    .a = 1, // override-note {{here}}<br>
+    .b = 2, // override-error {{overrides prior}}<br>
+  };<br>
+}<br>
+<br>
+namespace overload_resolution {<br>
+  struct A { int x, y; };<br>
+  union B { int x, y; };<br>
+<br>
+  void f(A a);<br>
+  void f(B b) = delete;<br>
+  void g() { f({.x = 1, .y = 2}); } // ok, calls non-union overload<br>
+<br>
+  // As an extension of the union case, overload resolution won't pick any<br>
+  // candidate where a field initializer would be overridden.<br>
+  struct A2 { int x, other, y; };<br>
+  int f(A2);<br>
+  void g2() { int k = f({.x = 1, 2, .y = 3}); (void)k; } // pedantic-error {{mixture of designated and non-designated}} pedantic-note {{here}}<br>
+<br>
+  struct C { int x; };<br>
+  void h(A a); // expected-note {{candidate}}<br>
+  void h(C c); // expected-note {{candidate}}<br>
+  void i() {<br>
+    h({.x = 1, .y = 2});<br>
+    h({.y = 1, .x = 2}); // reorder-error {{declaration order}} reorder-note {{previous}}<br>
+    h({.x = 1}); // expected-error {{ambiguous}}<br>
+  }<br>
+<br>
+  struct D { int y, x; };<br>
+  void j(A a); // expected-note {{candidate}}<br>
+  void j(D d); // expected-note {{candidate}}<br>
+  void k() {<br>
+    j({.x = 1, .y = 2}); // expected-error {{ambiguous}}<br>
+  }<br>
+}<br>
+<br>
+namespace deduction {<br>
+  struct A { int x, y; };<br>
+  union B { int x, y; };<br>
+<br>
+  template<typename T, typename U> void f(decltype(T{.x = 1, .y = 2}) = {});<br>
+  template<typename T, typename U> void f(decltype(U{.x = 1, .y = 2}) = {}) = delete;<br>
+  void g() { f<A, B>(); } // ok, calls non-union overload<br>
+<br>
+  struct C { int y, x; };<br>
+  template<typename T, typename U> void h(decltype(T{.y = 1, .x = 2}) = {}) = delete;<br>
+  template<typename T, typename U> void h(decltype(U{.y = 1, .x = 2}) = {});<br>
+  void i() {<br>
+    h<A, C>(); // ok, selects C overload by SFINAE<br>
+  }<br>
+}<br>
<br>
Modified: cfe/trunk/test/SemaCXX/decltype.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/decltype.cpp?rev=370544&r1=370543&r2=370544&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/decltype.cpp?rev=370544&r1=370543&r2=370544&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaCXX/decltype.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/decltype.cpp Fri Aug 30 15:52:55 2019<br>
@@ -1,4 +1,4 @@<br>
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s<br>
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -Wno-c99-designator %s<br>
<br>
 // PR5290<br>
 int const f0();<br>
@@ -80,22 +80,22 @@ namespace D5789 {<br>
   struct P1 { char x[6]; } g1 = { "foo" };<br>
   struct LP1 { struct P1 p1; };<br>
<br>
-  // expected-warning@+3 {{subobject initialization overrides}}<br>
+  // expected-warning@+3 {{initializer partially overrides}}<br>
   // expected-note@+2 {{previous initialization}}<br>
   // expected-note@+1 {{previous definition}}<br>
   template<class T> void foo(decltype(T(LP1{ .p1 = g1, .p1.x[1] = 'x' }))) {}<br>
<br>
-  // expected-warning@+3 {{subobject initialization overrides}}<br>
+  // expected-warning@+3 {{initializer partially overrides}}<br>
   // expected-note@+2 {{previous initialization}}<br>
   template<class T><br>
   void foo(decltype(T(LP1{ .p1 = g1, .p1.x[1] = 'r' }))) {} // okay<br>
<br>
-  // expected-warning@+3 {{subobject initialization overrides}}<br>
+  // expected-warning@+3 {{initializer partially overrides}}<br>
   // expected-note@+2 {{previous initialization}}<br>
   template<class T><br>
   void foo(decltype(T(LP1{ .p1 = { "foo" }, .p1.x[1] = 'x'}))) {} // okay<br>
<br>
-  // expected-warning@+3 {{subobject initialization overrides}}<br>
+  // expected-warning@+3 {{initializer partially overrides}}<br>
   // expected-note@+2 {{previous initialization}}<br>
   // expected-error@+1 {{redefinition of 'foo'}}<br>
   template<class T> void foo(decltype(T(LP1{ .p1 = g1, .p1.x[1] = 'x' }))) {}<br>
<br>
Modified: cfe/trunk/test/SemaCXX/designated-initializers-base-class.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/designated-initializers-base-class.cpp?rev=370544&r1=370543&r2=370544&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/designated-initializers-base-class.cpp?rev=370544&r1=370543&r2=370544&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaCXX/designated-initializers-base-class.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/designated-initializers-base-class.cpp Fri Aug 30 15:52:55 2019<br>
@@ -1,5 +1,4 @@<br>
 // RUN: %clang_cc1 %s -std=c++1z -fsyntax-only -verify -Winitializer-overrides<br>
-// expected-no-diagnostics<br>
<br>
 struct B {<br>
   int x;<br>
@@ -9,4 +8,4 @@ struct D : B {<br>
   int y;<br>
 };<br>
<br>
-void test() { D d = {1, .y = 2}; }<br>
+void test() { D d = {1, .y = 2}; } // expected-warning {{C99 extension}} expected-note {{}}<br>
<br>
Modified: cfe/trunk/test/SemaCXX/designated-initializers.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/designated-initializers.cpp?rev=370544&r1=370543&r2=370544&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/designated-initializers.cpp?rev=370544&r1=370543&r2=370544&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaCXX/designated-initializers.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/designated-initializers.cpp Fri Aug 30 15:52:55 2019<br>
@@ -1,5 +1,5 @@<br>
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -Winitializer-overrides %s<br>
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -Woverride-init %s<br>
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -Wno-reorder -Wno-c99-designator -Winitializer-overrides %s<br>
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -Wno-reorder -Wno-c99-designator -Woverride-init %s<br>
<br>
 template <typename T> struct Foo {<br>
   struct SubFoo {<br>
<br>
Modified: cfe/trunk/test/SemaCXX/eval-crashes.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/eval-crashes.cpp?rev=370544&r1=370543&r2=370544&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/eval-crashes.cpp?rev=370544&r1=370543&r2=370544&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaCXX/eval-crashes.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/eval-crashes.cpp Fri Aug 30 15:52:55 2019<br>
@@ -37,7 +37,7 @@ namespace pr33140_3 {<br>
   struct X {<br>
     Y_t a;<br>
   };<br>
-  struct X foo[2] = {[0 ... 1] = {.a = (Y_t){.c = 0}}};<br>
+  struct X foo[2] = {[0 ... 1] = {.a = (Y_t){.c = 0}}}; // expected-warning {{C99 extension}}<br>
 }<br>
<br>
 namespace pr33140_6 {<br>
<br>
Modified: cfe/trunk/test/SemaCXX/member-init.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/member-init.cpp?rev=370544&r1=370543&r2=370544&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/member-init.cpp?rev=370544&r1=370543&r2=370544&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaCXX/member-init.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/member-init.cpp Fri Aug 30 15:52:55 2019<br>
@@ -184,7 +184,7 @@ void g() { f<int>(); } // expected-note<br>
 namespace PR22056 {<br>
 template <int N><br>
 struct S {<br>
-  int x[3] = {[N] = 3};<br>
+  int x[3] = {[N] = 3}; // expected-warning {{C99 extension}}<br>
 };<br>
 }<br>
<br>
<br>
Modified: cfe/trunk/test/SemaObjCXX/<a href="http://message.mm" rel="noreferrer" target="_blank">message.mm</a><br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/message.mm?rev=370544&r1=370543&r2=370544&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/message.mm?rev=370544&r1=370543&r2=370544&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaObjCXX/<a href="http://message.mm" rel="noreferrer" target="_blank">message.mm</a> (original)<br>
+++ cfe/trunk/test/SemaObjCXX/<a href="http://message.mm" rel="noreferrer" target="_blank">message.mm</a> Fri Aug 30 15:52:55 2019<br>
@@ -84,7 +84,7 @@ struct identity {<br>
 #if __cplusplus <= 199711L<br>
   // expected-warning@-2 {{'typename' occurs outside of a template}}<br>
 #endif<br>
-  int array[5] = {[3] = 2};<br>
+  int array[5] = {[3] = 2}; // expected-warning {{C99 extension}}<br>
   return [super method];<br>
 }<br>
 @end<br>
<br>
Modified: cfe/trunk/test/SemaTemplate/instantiate-c99.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-c99.cpp?rev=370544&r1=370543&r2=370544&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-c99.cpp?rev=370544&r1=370543&r2=370544&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaTemplate/instantiate-c99.cpp (original)<br>
+++ cfe/trunk/test/SemaTemplate/instantiate-c99.cpp Fri Aug 30 15:52:55 2019<br>
@@ -1,6 +1,6 @@<br>
-// RUN: %clang_cc1 -fsyntax-only -verify %s<br>
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s<br>
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s<br>
+// RUN: %clang_cc1 -Wno-c99-extensions -Wno-reorder -fsyntax-only -verify %s<br>
+// RUN: %clang_cc1 -Wno-c99-extensions -Wno-reorder -fsyntax-only -verify -std=c++98 %s<br>
+// RUN: %clang_cc1 -Wno-c99-extensions -Wno-reorder -fsyntax-only -verify -std=c++11 %s<br>
<br>
 // Test template instantiation for C99-specific features.<br>
<br>
<br>
Modified: cfe/trunk/test/SemaTemplate/instantiate-init.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-init.cpp?rev=370544&r1=370543&r2=370544&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-init.cpp?rev=370544&r1=370543&r2=370544&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaTemplate/instantiate-init.cpp (original)<br>
+++ cfe/trunk/test/SemaTemplate/instantiate-init.cpp Fri Aug 30 15:52:55 2019<br>
@@ -151,8 +151,8 @@ namespace InitListUpdate {<br>
<br>
   // Check that an init list update doesn't "lose" the pack-ness of an expression.<br>
   template <int... N> void f() {<br>
-    g(AA{0, [0].n = N} ...); // expected-warning 3{{overrides prior init}} expected-note 3{{previous init}}<br>
-    g(AA{N, [0].n = 0} ...); // expected-warning 3{{overrides prior init}} expected-note 3{{previous init}}<br>
+    g(AA{0, [0].n = N} ...); // expected-warning 3{{extension}} expected-note {{here}} expected-warning 3{{overrides prior init}} expected-note 3{{previous init}}<br>
+    g(AA{N, [0].n = 0} ...); // expected-warning 3{{extension}} expected-note {{here}} expected-warning 3{{overrides prior init}} expected-note 3{{previous init}}<br>
   };<br>
<br>
   void g(AA, AA);<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote></div>