Remove a FIXME. Replace a couple asserts with an appropriate error

diagnostic for illegal initializers.

llvm-svn: 41889
This commit is contained in:
Steve Naroff 2007-09-12 20:13:48 +00:00
parent fe1da5ec56
commit 437b4d8bda
3 changed files with 22 additions and 17 deletions

View File

@ -561,32 +561,31 @@ Sema::ParseDeclarator(Scope *S, Declarator &D, DeclTy *lastDeclarator) {
}
void Sema::AddInitializerToDecl(DeclTy *dcl, ExprTy *init) {
VarDecl *Dcl = dyn_cast<VarDecl>(static_cast<Decl *>(dcl));
Decl *RealDecl = static_cast<Decl *>(dcl);
Expr *Init = static_cast<Expr *>(init);
assert((Dcl && Init) && "missing decl or initializer");
// FIXME: moved these directly from ParseDeclarator(). Need to convert
// asserts to actual error diagnostics!
if (isa<FunctionDecl>(Dcl))
assert(0 && "Can't have an initializer for a functiondecl!");
if (isa<TypedefDecl>(Dcl))
assert(0 && "Can't have an initializer for a typedef!");
assert((RealDecl && Init) && "missing decl or initializer");
VarDecl *VDecl = dyn_cast<VarDecl>(RealDecl);
if (!VDecl) {
Diag(RealDecl->getLocation(), diag::err_illegal_initializer);
RealDecl->setInvalidDecl();
return;
}
// Get the decls type and save a reference for later, since
// CheckInitializer may change it.
QualType DclT = Dcl->getType(), SavT = DclT;
if (BlockVarDecl *BVD = dyn_cast<BlockVarDecl>(Dcl)) {
QualType DclT = VDecl->getType(), SavT = DclT;
if (BlockVarDecl *BVD = dyn_cast<BlockVarDecl>(VDecl)) {
VarDecl::StorageClass SC = BVD->getStorageClass();
if (SC == VarDecl::Extern) { // C99 6.7.8p5
Diag(Dcl->getLocation(), diag::err_block_extern_cant_init);
Diag(VDecl->getLocation(), diag::err_block_extern_cant_init);
BVD->setInvalidDecl();
} else if (!BVD->isInvalidDecl()) {
CheckInitializer(Init, DclT, SC == VarDecl::Static);
}
} else if (FileVarDecl *FVD = dyn_cast<FileVarDecl>(Dcl)) {
} else if (FileVarDecl *FVD = dyn_cast<FileVarDecl>(VDecl)) {
if (FVD->getStorageClass() == VarDecl::Extern)
Diag(Dcl->getLocation(), diag::warn_extern_init);
Diag(VDecl->getLocation(), diag::warn_extern_init);
if (!FVD->isInvalidDecl())
CheckInitializer(Init, DclT, true);
}
@ -594,11 +593,11 @@ void Sema::AddInitializerToDecl(DeclTy *dcl, ExprTy *init) {
// completed by the initializer. For example:
// int ary[] = { 1, 3, 5 };
// "ary" transitions from a VariableArrayType to a ConstantArrayType.
if (!Dcl->isInvalidDecl() && (DclT != SavT))
Dcl->setType(DclT);
if (!VDecl->isInvalidDecl() && (DclT != SavT))
VDecl->setType(DclT);
// Attach the initializer to the decl.
Dcl->setInit(Init);
VDecl->setInit(Init);
return;
}

View File

@ -553,6 +553,8 @@ DIAG(warn_excess_initializers, WARNING,
"excess elements in array initializer")
DIAG(warn_braces_around_scalar_init, WARNING,
"braces around scalar initializer")
DIAG(err_illegal_initializer, ERROR,
"illegal initializer (only variables can be initialized)")
DIAG(err_redefinition_of_label, ERROR,
"redefinition of label '%0'")

View File

@ -1,5 +1,7 @@
// RUN: clang -parse-ast-check -pedantic %s
extern int foof() = 1; // expected-error{{illegal initializer (only variables can be initialized)}}
static int x, y, z;
static int ary[] = { x, y, z }; // expected-error{{initializer element is not constant}}
@ -12,6 +14,8 @@ static int ary3[] = { 1, "abc", 3, 4 }; // expected-warning{{incompatible types
void func() {
int x = 1;
typedef int TInt = 1; // expected-error{{illegal initializer (only variables can be initialized)}}
int xComputeSize[] = { 1, 3, 5 };
int x3[x] = { 1, 2 }; // expected-error{{variable-sized object may not be initialized}}