Commit f8700db7 authored by Richard Sandiford's avatar Richard Sandiford
Browse files

[Sema][SVE] Don't allow static or thread-local variables to have sizeless type

clang accepts a TU containing just:

  __SVInt8_t x;

However, sizeless types are not allowed to have static or thread-local
storage duration and trying to code-generate the TU triggers an LLVM
fatal error:

  Globals cannot contain scalable vectors
  <vscale x 16 x i8>* @x
  fatal error: error in backend: Broken module found, compilation aborted!

This patch adds an associated clang diagnostic.

Differential Revision: https://reviews.llvm.org/D75736
parent 36e018b9
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -9145,6 +9145,8 @@ def err_block_on_nonlocal : Error<
  "__block attribute not allowed, only allowed on local variables">;
def err_block_on_vm : Error<
  "__block attribute not allowed on declaration with a variably modified type">;
def err_sizeless_nonlocal : Error<
  "non-local variable with sizeless type %0">;
def err_vec_builtin_non_vector : Error<
 "first two arguments to %0 must be vectors">;
+6 −0
Original line number Diff line number Diff line
@@ -7939,6 +7939,12 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {
    return;
  }
  if (!NewVD->hasLocalStorage() && T->isSizelessType()) {
    Diag(NewVD->getLocation(), diag::err_sizeless_nonlocal) << T;
    NewVD->setInvalidDecl();
    return;
  }
  if (isVM && NewVD->hasAttr<BlocksAttr>()) {
    Diag(NewVD->getLocation(), diag::err_block_on_vm);
    NewVD->setInvalidDecl();
+6 −0
Original line number Diff line number Diff line
@@ -5,6 +5,10 @@
typedef __SVInt8_t svint8_t;
typedef __SVInt16_t svint16_t;

svint8_t global_int8;          // expected-error {{non-local variable with sizeless type 'svint8_t'}}
extern svint8_t extern_int8;   // expected-error {{non-local variable with sizeless type 'svint8_t'}}
static svint8_t static_int8;   // expected-error {{non-local variable with sizeless type 'svint8_t'}}
__thread svint8_t thread_int8; // expected-error {{non-local variable with sizeless type 'svint8_t'}}
svint8_t *global_int8_ptr;
extern svint8_t *extern_int8_ptr;
static svint8_t *static_int8_ptr;
@@ -48,6 +52,8 @@ void unused() {
struct incomplete_struct *incomplete_ptr;

void func(int sel) {
  static svint8_t static_int8; // expected-error {{non-local variable with sizeless type 'svint8_t'}}

  svint8_t local_int8;
  svint16_t local_int16;

+6 −0
Original line number Diff line number Diff line
@@ -10,6 +10,10 @@ struct type_info;
typedef __SVInt8_t svint8_t;
typedef __SVInt16_t svint16_t;

svint8_t global_int8;          // expected-error {{non-local variable with sizeless type 'svint8_t'}}
extern svint8_t extern_int8;   // expected-error {{non-local variable with sizeless type 'svint8_t'}}
static svint8_t static_int8;   // expected-error {{non-local variable with sizeless type 'svint8_t'}}
__thread svint8_t thread_int8; // expected-error {{non-local variable with sizeless type 'svint8_t'}}
svint8_t *global_int8_ptr;
extern svint8_t *extern_int8_ptr;
static svint8_t *static_int8_ptr;
@@ -58,6 +62,8 @@ void unused() {
struct incomplete_struct *incomplete_ptr;

void func(int sel) {
  static svint8_t static_int8; // expected-error {{non-local variable with sizeless type 'svint8_t'}}

  svint8_t local_int8;
  svint16_t local_int16;