From: David Majnemer Date: Tue, 7 Apr 2015 22:08:51 +0000 (+0000) Subject: [Sema] Correctly recurse when looking for [*] in function definitions X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b3aaa7dd2d3126ff4cfbff0ba0abf4f417e5cb4d;p=clang [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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@234363 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 0501f63e90..e557c50e02 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -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(PType)) { + diagnoseArrayStarInParamType(S, PointerTy->getPointeeType(), Loc); + return; + } + if (const auto *ParenTy = dyn_cast(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 diff --git a/test/Sema/vla.c b/test/Sema/vla.c index e03dda8c5f..b9576bf8cf 100644 --- a/test/Sema/vla.c +++ b/test/Sema/vla.c @@ -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}}