зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
b098c14c52
Коммит
1a7acfa0de
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче