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}} } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits