From: Richard Sandiford Date: Thu, 27 Feb 2020 10:25:31 +0000 (+0000) Subject: [Sema][SVE] Reject arrays of sizeless types X-Git-Tag: llvmorg-12-init~12129 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=994c071a1b7eee8de132d78286c730da2be2c48f;p=platform%2Fupstream%2Fllvm.git [Sema][SVE] Reject arrays of sizeless types The SVE ACLE doesn't allow arrays of sizeless types. At the moment clang accepts the TU: __SVInt8_t x[2]; but trying to code-generate it triggers the LLVM assertion: llvm/lib/IR/Type.cpp:588: static llvm::ArrayType* llvm::ArrayType::get(llvm::Type*, uint64_t): Assertion `isValidElementType(ElementType) && "Invalid type for array element!"' failed. This patch reports an appropriate error instead. The rules are slightly more restrictive than for general incomplete types. For example: struct s; typedef struct s arr[2]; is valid as far as it goes, whereas arrays of sizeless types are invalid in all contexts. BuildArrayType therefore needs a specific check for isSizelessType in addition to the usual handling of incomplete types. Differential Revision: https://reviews.llvm.org/D76082 --- diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 936edf2..4328e32 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -5895,8 +5895,8 @@ def err_flexible_array_init_needs_braces : Error< "flexible array requires brace-enclosed initializer">; def err_illegal_decl_array_of_functions : Error< "'%0' declared as array of functions of type %1">; -def err_illegal_decl_array_incomplete_type : Error< - "array has incomplete element type %0">; +def err_array_incomplete_or_sizeless_type : Error< + "array has %select{incomplete|sizeless}0 element type %1">; def err_illegal_message_expr_incomplete_type : Error< "Objective-C message has incomplete result type %0">; def err_illegal_decl_array_of_references : Error< diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 4ffac5e..a61ddbd 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -12385,9 +12385,9 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) { if (!Var->isInvalidDecl()) { if (const IncompleteArrayType *ArrayT = Context.getAsIncompleteArrayType(Type)) { - if (RequireCompleteType(Var->getLocation(), - ArrayT->getElementType(), - diag::err_illegal_decl_array_incomplete_type)) + if (RequireCompleteSizedType( + Var->getLocation(), ArrayT->getElementType(), + diag::err_array_incomplete_or_sizeless_type)) Var->setInvalidDecl(); } else if (Var->getStorageClass() == SC_Static) { // C99 6.9.2p3: If the declaration of an identifier for an object is diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index eaf22fe..9ab6a16 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -6175,10 +6175,10 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo, QualType literalType = TInfo->getType(); if (literalType->isArrayType()) { - if (RequireCompleteType(LParenLoc, Context.getBaseElementType(literalType), - diag::err_illegal_decl_array_incomplete_type, - SourceRange(LParenLoc, - LiteralExpr->getSourceRange().getEnd()))) + if (RequireCompleteSizedType( + LParenLoc, Context.getBaseElementType(literalType), + diag::err_array_incomplete_or_sizeless_type, + SourceRange(LParenLoc, LiteralExpr->getSourceRange().getEnd()))) return ExprError(); if (literalType->isVariableArrayType()) return ExprError(Diag(LParenLoc, diag::err_variable_object_no_init) diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 7f555ec..5341783 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -2214,7 +2214,7 @@ QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM, } if (T->isVoidType() || T->isIncompleteArrayType()) { - Diag(Loc, diag::err_illegal_decl_array_incomplete_type) << T; + Diag(Loc, diag::err_array_incomplete_or_sizeless_type) << 0 << T; return QualType(); } @@ -2232,11 +2232,16 @@ QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM, } else { // C99 6.7.5.2p1: If the element type is an incomplete or function type, // reject it (e.g. void ary[7], struct foo ary[7], void ary[7]()) - if (RequireCompleteType(Loc, T, - diag::err_illegal_decl_array_incomplete_type)) + if (RequireCompleteSizedType(Loc, T, + diag::err_array_incomplete_or_sizeless_type)) return QualType(); } + if (T->isSizelessType()) { + Diag(Loc, diag::err_array_incomplete_or_sizeless_type) << 1 << T; + return QualType(); + } + if (T->isFunctionType()) { Diag(Loc, diag::err_illegal_decl_array_of_functions) << getPrintableNameForEntity(Entity) << T; diff --git a/clang/test/Sema/sizeless-1.c b/clang/test/Sema/sizeless-1.c index 06ced56..962595b 100644 --- a/clang/test/Sema/sizeless-1.c +++ b/clang/test/Sema/sizeless-1.c @@ -51,6 +51,8 @@ void unused() { struct incomplete_struct *incomplete_ptr; +typedef svint8_t sizeless_array[1]; // expected-error {{array has sizeless element type}} + void func(int sel) { static svint8_t static_int8; // expected-error {{non-local variable with sizeless type 'svint8_t'}} @@ -93,6 +95,9 @@ void func(int sel) { _Atomic svint8_t atomic_int8; // expected-error {{_Atomic cannot be applied to sizeless type 'svint8_t'}} __restrict svint8_t restrict_int8; // expected-error {{requires a pointer or reference}} + svint8_t array_int8[1]; // expected-error {{array has sizeless element type}} + svint8_t array_int8_init[] = {}; // expected-error {{array has sizeless element type}} + _Bool test_int8 = init_int8; // expected-error {{initializing '_Bool' with an expression of incompatible type 'svint8_t'}} int int_int8 = init_int8; // expected-error {{initializing 'int' with an expression of incompatible type 'svint8_t'}} diff --git a/clang/test/SemaCXX/sizeless-1.cpp b/clang/test/SemaCXX/sizeless-1.cpp index f776c47..8b6c00f 100644 --- a/clang/test/SemaCXX/sizeless-1.cpp +++ b/clang/test/SemaCXX/sizeless-1.cpp @@ -61,6 +61,8 @@ void unused() { struct incomplete_struct *incomplete_ptr; +typedef svint8_t sizeless_array[1]; // expected-error {{array has sizeless element type}} + void func(int sel) { static svint8_t static_int8; // expected-error {{non-local variable with sizeless type 'svint8_t'}} @@ -107,6 +109,9 @@ void func(int sel) { _Atomic svint8_t atomic_int8; // expected-error {{_Atomic cannot be applied to sizeless type 'svint8_t'}} __restrict svint8_t restrict_int8; // expected-error {{requires a pointer or reference}} + svint8_t array_int8[1]; // expected-error {{array has sizeless element type}} + svint8_t array_int8_init[] = {}; // expected-error {{array has sizeless element type}} + bool test_int8 = init_int8; // expected-error {{cannot initialize a variable of type 'bool' with an lvalue of type 'svint8_t'}} int int_int8 = init_int8; // expected-error {{cannot initialize a variable of type 'int' with an lvalue of type 'svint8_t'}} @@ -283,6 +288,11 @@ struct s_ptr_template { T *y; }; +template +struct s_array_template { + T y[1]; // expected-error {{array has sizeless element type}} +}; + struct widget { widget(s_ptr_template); svint8_t operator[](int); @@ -330,6 +340,13 @@ template void template_fn_rvalue_ref(T &&) {} #endif +#if __cplusplus >= 201103L +template +using array_alias = T[1]; // expected-error {{array has sizeless element type '__SVInt8_t'}} +extern array_alias *array_alias_int_ptr; +extern array_alias *array_alias_int8_ptr; // expected-note {{in instantiation of template type alias 'array_alias' requested here}} +#endif + void cxx_only(int sel) { svint8_t local_int8; svint16_t local_int16; @@ -372,6 +389,9 @@ void cxx_only(int sel) { widget w(1); local_int8 = w[1]; + s_array_template st_array_int; + s_array_template st_array_svint8; // expected-note {{in instantiation}} + local_int8 = static_cast(wrapper()); local_int16 = static_cast(wrapper()); // expected-error {{assigning to 'svint16_t' (aka '__SVInt16_t') from incompatible type 'svint8_t'}}