diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -1756,6 +1756,8 @@ K_Deferred }; + // Special builder emitting no diagnostics + SemaDiagnosticBuilder(Sema &S) : S(S) {} SemaDiagnosticBuilder(Kind K, SourceLocation Loc, unsigned DiagID, FunctionDecl *Fn, Sema &S); SemaDiagnosticBuilder(SemaDiagnosticBuilder &&D); diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -2367,9 +2367,11 @@ unsigned VLADiag; bool VLAIsError; bool IsVLA = false; + bool SuppressNotICEVLA = false; - VLADiagnoser(unsigned VLADiag, bool VLAIsError) - : VLADiag(VLADiag), VLAIsError(VLAIsError) {} + VLADiagnoser(unsigned VLADiag, bool VLAIsError, bool SuppressNotICEVLA) + : VLADiag(VLADiag), VLAIsError(VLAIsError), + SuppressNotICEVLA(SuppressNotICEVLA) {} Sema::SemaDiagnosticBuilder diagnoseNotICEType(Sema &S, SourceLocation Loc, QualType T) override { @@ -2379,14 +2381,18 @@ Sema::SemaDiagnosticBuilder diagnoseNotICE(Sema &S, SourceLocation Loc) override { IsVLA = !VLAIsError; - return S.Diag(Loc, VLADiag); + if (!SuppressNotICEVLA) + return S.Diag(Loc, VLADiag); + return Sema::SemaDiagnosticBuilder(S); } Sema::SemaDiagnosticBuilder diagnoseFold(Sema &S, SourceLocation Loc) override { return S.Diag(Loc, diag::ext_vla_folded_to_constant); } - } Diagnoser(VLADiag, VLAIsError); + } Diagnoser(VLADiag, VLAIsError, + S.getCurScope()->isFunctionPrototypeScope() && + VLADiag == diag::warn_vla_used); ExprResult R = S.VerifyIntegerConstantExpression(ArraySize, &SizeVal, Diagnoser); @@ -2528,7 +2534,9 @@ llvm::APSInt ConstVal(Context.getTypeSize(Context.getSizeType())); if (!ArraySize) { if (ASM == ArrayType::Star) { - Diag(Loc, VLADiag); + if (!(getCurScope()->isFunctionPrototypeScope() && + VLADiag == diag::warn_vla_used)) + Diag(Loc, VLADiag); if (VLAIsError) return QualType(); diff --git a/clang/test/Sema/warn-vla.c b/clang/test/Sema/warn-vla.c --- a/clang/test/Sema/warn-vla.c +++ b/clang/test/Sema/warn-vla.c @@ -5,8 +5,18 @@ int v[n]; // expected-warning {{variable length array}} } -void test2(int n, int v[n]) { // expected-warning {{variable length array}} +void test2(int n, int v[n]) { // c99 no-warning +#if __STDC_VERSION__ < 199901L +// expected-warning@-2{{variable length arrays are a C99 feature}} +#endif } -void test3(int n, int v[n]); // expected-warning {{variable length array}} +void test3(int n, int v[n]); // c99 no-warning +#if __STDC_VERSION__ < 199901L +// expected-warning@-2{{variable length arrays are a C99 feature}} +#endif +void test4(int n, int v[][*]); // c99 no-warning +#if __STDC_VERSION__ < 199901L +// expected-warning@-2{{variable length arrays are a C99 feature}} +#endif