r370544 - [c++20] Implement semantic restrictions for C++20 designated
Nico Weber via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 2 09:02:52 PDT 2019
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
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190902/920b8d59/attachment-0001.html>
More information about the cfe-commits
mailing list