diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 0501f63e90b2..e557c50e0273 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/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/clang/test/Sema/vla.c b/clang/test/Sema/vla.c index e03dda8c5f6c..b9576bf8cfd6 100644 --- a/clang/test/Sema/vla.c +++ b/clang/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}}