aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-02-28 21:56:50 +0000
committerAnders Carlsson <andersca@mac.com>2009-02-28 21:56:50 +0000
commit1a7acfa0de7364b24599be4329d7ee2944540428 (patch)
treeaa763079626395f00d6d7d2f5f7d2b31ae876d3a /lib/Sema/SemaDecl.cpp
parentb098c14c525894702994d5dc4b58a4283ac25c63 (diff)
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
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r--lib/Sema/SemaDecl.cpp36
1 files changed, 36 insertions, 0 deletions
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.