[clang] b50d80c - [Sema][SVE] Don't allow fields to have sizeless type
Richard Sandiford via cfe-commits
cfe-commits at lists.llvm.org
Fri Mar 13 12:23:18 PDT 2020
Author: Richard Sandiford
Date: 2020-03-13T19:22:23Z
New Revision: b50d80c1ee1fc154c906f59a2ebedab2f85bacca
URL: https://github.com/llvm/llvm-project/commit/b50d80c1ee1fc154c906f59a2ebedab2f85bacca
DIFF: https://github.com/llvm/llvm-project/commit/b50d80c1ee1fc154c906f59a2ebedab2f85bacca.diff
LOG: [Sema][SVE] Don't allow fields to have sizeless type
The SVE ACLE doesn't allow fields to have sizeless type. At the moment
clang accepts things like:
struct s { __SVInt8_t x; } y;
but trying to code-generate it leads to LLVM asserts like:
llvm/include/llvm/Support/TypeSize.h:126: uint64_t llvm::TypeSize::getFixedSize() const: Assertion `!IsScalable && "Request for a fixed size on a scalable object"' failed.
This patch adds an associated clang diagnostic.
Differential Revision: https://reviews.llvm.org/D75737
Added:
Modified:
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaLambda.cpp
clang/test/Sema/sizeless-1.c
clang/test/SemaCXX/sizeless-1.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 52bc4077bbc2..4966942e37e7 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -5602,7 +5602,8 @@ def err_func_returning_qualified_void : ExtWarn<
def err_func_returning_array_function : Error<
"function cannot return %select{array|function}0 type %1">;
def err_field_declared_as_function : Error<"field %0 declared as a function">;
-def err_field_incomplete : Error<"field has incomplete type %0">;
+def err_field_incomplete_or_sizeless : Error<
+ "field has %select{incomplete|sizeless}0 type %1">;
def ext_variable_sized_type_in_struct : ExtWarn<
"field %0 with variable sized type %1 not at the end of a struct or class is"
" a GNU extension">, InGroup<GNUVariableSizedTypeNotAtEnd>;
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index d31e2747f65c..4ffac5eb5c70 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -5247,8 +5247,8 @@ Decl *Sema::BuildMicrosoftCAnonymousStruct(Scope *S, DeclSpec &DS,
Chain.push_back(Anon);
RecordDecl *RecordDef = Record->getDefinition();
- if (RequireCompleteType(Anon->getLocation(), RecTy,
- diag::err_field_incomplete) ||
+ if (RequireCompleteSizedType(Anon->getLocation(), RecTy,
+ diag::err_field_incomplete_or_sizeless) ||
InjectAnonymousStructOrUnionMembers(*this, S, CurContext, RecordDef,
AS_none, Chain)) {
Anon->setInvalidDecl();
@@ -16103,8 +16103,9 @@ ExprResult Sema::VerifyBitField(SourceLocation FieldLoc,
// C99 6.7.2.1p4 - verify the field type.
// C++ 9.6p3: A bit-field shall have integral or enumeration type.
if (!FieldTy->isDependentType() && !FieldTy->isIntegralOrEnumerationType()) {
- // Handle incomplete types with specific error.
- if (RequireCompleteType(FieldLoc, FieldTy, diag::err_field_incomplete))
+ // Handle incomplete and sizeless types with a specific error.
+ if (RequireCompleteSizedType(FieldLoc, FieldTy,
+ diag::err_field_incomplete_or_sizeless))
return ExprError();
if (FieldName)
return Diag(FieldLoc, diag::err_not_integral_type_bitfield)
@@ -16321,7 +16322,8 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
QualType EltTy = Context.getBaseElementType(T);
if (!EltTy->isDependentType()) {
- if (RequireCompleteType(Loc, EltTy, diag::err_field_incomplete)) {
+ if (RequireCompleteSizedType(Loc, EltTy,
+ diag::err_field_incomplete_or_sizeless)) {
// Fields of incomplete type force their record to be invalid.
Record->setInvalidDecl();
InvalidDecl = true;
@@ -16865,8 +16867,9 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
// elsewhere, after synthesized ivars are known.
}
} else if (!FDTy->isDependentType() &&
- RequireCompleteType(FD->getLocation(), FD->getType(),
- diag::err_field_incomplete)) {
+ RequireCompleteSizedType(
+ FD->getLocation(), FD->getType(),
+ diag::err_field_incomplete_or_sizeless)) {
// Incomplete type
FD->setInvalidDecl();
EnclosingDecl->setInvalidDecl();
@@ -16924,8 +16927,8 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
Context, "", UnavailableAttr::IR_ARCFieldWithOwnership,
FD->getLocation()));
} else if (getLangOpts().ObjC &&
- getLangOpts().getGC() != LangOptions::NonGC &&
- Record && !Record->hasObjectMember()) {
+ getLangOpts().getGC() != LangOptions::NonGC && Record &&
+ !Record->hasObjectMember()) {
if (FD->getType()->isObjCObjectPointerType() ||
FD->getType().isObjCGCStrong())
Record->setHasObjectMember(true);
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index 51f643e6431e..ab4f3491b90b 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -1629,7 +1629,8 @@ FieldDecl *Sema::BuildCaptureField(RecordDecl *RD,
// If the variable being captured has an invalid type, mark the class as
// invalid as well.
if (!FieldType->isDependentType()) {
- if (RequireCompleteType(Loc, FieldType, diag::err_field_incomplete)) {
+ if (RequireCompleteSizedType(Loc, FieldType,
+ diag::err_field_incomplete_or_sizeless)) {
RD->setInvalidDecl();
Field->setInvalidDecl();
} else {
diff --git a/clang/test/Sema/sizeless-1.c b/clang/test/Sema/sizeless-1.c
index f1f562938dbd..06ced5656dcb 100644
--- a/clang/test/Sema/sizeless-1.c
+++ b/clang/test/Sema/sizeless-1.c
@@ -230,6 +230,20 @@ int vararg_receiver(int count, svint8_t first, ...) {
return count;
}
+struct sized_struct {
+ int f1;
+ svint8_t f2; // expected-error {{field has sizeless type 'svint8_t'}}
+ svint8_t f3 : 2; // expected-error {{field has sizeless type 'svint8_t'}}
+ svint8_t : 3; // expected-error {{field has sizeless type 'svint8_t'}}
+};
+
+union sized_union {
+ int f1;
+ svint8_t f2; // expected-error {{field has sizeless type 'svint8_t'}}
+ svint8_t f3 : 2; // expected-error {{field has sizeless type 'svint8_t'}}
+ svint8_t : 3; // expected-error {{field has sizeless type 'svint8_t'}}
+};
+
#if __STDC_VERSION__ >= 201112L
void test_generic(void) {
svint8_t local_int8;
diff --git a/clang/test/SemaCXX/sizeless-1.cpp b/clang/test/SemaCXX/sizeless-1.cpp
index 11cc629620d6..48453f594f18 100644
--- a/clang/test/SemaCXX/sizeless-1.cpp
+++ b/clang/test/SemaCXX/sizeless-1.cpp
@@ -249,6 +249,20 @@ int vararg_receiver(int count, svint8_t first, ...) {
return count;
}
+struct sized_struct {
+ int f1;
+ svint8_t f2; // expected-error {{field has sizeless type 'svint8_t'}}
+ svint8_t f3 : 2; // expected-error {{field has sizeless type 'svint8_t'}}
+ svint8_t : 3; // expected-error {{field has sizeless type 'svint8_t'}}
+};
+
+union sized_union {
+ int f1;
+ svint8_t f2; // expected-error {{field has sizeless type 'svint8_t'}}
+ svint8_t f3 : 2; // expected-error {{field has sizeless type 'svint8_t'}}
+ svint8_t : 3; // expected-error {{field has sizeless type 'svint8_t'}}
+};
+
void pass_int8_ref(svint8_t &); // expected-note {{not viable}}
svint8_t &return_int8_ref();
@@ -256,6 +270,11 @@ svint8_t &return_int8_ref();
svint8_t &&return_int8_rvalue_ref();
#endif
+template <typename T>
+struct s_template {
+ T y; // expected-error {{field has sizeless type '__SVInt8_t'}}
+};
+
template <typename T>
struct s_ptr_template {
s_ptr_template();
@@ -344,6 +363,9 @@ void cxx_only(int sel) {
local_int8 = svint8_t();
local_int8 = svint16_t(); // expected-error {{assigning to 'svint8_t' (aka '__SVInt8_t') from incompatible type 'svint16_t'}}
+ s_template<int> st_int;
+ s_template<svint8_t> st_svint8; // expected-note {{in instantiation}}
+
s_ptr_template<int> st_ptr_int;
s_ptr_template<svint8_t> st_ptr_svint8;
@@ -474,6 +496,9 @@ void cxx_only(int sel) {
local_int8 = ([]() -> svint8_t { return svint8_t(); })();
auto fn1 = [&local_int8](svint8_t x) { local_int8 = x; };
auto fn2 = [&local_int8](svint8_t *ptr) { *ptr = local_int8; };
+#if __cplusplus >= 201703L
+ auto fn3 = [a(return_int8())] {}; // expected-error {{field has sizeless type '__SVInt8_t'}}
+#endif
for (auto x : local_int8) { // expected-error {{no viable 'begin' function available}}
}
More information about the cfe-commits
mailing list