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