forked from OSchip/llvm-project
Improve VLA diagnostics/sema checking. Fixes PR2361 and PR2352.
llvm-svn: 60638
This commit is contained in:
parent
b098a7883f
commit
0d8f0ba6ed
|
@ -998,8 +998,16 @@ DIAG(warn_enum_too_large, WARNING,
|
|||
"enumeration values exceed range of largest integer")
|
||||
DIAG(warn_illegal_constant_array_size, EXTENSION,
|
||||
"size of static array must be an integer constant expression")
|
||||
DIAG(err_typecheck_illegal_vla, ERROR,
|
||||
"arrays with static storage duration must have constant integer length")
|
||||
DIAG(err_vla_decl_in_file_scope, ERROR,
|
||||
"variable length array declaration not allowed in file scope")
|
||||
DIAG(err_vla_decl_has_static_storage, ERROR,
|
||||
"variable length array declaration can not have 'static' storage duration")
|
||||
DIAG(err_vla_decl_has_extern_linkage, ERROR,
|
||||
"variable length array declaration can not have 'extern' linkage")
|
||||
DIAG(err_vm_decl_in_file_scope, ERROR,
|
||||
"variably modified type declaration not allowed in file scope")
|
||||
DIAG(err_vm_decl_has_extern_linkage, ERROR,
|
||||
"variably modified type declaration can not have 'extern' linkage")
|
||||
DIAG(err_typecheck_field_variable_size, ERROR,
|
||||
"fields must have a constant size")
|
||||
DIAG(err_typecheck_negative_array_size, ERROR,
|
||||
|
@ -1157,6 +1165,8 @@ DIAG(err_typecheck_incomplete_tag, ERROR,
|
|||
"incomplete definition of type %0")
|
||||
DIAG(err_typecheck_no_member, ERROR,
|
||||
"no member named %0")
|
||||
DIAG(err_typecheck_ivar_variable_size, ERROR,
|
||||
"instance variables must have a constant size")
|
||||
// FIXME: Improve with %select
|
||||
DIAG(err_typecheck_illegal_increment_decrement, ERROR,
|
||||
"cannot modify value of type %0")
|
||||
|
|
|
@ -906,8 +906,11 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) {
|
|||
// C99 6.7.7p2: If a typedef name specifies a variably modified type
|
||||
// then it shall have block scope.
|
||||
if (NewTD->getUnderlyingType()->isVariablyModifiedType()) {
|
||||
// FIXME: Diagnostic needs to be fixed.
|
||||
Diag(D.getIdentifierLoc(), diag::err_typecheck_illegal_vla);
|
||||
if (NewTD->getUnderlyingType()->isVariableArrayType())
|
||||
Diag(D.getIdentifierLoc(), diag::err_vla_decl_in_file_scope);
|
||||
else
|
||||
Diag(D.getIdentifierLoc(), diag::err_vm_decl_in_file_scope);
|
||||
|
||||
InvalidDecl = true;
|
||||
}
|
||||
}
|
||||
|
@ -1924,15 +1927,33 @@ Sema::DeclTy *Sema::FinalizeDeclaratorGroup(Scope *S, DeclTy *group) {
|
|||
continue;
|
||||
QualType T = IDecl->getType();
|
||||
|
||||
// C99 6.7.5.2p2: If an identifier is declared to be an object with
|
||||
// static storage duration, it shall not have a variable length array.
|
||||
if ((IDecl->isFileVarDecl() || IDecl->isBlockVarDecl()) &&
|
||||
IDecl->getStorageClass() == VarDecl::Static) {
|
||||
if (T->isVariableArrayType()) {
|
||||
Diag(IDecl->getLocation(), diag::err_typecheck_illegal_vla);
|
||||
if (T->isVariableArrayType()) {
|
||||
if (IDecl->isFileVarDecl()) {
|
||||
Diag(IDecl->getLocation(), diag::err_vla_decl_in_file_scope);
|
||||
IDecl->setInvalidDecl();
|
||||
} else {
|
||||
// C99 6.7.5.2p2: If an identifier is declared to be an object with
|
||||
// static storage duration, it shall not have a variable length array.
|
||||
if (IDecl->getStorageClass() == VarDecl::Static) {
|
||||
Diag(IDecl->getLocation(), diag::err_vla_decl_has_static_storage);
|
||||
IDecl->setInvalidDecl();
|
||||
} else if (IDecl->getStorageClass() == VarDecl::Extern) {
|
||||
Diag(IDecl->getLocation(), diag::err_vla_decl_has_extern_linkage);
|
||||
IDecl->setInvalidDecl();
|
||||
}
|
||||
}
|
||||
} else if (T->isVariablyModifiedType()) {
|
||||
if (IDecl->isFileVarDecl()) {
|
||||
Diag(IDecl->getLocation(), diag::err_vm_decl_in_file_scope);
|
||||
IDecl->setInvalidDecl();
|
||||
} else {
|
||||
if (IDecl->getStorageClass() == VarDecl::Extern) {
|
||||
Diag(IDecl->getLocation(), diag::err_vm_decl_has_extern_linkage);
|
||||
IDecl->setInvalidDecl();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Block scope. C99 6.7p7: If an identifier for an object is declared with
|
||||
// no linkage (C99 6.2.2p6), the type for the object shall be complete...
|
||||
if (IDecl->isBlockVarDecl() &&
|
||||
|
@ -2735,8 +2756,7 @@ Sema::DeclTy *Sema::ActOnIvar(Scope *S,
|
|||
// C99 6.7.2.1p8: A member of a structure or union may have any type other
|
||||
// than a variably modified type.
|
||||
if (T->isVariablyModifiedType()) {
|
||||
// FIXME: This diagnostic needs work
|
||||
Diag(Loc, diag::err_typecheck_illegal_vla) << SourceRange(Loc);
|
||||
Diag(Loc, diag::err_typecheck_ivar_variable_size);
|
||||
InvalidDecl = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,8 +9,8 @@ int main() {
|
|||
struct foo s;
|
||||
|
||||
static int ary[__builtin_classify_type(a)];
|
||||
static int ary2[(__builtin_classify_type)(a)]; // expected-error{{arrays with static storage duration must have constant integer length}}
|
||||
static int ary3[(*__builtin_classify_type)(a)]; // expected-error{{arrays with static storage duration must have constant integer length}}
|
||||
static int ary2[(__builtin_classify_type)(a)]; // expected-error{{variable length array declaration can not have 'static' storage duration}}
|
||||
static int ary3[(*__builtin_classify_type)(a)]; // expected-error{{variable length array declaration can not have 'static' storage duration}}
|
||||
|
||||
int result;
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ void check_size() {
|
|||
}
|
||||
|
||||
static int I;
|
||||
typedef int TA[I]; // expected-error {{arrays with static storage duration must have constant integer length}}
|
||||
typedef int TA[I]; // expected-error {{variable length array declaration not allowed in file scope}}
|
||||
|
||||
void strFunc(char *);
|
||||
const char staticAry[] = "test";
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
// RUN: clang %s -verify -fsyntax-only -pedantic
|
||||
|
||||
typedef int (*a)[!.0]; // expected-error{{arrays with static storage duration must have constant integer length}}
|
||||
typedef int (*a)[!.0]; // expected-error{{variably modified type declaration not allowed in file scope}}
|
||||
|
|
|
@ -16,3 +16,28 @@ void f (unsigned int m)
|
|||
// PR3048
|
||||
int x = sizeof(struct{char qq[x];}); // expected-error {{fields must have a constant size}}
|
||||
|
||||
// PR2352
|
||||
void f2(unsigned int m)
|
||||
{
|
||||
extern int e[2][m]; // expected-error {{variable length array declaration can not have 'extern' linkage}}
|
||||
|
||||
e[0][0] = 0;
|
||||
|
||||
}
|
||||
|
||||
// PR2361
|
||||
int i;
|
||||
int c[][i]; // expected-error {{variably modified type declaration not allowed in file scope}}
|
||||
int d[i]; // expected-error {{variable length array declaration not allowed in file scope}}
|
||||
|
||||
int (*e)[i]; // expected-error {{variably modified type declaration not allowed in file scope}}
|
||||
|
||||
void f3()
|
||||
{
|
||||
static int a[i]; // expected-error {{variable length array declaration can not have 'static' storage duration}}
|
||||
extern int b[i]; // expected-error {{variable length array declaration can not have 'extern' linkage}}
|
||||
|
||||
extern int (*c)[i]; // expected-error {{variably modified type declaration can not have 'extern' linkage}}
|
||||
static int (*d)[i];
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue