diff options
-rw-r--r-- | Sema/SemaDecl.cpp | 33 | ||||
-rw-r--r-- | include/clang/Basic/DiagnosticKinds.def | 2 | ||||
-rw-r--r-- | test/Sema/array-init.c | 4 |
3 files changed, 22 insertions, 17 deletions
diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp index d367038cdd..245e75c3b6 100644 --- a/Sema/SemaDecl.cpp +++ b/Sema/SemaDecl.cpp @@ -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; } diff --git a/include/clang/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def index a3249d742b..4b7399ddbe 100644 --- a/include/clang/Basic/DiagnosticKinds.def +++ b/include/clang/Basic/DiagnosticKinds.def @@ -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'") diff --git a/test/Sema/array-init.c b/test/Sema/array-init.c index 98387bedd0..5eed259dff 100644 --- a/test/Sema/array-init.c +++ b/test/Sema/array-init.c @@ -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}} |