diff --git a/clang/docs/DiagnosticsReference.rst b/clang/docs/DiagnosticsReference.rst --- a/clang/docs/DiagnosticsReference.rst +++ b/clang/docs/DiagnosticsReference.rst @@ -1032,9 +1032,13 @@ **Diagnostic text:** -+-----------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`braces around scalar initializer`| -+-----------------------------------------------------------------------+ ++------------------------------------------------------------+----------------------------+-----------------------+ +|:warning:`warning:` |nbsp| :diagtext:`braces around` |nbsp| |+--------------------------+|:diagtext:`initializer`| +| ||:diagtext:`scalar` |nbsp| || | +| |+--------------------------+| | +| || || | +| |+--------------------------+| | ++------------------------------------------------------------+----------------------------+-----------------------+ -Wbridge-cast @@ -2151,6 +2155,10 @@ |:warning:`warning:` |nbsp| :diagtext:`scalar initialized from empty initializer list is incompatible with C++98`| +----------------------------------------------------------------------------------------------------------------+ ++--------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`initializing` |nbsp| :placeholder:`A` |nbsp| :diagtext:`from an empty initializer list is incompatible with C++98`| ++--------------------------------------------------------------------------------------------------------------------------------------------------------+ + +-----------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`enumeration types with a fixed underlying type are incompatible with C++98`| +-----------------------------------------------------------------------------------------------------------------+ @@ -4501,6 +4509,10 @@ | |+------------------+| | +-----------------------------------------------------------------+--------------------+-------------------------------+ ++---------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`excess elements in initializer for indivisible sizeless type` |nbsp| :placeholder:`A`| ++---------------------------------------------------------------------------------------------------------------------------+ + +--------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`excess elements in char array initializer`| +--------------------------------------------------------------------------------+ @@ -7429,9 +7441,13 @@ **Diagnostic text:** -+--------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`too many braces around scalar initializer`| -+--------------------------------------------------------------------------------+ ++---------------------------------------------------------------------+----------------------------+-----------------------+ +|:warning:`warning:` |nbsp| :diagtext:`too many braces around` |nbsp| |+--------------------------+|:diagtext:`initializer`| +| ||:diagtext:`scalar` |nbsp| || | +| |+--------------------------+| | +| || || | +| |+--------------------------+| | ++---------------------------------------------------------------------+----------------------------+-----------------------+ -Wmax-tokens diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -171,8 +171,9 @@ def err_field_designator_nonfield : Error< "field designator %0 does not refer to a non-static data member">; 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 err_designator_for_scalar_or_sizeless_init : Error< + "designator in initializer for %select{scalar|indivisible sizeless}0 " + "type %1">; def warn_initializer_overrides : Warning< "initializer %select{partially |}0overrides prior initialization of " "this subobject">, InGroup; @@ -5398,6 +5399,11 @@ def ext_excess_initializers : ExtWarn< "excess elements in %select{array|vector|scalar|union|struct}0 initializer">, InGroup; +def err_excess_initializers_for_sizeless_type : Error< + "excess elements in initializer for indivisible sizeless type %0">; +def ext_excess_initializers_for_sizeless_type : ExtWarn< + "excess elements in initializer for indivisible sizeless type %0">, + InGroup; def err_excess_initializers_in_char_array_initializer : Error< "excess elements in char array initializer">; def ext_excess_initializers_in_char_array_initializer : ExtWarn< @@ -5411,18 +5417,24 @@ def warn_missing_field_initializers : Warning< "missing field %0 initializer">, InGroup, DefaultIgnore; -def warn_braces_around_scalar_init : Warning< - "braces around scalar initializer">, InGroup>; -def ext_many_braces_around_scalar_init : ExtWarn< - "too many braces around scalar initializer">, +def warn_braces_around_init : Warning< + "braces around %select{scalar |}0initializer">, + InGroup>; +def ext_many_braces_around_init : ExtWarn< + "too many braces around %select{scalar |}0initializer">, InGroup>, SFINAEFailure; def ext_complex_component_init : Extension< "complex initialization specifying real and imaginary components " "is an extension">, InGroup>; def err_empty_scalar_initializer : Error<"scalar initializer cannot be empty">; +def err_empty_sizeless_initializer : Error< + "initializer for sizeless type %0 cannot be empty">; def warn_cxx98_compat_empty_scalar_initializer : Warning< "scalar initialized from empty initializer list is incompatible with C++98">, InGroup, DefaultIgnore; +def warn_cxx98_compat_empty_sizeless_initializer : Warning< + "initializing %0 from an empty initializer list is incompatible with C++98">, + InGroup, DefaultIgnore; def warn_cxx98_compat_reference_list_init : Warning< "reference initialized from initializer list is incompatible with C++98">, InGroup, DefaultIgnore; diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -1119,14 +1119,14 @@ case InitializedEntity::EK_Parameter_CF_Audited: case InitializedEntity::EK_Result: // Extra braces here are suspicious. - DiagID = diag::warn_braces_around_scalar_init; + DiagID = diag::warn_braces_around_init; break; case InitializedEntity::EK_Member: // Warn on aggregate initialization but not on ctor init list or // default member initializer. if (Entity.getParent()) - DiagID = diag::warn_braces_around_scalar_init; + DiagID = diag::warn_braces_around_init; break; case InitializedEntity::EK_Variable: @@ -1157,9 +1157,9 @@ if (DiagID) { S.Diag(Braces.getBegin(), DiagID) - << Braces - << FixItHint::CreateRemoval(Braces.getBegin()) - << FixItHint::CreateRemoval(Braces.getEnd()); + << Entity.getType()->isSizelessBuiltinType() << Braces + << FixItHint::CreateRemoval(Braces.getBegin()) + << FixItHint::CreateRemoval(Braces.getEnd()); } } @@ -1203,6 +1203,12 @@ : diag::ext_excess_initializers_in_char_array_initializer; SemaRef.Diag(IList->getInit(Index)->getBeginLoc(), DK) << IList->getInit(Index)->getSourceRange(); + } else if (T->isSizelessBuiltinType()) { + unsigned DK = ExtraInitsIsError + ? diag::err_excess_initializers_for_sizeless_type + : diag::ext_excess_initializers_for_sizeless_type; + SemaRef.Diag(IList->getInit(Index)->getBeginLoc(), DK) + << T << IList->getInit(Index)->getSourceRange(); } else { int initKind = T->isArrayType() ? 0 : T->isVectorType() ? 1 : @@ -1295,7 +1301,8 @@ if (!VerifyOnly) SemaRef.Diag(IList->getBeginLoc(), diag::err_init_objc_class) << DeclType; hadError = true; - } else if (DeclType->isOCLIntelSubgroupAVCType()) { + } else if (DeclType->isOCLIntelSubgroupAVCType() || + DeclType->isSizelessBuiltinType()) { // Checks for scalar type are sufficient for these types too. CheckScalarType(Entity, IList, DeclType, Index, StructuredList, StructuredIndex); @@ -1508,12 +1515,20 @@ InitListExpr *StructuredList, unsigned &StructuredIndex) { if (Index >= IList->getNumInits()) { - if (!VerifyOnly) - SemaRef.Diag(IList->getBeginLoc(), - SemaRef.getLangOpts().CPlusPlus11 - ? diag::warn_cxx98_compat_empty_scalar_initializer - : diag::err_empty_scalar_initializer) - << IList->getSourceRange(); + if (!VerifyOnly) { + if (DeclType->isSizelessBuiltinType()) + SemaRef.Diag(IList->getBeginLoc(), + SemaRef.getLangOpts().CPlusPlus11 + ? diag::warn_cxx98_compat_empty_sizeless_initializer + : diag::err_empty_sizeless_initializer) + << DeclType << IList->getSourceRange(); + else + SemaRef.Diag(IList->getBeginLoc(), + SemaRef.getLangOpts().CPlusPlus11 + ? diag::warn_cxx98_compat_empty_scalar_initializer + : diag::err_empty_scalar_initializer) + << IList->getSourceRange(); + } hadError = !SemaRef.getLangOpts().CPlusPlus11; ++Index; ++StructuredIndex; @@ -1525,17 +1540,18 @@ // FIXME: This is invalid, and accepting it causes overload resolution // to pick the wrong overload in some corner cases. if (!VerifyOnly) - SemaRef.Diag(SubIList->getBeginLoc(), - diag::ext_many_braces_around_scalar_init) - << SubIList->getSourceRange(); + SemaRef.Diag(SubIList->getBeginLoc(), diag::ext_many_braces_around_init) + << DeclType->isSizelessBuiltinType() << SubIList->getSourceRange(); CheckScalarType(Entity, SubIList, DeclType, Index, StructuredList, StructuredIndex); return; } else if (isa(expr)) { if (!VerifyOnly) - SemaRef.Diag(expr->getBeginLoc(), diag::err_designator_for_scalar_init) - << DeclType << expr->getSourceRange(); + SemaRef.Diag(expr->getBeginLoc(), + diag::err_designator_for_scalar_or_sizeless_init) + << DeclType->isSizelessBuiltinType() << DeclType + << expr->getSourceRange(); hadError = true; ++Index; ++StructuredIndex; diff --git a/clang/test/Sema/sizeless-1.c b/clang/test/Sema/sizeless-1.c --- a/clang/test/Sema/sizeless-1.c +++ b/clang/test/Sema/sizeless-1.c @@ -83,6 +83,14 @@ svint8_t bad_init_int8 = for; // expected-error {{expected expression}} int empty_brace_init_int = {}; // expected-error {{scalar initializer cannot be empty}} + svint8_t empty_brace_init_int8 = {}; // expected-error {{initializer for sizeless type 'svint8_t' (aka '__SVInt8_t') cannot be empty}} + svint8_t brace_init_int8 = {local_int8}; + svint8_t bad_brace_init_int8_1 = {local_int8, 0}; // expected-warning {{excess elements in initializer for indivisible sizeless type 'svint8_t'}} + svint8_t bad_brace_init_int8_2 = {0}; // expected-error {{incompatible type 'int'}} + svint8_t bad_brace_init_int8_3 = {local_int16}; // expected-error {{incompatible type 'svint16_t'}} + svint8_t bad_brace_init_int8_4 = {[0] = local_int8}; // expected-error {{designator in initializer for indivisible sizeless type 'svint8_t'}} + svint8_t bad_brace_init_int8_5 = {{local_int8}}; // expected-warning {{too many braces around initializer}} + svint8_t bad_brace_init_int8_6 = {{local_int8, 0}}; // expected-warning {{too many braces around initializer}} const svint8_t const_int8 = local_int8; // expected-note {{declared const here}} const svint8_t uninit_const_int8; diff --git a/clang/test/SemaCXX/sizeless-1.cpp b/clang/test/SemaCXX/sizeless-1.cpp --- a/clang/test/SemaCXX/sizeless-1.cpp +++ b/clang/test/SemaCXX/sizeless-1.cpp @@ -94,9 +94,18 @@ #if __cplusplus >= 201103L int empty_brace_init_int = {}; + svint8_t empty_brace_init_int8 = {}; #else int empty_brace_init_int = {}; // expected-error {{scalar initializer cannot be empty}} + svint8_t empty_brace_init_int8 = {}; // expected-error {{initializer for sizeless type 'svint8_t' (aka '__SVInt8_t') cannot be empty}} #endif + svint8_t brace_init_int8 = {local_int8}; + svint8_t bad_brace_init_int8_1 = {local_int8, 0}; // expected-error {{excess elements in initializer for indivisible sizeless type 'svint8_t'}} + svint8_t bad_brace_init_int8_2 = {0}; // expected-error {{rvalue of type 'int'}} + svint8_t bad_brace_init_int8_3 = {local_int16}; // expected-error {{lvalue of type 'svint16_t'}} + svint8_t bad_brace_init_int8_4 = {[0] = local_int8}; // expected-error {{designator in initializer for indivisible sizeless type 'svint8_t'}} expected-warning {{array designators are a C99 extension}} + svint8_t bad_brace_init_int8_5 = {{local_int8}}; // expected-warning {{too many braces around initializer}} + svint8_t bad_brace_init_int8_6 = {{local_int8, 0}}; // expected-warning {{too many braces around initializer}} const svint8_t const_int8 = local_int8; // expected-note {{declared const here}} const svint8_t uninit_const_int8; // expected-error {{default initialization of an object of const type 'const svint8_t'}} @@ -455,6 +464,14 @@ local_int8 = ref_int8; #if __cplusplus >= 201103L + svint8_t zero_init_int8{}; + svint8_t init_int8{local_int8}; + svint8_t bad_brace_init_int8_1{local_int8, 0}; // expected-error {{excess elements in initializer for indivisible sizeless type 'svint8_t'}} + svint8_t bad_brace_init_int8_2{0}; // expected-error {{rvalue of type 'int'}} + svint8_t bad_brace_init_int8_3{local_int16}; // expected-error {{lvalue of type 'svint16_t'}} + svint8_t bad_brace_init_int8_4{[0] = local_int8}; // expected-error {{designator in initializer for indivisible sizeless type 'svint8_t'}} expected-warning {{array designators are a C99 extension}} + svint8_t bad_brace_init_int8_5{{local_int8}}; // expected-warning {{too many braces around initializer}} + svint8_t bad_brace_init_int8_6{{local_int8, 0}}; // expected-warning {{too many braces around initializer}} svint8_t wrapper_init_int8{wrapper()}; svint8_t &ref_init_int8{local_int8}; @@ -601,4 +618,9 @@ #if __cplusplus >= 201103L svint8_t ret_bad_conv() { return explicit_conv(); } // expected-error {{no viable conversion from returned value of type 'explicit_conv' to function return type 'svint8_t'}} + +#pragma clang diagnostic warning "-Wc++98-compat" + +void incompat_init() { __attribute__((unused)) svint8_t foo = {}; } // expected-warning {{initializing 'svint8_t' (aka '__SVInt8_t') from an empty initializer list is incompatible with C++98}} + #endif