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
This commit is contained in:
Anders Carlsson 2009-02-28 21:56:50 +00:00
Родитель b098c14c52
Коммит 1a7acfa0de
2 изменённых файлов: 39 добавлений и 0 удалений

Просмотреть файл

@ -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.

Просмотреть файл

@ -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);