[clang] 994c071 - [Sema][SVE] Reject arrays of sizeless types
Richard Sandiford via cfe-commits
cfe-commits at lists.llvm.org
Fri Mar 13 12:32:56 PDT 2020
Author: Richard Sandiford
Date: 2020-03-13T19:28:45Z
New Revision: 994c071a1b7eee8de132d78286c730da2be2c48f
URL: https://github.com/llvm/llvm-project/commit/994c071a1b7eee8de132d78286c730da2be2c48f
DIFF: https://github.com/llvm/llvm-project/commit/994c071a1b7eee8de132d78286c730da2be2c48f.diff
LOG: [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
Added:
Modified:
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaExpr.cpp
clang/lib/Sema/SemaType.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 936edf2d5ae0..4328e322b914 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 4ffac5eb5c70..a61ddbd290f8 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 eaf22fed3131..9ab6a16154d5 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 7f555ecdcc95..534178388048 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 06ced5656dcb..962595b7b1f8 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 f776c47ffc94..8b6c00f6e044 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 <typename T>
+struct s_array_template {
+ T y[1]; // expected-error {{array has sizeless element type}}
+};
+
struct widget {
widget(s_ptr_template<int>);
svint8_t operator[](int);
@@ -330,6 +340,13 @@ template <typename T>
void template_fn_rvalue_ref(T &&) {}
#endif
+#if __cplusplus >= 201103L
+template <typename T>
+using array_alias = T[1]; // expected-error {{array has sizeless element type '__SVInt8_t'}}
+extern array_alias<int> *array_alias_int_ptr;
+extern array_alias<svint8_t> *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<int> st_array_int;
+ s_array_template<svint8_t> st_array_svint8; // expected-note {{in instantiation}}
+
local_int8 = static_cast<svint8_t>(wrapper<svint8_t>());
local_int16 = static_cast<svint8_t>(wrapper<svint8_t>()); // expected-error {{assigning to 'svint16_t' (aka '__SVInt16_t') from incompatible type 'svint8_t'}}
More information about the cfe-commits
mailing list