[Sema] Correctly recurse when looking for [*] in function definitions

A [*] is only allowed in a declaration for a function, not in its
definition.  We didn't correctly recurse while looking for it, causing
us to crash in CodeGen instead of rejecting it.

This fixes PR23151.

llvm-svn: 234363
This commit is contained in:
David Majnemer 2015-04-07 22:08:51 +00:00
parent 01f4c6cda6
commit 61a5bbf92a
2 changed files with 31 additions and 9 deletions

View File

@ -7705,6 +7705,31 @@ void Sema::CheckBitFieldInitialization(SourceLocation InitLoc,
(void) AnalyzeBitFieldAssignment(*this, BitField, Init, InitLoc);
}
static void diagnoseArrayStarInParamType(Sema &S, QualType PType,
SourceLocation Loc) {
if (!PType->isVariablyModifiedType())
return;
if (const auto *PointerTy = dyn_cast<PointerType>(PType)) {
diagnoseArrayStarInParamType(S, PointerTy->getPointeeType(), Loc);
return;
}
if (const auto *ParenTy = dyn_cast<ParenType>(PType)) {
diagnoseArrayStarInParamType(S, ParenTy->getInnerType(), Loc);
return;
}
const ArrayType *AT = S.Context.getAsArrayType(PType);
if (!AT)
return;
if (AT->getSizeModifier() != ArrayType::Star) {
diagnoseArrayStarInParamType(S, AT->getElementType(), Loc);
return;
}
S.Diag(Loc, diag::err_array_star_in_function_definition);
}
/// CheckParmsForFunctionDef - Check that the parameters of the given
/// function are appropriate for the definition of a function. This
/// takes care of any checks that cannot be performed on the
@ -7743,15 +7768,9 @@ bool Sema::CheckParmsForFunctionDef(ParmVarDecl *const *P,
// notation in their sequences of declarator specifiers to specify
// variable length array types.
QualType PType = Param->getOriginalType();
while (const ArrayType *AT = Context.getAsArrayType(PType)) {
if (AT->getSizeModifier() == ArrayType::Star) {
// FIXME: This diagnostic should point the '[*]' if source-location
// information is added for it.
Diag(Param->getLocation(), diag::err_array_star_in_function_definition);
break;
}
PType= AT->getElementType();
}
// FIXME: This diagnostic should point the '[*]' if source-location
// information is added for it.
diagnoseArrayStarInParamType(*this, PType, Param->getLocation());
// MSVC destroys objects passed by value in the callee. Therefore a
// function definition which takes such a parameter must be able to call the

View File

@ -61,6 +61,9 @@ void pr5185(int a[*]) // expected-error {{variable length array must be bound in
{
}
void pr23151(int (*p1)[*]) // expected-error {{variable length array must be bound in function definition}}
{}
// Make sure this isn't treated as an error
int TransformBug(int a) {
return sizeof(*(int(*)[({ goto v; v: a;})]) 0); // expected-warning {{use of GNU statement expression extension}}