mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-22 15:31:00 +00:00
[Sema][SVE] Fix handling of initialisers for built-in SVE types
The built-in SVE types are supposed to be treated as opaque types. This means that for initialisation purposes they should be treated as a single unit, much like a scalar type. However, as Eli pointed out, actually using "scalar" in the diagnostics is likely to cause confusion, given the types are logically vectors. The patch therefore uses custom diagnostics or generalises existing ones. Some of the messages use the word "indivisible" to try to make it clear(er) that these types can't be initialised elementwise. I don't think it's possible to trigger warn_braces_around_(scalar_)init for sizeless types as things stand, since the types can't be used as members or elements of more complex types. But it seemed better to be consistent with ext_many_braces_around_(scalar_)init, so the patch changes it anyway. Differential Revision: https://reviews.llvm.org/D76689
This commit is contained in:
parent
9b509bca85
commit
69ab8b46b8
@ -1032,9 +1032,13 @@ This diagnostic is enabled by default.
|
||||
|
||||
**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 @@ Also controls `-Wc++98-c++11-c++14-c++17-compat`_, `-Wc++98-c++11-c++14-compat`_
|
||||
|: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 @@ This diagnostic is enabled by default.
|
||||
| |+------------------+| |
|
||||
+-----------------------------------------------------------------+--------------------+-------------------------------+
|
||||
|
||||
+---------------------------------------------------------------------------------------------------------------------------+
|
||||
|: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 @@ This diagnostic is enabled by default.
|
||||
|
||||
**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
|
||||
|
@ -171,8 +171,9 @@ def err_field_designator_unknown : Error<
|
||||
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<InitializerOverrides>;
|
||||
@ -5398,6 +5399,11 @@ def err_excess_initializers : Error<
|
||||
def ext_excess_initializers : ExtWarn<
|
||||
"excess elements in %select{array|vector|scalar|union|struct}0 initializer">,
|
||||
InGroup<ExcessInitializers>;
|
||||
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<ExcessInitializers>;
|
||||
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 ext_initializer_string_for_char_array_too_long : ExtWarn<
|
||||
def warn_missing_field_initializers : Warning<
|
||||
"missing field %0 initializer">,
|
||||
InGroup<MissingFieldInitializers>, DefaultIgnore;
|
||||
def warn_braces_around_scalar_init : Warning<
|
||||
"braces around scalar initializer">, InGroup<DiagGroup<"braced-scalar-init">>;
|
||||
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<DiagGroup<"braced-scalar-init">>;
|
||||
def ext_many_braces_around_init : ExtWarn<
|
||||
"too many braces around %select{scalar |}0initializer">,
|
||||
InGroup<DiagGroup<"many-braces-around-scalar-init">>, SFINAEFailure;
|
||||
def ext_complex_component_init : Extension<
|
||||
"complex initialization specifying real and imaginary components "
|
||||
"is an extension">, InGroup<DiagGroup<"complex-component-init">>;
|
||||
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<CXX98Compat>, DefaultIgnore;
|
||||
def warn_cxx98_compat_empty_sizeless_initializer : Warning<
|
||||
"initializing %0 from an empty initializer list is incompatible with C++98">,
|
||||
InGroup<CXX98Compat>, DefaultIgnore;
|
||||
def warn_cxx98_compat_reference_list_init : Warning<
|
||||
"reference initialized from initializer list is incompatible with C++98">,
|
||||
InGroup<CXX98Compat>, DefaultIgnore;
|
||||
|
@ -1119,14 +1119,14 @@ static void warnBracedScalarInit(Sema &S, const InitializedEntity &Entity,
|
||||
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 @@ static void warnBracedScalarInit(Sema &S, const InitializedEntity &Entity,
|
||||
|
||||
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 @@ void InitListChecker::CheckExplicitInitList(const InitializedEntity &Entity,
|
||||
: 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 @@ void InitListChecker::CheckListElementTypes(const InitializedEntity &Entity,
|
||||
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 @@ void InitListChecker::CheckScalarType(const InitializedEntity &Entity,
|
||||
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 @@ void InitListChecker::CheckScalarType(const InitializedEntity &Entity,
|
||||
// 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<DesignatedInitExpr>(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;
|
||||
|
@ -83,6 +83,14 @@ void func(int sel) {
|
||||
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;
|
||||
|
@ -94,9 +94,18 @@ void func(int sel) {
|
||||
|
||||
#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 @@ void cxx_only(int sel) {
|
||||
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>()};
|
||||
svint8_t &ref_init_int8{local_int8};
|
||||
|
||||
@ -601,4 +618,9 @@ void cxx_only(int sel) {
|
||||
|
||||
#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
|
||||
|
Loading…
Reference in New Issue
Block a user