From: Anders Carlsson Date: Sat, 28 Feb 2009 21:56:50 +0000 (+0000) Subject: Fix invalid VLAs/VMs in Sema::ActOnVariableDeclarator, so that the variable will... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1a7acfa0de7364b24599be4329d7ee2944540428;p=clang Fix invalid VLAs/VMs in Sema::ActOnVariableDeclarator, so that the variable will have the right type by the time the initializer is checked. This ensures that code like int a[(int)(1.0 / 1.0) = { 1 } will work. Eli, please review. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65725 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index c9b5405fbe..76794e571d 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -1622,6 +1622,42 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC, Diag(D.getIdentifierLoc(), diag::warn_attribute_weak_on_local); } + bool isIllegalVLA = R->isVariableArrayType() && NewVD->hasGlobalStorage(); + bool isIllegalVM = R->isVariablyModifiedType() && NewVD->hasLinkage(); + if (isIllegalVLA || isIllegalVM) { + bool SizeIsNegative; + QualType FixedTy = + TryToFixInvalidVariablyModifiedType(R, Context, SizeIsNegative); + if (!FixedTy.isNull()) { + Diag(NewVD->getLocation(), diag::warn_illegal_constant_array_size); + NewVD->setType(FixedTy); + } else if (R->isVariableArrayType()) { + NewVD->setInvalidDecl(); + + const VariableArrayType *VAT = Context.getAsVariableArrayType(R); + // FIXME: This won't give the correct result for + // int a[10][n]; + SourceRange SizeRange = VAT->getSizeExpr()->getSourceRange(); + + if (NewVD->isFileVarDecl()) + Diag(NewVD->getLocation(), diag::err_vla_decl_in_file_scope) + << SizeRange; + else if (NewVD->getStorageClass() == VarDecl::Static) + Diag(NewVD->getLocation(), diag::err_vla_decl_has_static_storage) + << SizeRange; + else + Diag(NewVD->getLocation(), diag::err_vla_decl_has_extern_linkage) + << SizeRange; + } else { + InvalidDecl = true; + + if (NewVD->isFileVarDecl()) + Diag(NewVD->getLocation(), diag::err_vm_decl_in_file_scope); + else + Diag(NewVD->getLocation(), diag::err_vm_decl_has_extern_linkage); + } + } + // If name lookup finds a previous declaration that is not in the // same scope as the new declaration, this may still be an // acceptable redeclaration. diff --git a/test/Sema/const-eval.c b/test/Sema/const-eval.c index fd7b40ea1b..7714f48817 100644 --- a/test/Sema/const-eval.c +++ b/test/Sema/const-eval.c @@ -47,3 +47,6 @@ EVAL_EXPR(21, (__imag__ 2i) == 2 ? 1 : -1); EVAL_EXPR(22, (__real__ (2i+3)) == 3 ? 1 : -1); +int g23[(int)(1.0 / 1.0)] = { 1 }; +int g24[(int)(1.0 / 1.0)] = { 1 , 2 }; // expected-warning {{excess elements in array initializer}} +int g25[(int)(1.0 + 1.0)], g26 = sizeof(g25);