diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -137,8 +137,9 @@ "variable length array declaration cannot have 'static' storage duration">; def err_vla_decl_has_extern_linkage : Error< "variable length array declaration cannot have 'extern' linkage">; -def ext_vla_folded_to_constant : Extension< - "variable length array folded to constant array as an extension">, InGroup; +def ext_vla_folded_to_constant : ExtWarn< + "variable length array folded to constant array as an extension">, + InGroup; def err_vla_unsupported : Error< "variable length arrays are not supported for the current target">; def note_vla_unsupported : Note< @@ -5474,8 +5475,6 @@ "enumeration value %0 is out of range of flags in enumeration type %1">, InGroup; -def warn_illegal_constant_array_size : Extension< - "size of static array must be an integer constant expression">; def err_vm_decl_in_file_scope : Error< "variably modified type declaration not allowed at file scope">; def err_vm_decl_has_extern_linkage : Error< diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -5932,9 +5932,14 @@ const VariableArrayType* VLATy = dyn_cast(T); if (!VLATy) return QualType(); - // FIXME: We should probably handle this case - if (VLATy->getElementType()->isVariablyModifiedType()) - return QualType(); + + QualType ElemTy = VLATy->getElementType(); + if (ElemTy->isVariablyModifiedType()) { + ElemTy = TryToFixInvalidVariablyModifiedType(ElemTy, Context, + SizeIsNegative, Oversized); + if (ElemTy.isNull()) + return QualType(); + } Expr::EvalResult Result; if (!VLATy->getSizeExpr() || @@ -5950,16 +5955,18 @@ } // Check whether the array is too large to be addressed. - unsigned ActiveSizeBits - = ConstantArrayType::getNumAddressingBits(Context, VLATy->getElementType(), - Res); + unsigned ActiveSizeBits = + (!ElemTy->isDependentType() && !ElemTy->isVariablyModifiedType() && + !ElemTy->isIncompleteType() && !ElemTy->isUndeducedType()) + ? ConstantArrayType::getNumAddressingBits(Context, ElemTy, Res) + : Res.getActiveBits(); if (ActiveSizeBits > ConstantArrayType::getMaxSizeBits(Context)) { Oversized = Res; return QualType(); } - return Context.getConstantArrayType( - VLATy->getElementType(), Res, VLATy->getSizeExpr(), ArrayType::Normal, 0); + return Context.getConstantArrayType(ElemTy, Res, VLATy->getSizeExpr(), + ArrayType::Normal, 0); } static void @@ -5985,7 +5992,13 @@ ArrayTypeLoc DstATL = DstTL.castAs(); TypeLoc SrcElemTL = SrcATL.getElementLoc(); TypeLoc DstElemTL = DstATL.getElementLoc(); - DstElemTL.initializeFullCopy(SrcElemTL); + if (VariableArrayTypeLoc SrcElemATL = + SrcElemTL.getAs()) { + ConstantArrayTypeLoc DstElemATL = DstElemTL.castAs(); + FixInvalidVariablyModifiedTypeLoc(SrcElemATL, DstElemATL); + } else { + DstElemTL.initializeFullCopy(SrcElemTL); + } DstATL.setLBracketLoc(SrcATL.getLBracketLoc()); DstATL.setSizeExpr(SrcATL.getSizeExpr()); DstATL.setRBracketLoc(SrcATL.getRBracketLoc()); @@ -6115,7 +6128,7 @@ SizeIsNegative, Oversized); if (FixedTInfo) { - Diag(NewTD->getLocation(), diag::warn_illegal_constant_array_size); + Diag(NewTD->getLocation(), diag::ext_vla_folded_to_constant); NewTD->setTypeSourceInfo(FixedTInfo); } else { if (SizeIsNegative) @@ -7984,7 +7997,7 @@ return; } - Diag(NewVD->getLocation(), diag::warn_illegal_constant_array_size); + Diag(NewVD->getLocation(), diag::ext_vla_folded_to_constant); NewVD->setType(FixedT); NewVD->setTypeSourceInfo(FixedTInfo); } @@ -16675,7 +16688,7 @@ SizeIsNegative, Oversized); if (FixedTInfo) { - Diag(Loc, diag::warn_illegal_constant_array_size); + Diag(Loc, diag::ext_vla_folded_to_constant); TInfo = FixedTInfo; T = FixedTInfo->getType(); } else { 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 @@ -2273,13 +2273,9 @@ } } Diagnoser(VLADiag, VLAIsError); - // FIXME: GCC does *not* allow folding here in general; see PR44406. - // For GCC compatibility, we should remove this folding and leave it to - // TryFixVariablyModifiedType to convert VLAs to constant array types. ExprResult R = S.VerifyIntegerConstantExpression( ArraySize, &SizeVal, Diagnoser, - (S.LangOpts.GNUMode || S.LangOpts.OpenCL) ? Sema::AllowFold - : Sema::NoFold); + S.LangOpts.OpenCL ? Sema::AllowFold : Sema::NoFold); if (Diagnoser.IsVLA) return ExprResult(); return R; diff --git a/clang/test/CXX/basic/basic.types/p10.cpp b/clang/test/CXX/basic/basic.types/p10.cpp --- a/clang/test/CXX/basic/basic.types/p10.cpp +++ b/clang/test/CXX/basic/basic.types/p10.cpp @@ -139,6 +139,7 @@ constexpr int arb(int n) { int a[n]; // expected-error {{variable of non-literal type 'int [n]' cannot be defined in a constexpr function}} } +// expected-warning@+1 {{variable length array folded to constant array as an extension}} constexpr long Overflow[ // expected-error {{constexpr variable cannot have non-literal type 'long const[(1 << 30) << 2]'}} (1 << 30) << 2]{}; // expected-warning {{requires 34 bits to represent}} diff --git a/clang/test/CXX/drs/dr3xx.cpp b/clang/test/CXX/drs/dr3xx.cpp --- a/clang/test/CXX/drs/dr3xx.cpp +++ b/clang/test/CXX/drs/dr3xx.cpp @@ -898,8 +898,8 @@ int c[true ? *new int : 4]; // expected-error 2{{variable length array}} expected-note {{read of uninitialized}} int d[true ? 4 : *new int]; #if __cplusplus < 201103L - // expected-error@-4 {{variable length array}} expected-error@-4 {{constant expression}} - // expected-error@-3 {{variable length array}} expected-error@-3 {{constant expression}} + // expected-error@-4 2{{variable length array}} + // expected-error@-3 2{{variable length array}} #endif } diff --git a/clang/test/CodeGen/vla.c b/clang/test/CodeGen/vla.c --- a/clang/test/CodeGen/vla.c +++ b/clang/test/CodeGen/vla.c @@ -210,3 +210,15 @@ void test10(int a[static 0]) {} // NULL-INVALID: define void @test10(i32* nonnull align 4 %a) // NULL-VALID: define void @test10(i32* align 4 %a) + +const int constant = 32; +// CHECK: define {{.*}}pr44406( +int pr44406() { + int n = 0; + // Do not fold this VLA to an array of constant bound; that would miscompile + // this testcase. + char c[1][(constant - constant) + 3]; + // CHECK: store i32 1, + sizeof(c[n = 1]); + return n; +} diff --git a/clang/test/Misc/warning-flags.c b/clang/test/Misc/warning-flags.c --- a/clang/test/Misc/warning-flags.c +++ b/clang/test/Misc/warning-flags.c @@ -91,4 +91,4 @@ The list of warnings in -Wpedantic should NEVER grow. -CHECK: Number in -Wpedantic (not covered by other -W flags): 27 +CHECK: Number in -Wpedantic (not covered by other -W flags): 26 diff --git a/clang/test/PCH/cxx-constexpr.cpp b/clang/test/PCH/cxx-constexpr.cpp --- a/clang/test/PCH/cxx-constexpr.cpp +++ b/clang/test/PCH/cxx-constexpr.cpp @@ -16,7 +16,7 @@ #else const int a = 5; -typedef int T[b]; // expected-error {{variable length array}} expected-error {{must be an integer constant expression}} expected-note {{initializer of 'b'}} +typedef int T[b]; // expected-error 2{{variable length array}} expected-note {{initializer of 'b'}} // expected-note@14 {{here}} typedef int T[5]; diff --git a/clang/test/Profile/misexpect-switch-default.c b/clang/test/Profile/misexpect-switch-default.c --- a/clang/test/Profile/misexpect-switch-default.c +++ b/clang/test/Profile/misexpect-switch-default.c @@ -10,7 +10,7 @@ const int inner_loop = 1000; const int outer_loop = 20; -const int arry_size = 25; +enum { arry_size = 25 }; int arry[arry_size] = {0}; diff --git a/clang/test/Profile/misexpect-switch-nonconst.c b/clang/test/Profile/misexpect-switch-nonconst.c --- a/clang/test/Profile/misexpect-switch-nonconst.c +++ b/clang/test/Profile/misexpect-switch-nonconst.c @@ -11,7 +11,7 @@ const int inner_loop = 1000; const int outer_loop = 20; -const int arry_size = 25; +enum { arry_size = 25 }; int arry[arry_size] = {0}; diff --git a/clang/test/Profile/misexpect-switch-only-default-case.c b/clang/test/Profile/misexpect-switch-only-default-case.c --- a/clang/test/Profile/misexpect-switch-only-default-case.c +++ b/clang/test/Profile/misexpect-switch-only-default-case.c @@ -11,7 +11,7 @@ const int inner_loop = 1000; const int outer_loop = 20; -const int arry_size = 25; +enum { arry_size = 25 }; int arry[arry_size] = {0}; diff --git a/clang/test/Profile/misexpect-switch.c b/clang/test/Profile/misexpect-switch.c --- a/clang/test/Profile/misexpect-switch.c +++ b/clang/test/Profile/misexpect-switch.c @@ -10,7 +10,7 @@ const int inner_loop = 1000; const int outer_loop = 20; -const int arry_size = 25; +enum { arry_size = 25 }; int arry[arry_size] = {0}; diff --git a/clang/test/Sema/builtin-assume.c b/clang/test/Sema/builtin-assume.c --- a/clang/test/Sema/builtin-assume.c +++ b/clang/test/Sema/builtin-assume.c @@ -23,7 +23,7 @@ __builtin_assume(ispure(i) > 2); __builtin_assume(ispure(++i) > 2); //expected-warning {{the argument to '__builtin_assume' has side effects that will be discarded}} - int test = sizeof(struct{char qq[(__builtin_assume(i != 5), 7)];}); + int test = sizeof(struct{char qq[(__builtin_assume(i != 5), 7)];}); // expected-warning {{variable length array}} #endif return a[i]; } diff --git a/clang/test/Sema/builtins.c b/clang/test/Sema/builtins.c --- a/clang/test/Sema/builtins.c +++ b/clang/test/Sema/builtins.c @@ -141,7 +141,7 @@ size_t strlen(const char *); void test17() { -#define ASSERT(...) { int arr[(__VA_ARGS__) ? 1 : -1]; } +#define ASSERT(...) { enum { folded = (__VA_ARGS__) }; int arr[folded ? 1 : -1]; } #define T(...) ASSERT(__builtin_constant_p(__VA_ARGS__)) #define F(...) ASSERT(!__builtin_constant_p(__VA_ARGS__)) @@ -179,12 +179,12 @@ ASSERT(!OPT("abcd")); // In these cases, the strlen is non-constant, but the __builtin_constant_p // is 0: the array size is not an ICE but is foldable. - ASSERT(!OPT(test17_c)); // expected-warning {{folded}} - ASSERT(!OPT(&test17_c[0])); // expected-warning {{folded}} - ASSERT(!OPT((char*)test17_c)); // expected-warning {{folded}} - ASSERT(!OPT(test17_d)); // expected-warning {{folded}} - ASSERT(!OPT(&test17_d[0])); // expected-warning {{folded}} - ASSERT(!OPT((char*)test17_d)); // expected-warning {{folded}} + ASSERT(!OPT(test17_c)); // expected-warning {{folding}} + ASSERT(!OPT(&test17_c[0])); // expected-warning {{folding}} + ASSERT(!OPT((char*)test17_c)); // expected-warning {{folding}} + ASSERT(!OPT(test17_d)); // expected-warning {{folding}} + ASSERT(!OPT(&test17_d[0])); // expected-warning {{folding}} + ASSERT(!OPT((char*)test17_d)); // expected-warning {{folding}} #undef OPT #undef T diff --git a/clang/test/Sema/complex-int.c b/clang/test/Sema/complex-int.c --- a/clang/test/Sema/complex-int.c +++ b/clang/test/Sema/complex-int.c @@ -60,14 +60,16 @@ (*x)++; } -int i1[(2+3i)*(5+7i) == 29i-11 ? 1 : -1]; -int i2[(29i-11)/(5+7i) == 2+3i ? 1 : -1]; -int i3[-(2+3i) == +(-3i-2) ? 1 : -1]; -int i4[~(2+3i) == 2-3i ? 1 : -1]; -int i5[(3i == -(-3i) ? ((void)3, 1i - 1) : 0) == 1i - 1 ? 1 : -1]; +// None of these array bounds is an ICE due to the use of literals of +// non-integer type. But we can constant-fold all of them. +int i1[(2+3i)*(5+7i) == 29i-11 ? 1 : -1]; // expected-warning {{fold}} +int i2[(29i-11)/(5+7i) == 2+3i ? 1 : -1]; // expected-warning {{fold}} +int i3[-(2+3i) == +(-3i-2) ? 1 : -1]; // expected-warning {{fold}} +int i4[~(2+3i) == 2-3i ? 1 : -1]; // expected-warning {{fold}} +int i5[(3i == -(-3i) ? ((void)3, 1i - 1) : 0) == 1i - 1 ? 1 : -1]; // expected-warning {{fold}} -int f1[(2.0+3.0i)*(5.0+7.0i) == 29.0i-11.0 ? 1 : -1]; -int f2[(29.0i-11.0)/(5.0+7.0i) == 2.0+3.0i ? 1 : -1]; -int f3[-(2.0+3.0i) == +(-3.0i-2.0) ? 1 : -1]; -int f4[~(2.0+3.0i) == 2.0-3.0i ? 1 : -1]; -int f5[(3.0i == -(-3.0i) ? ((void)3.0, __extension__ (1.0i - 1.0)) : 0) == 1.0i - 1.0 ? 1 : -1]; +int f1[(2.0+3.0i)*(5.0+7.0i) == 29.0i-11.0 ? 1 : -1]; // expected-warning {{fold}} +int f2[(29.0i-11.0)/(5.0+7.0i) == 2.0+3.0i ? 1 : -1]; // expected-warning {{fold}} +int f3[-(2.0+3.0i) == +(-3.0i-2.0) ? 1 : -1]; // expected-warning {{fold}} +int f4[~(2.0+3.0i) == 2.0-3.0i ? 1 : -1]; // expected-warning {{fold}} +int f5[(3.0i == -(-3.0i) ? ((void)3.0, __extension__ (1.0i - 1.0)) : 0) == 1.0i - 1.0 ? 1 : -1]; // expected-warning {{fold}} diff --git a/clang/test/Sema/const-eval-64.c b/clang/test/Sema/const-eval-64.c --- a/clang/test/Sema/const-eval-64.c +++ b/clang/test/Sema/const-eval-64.c @@ -1,8 +1,7 @@ // RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-linux %s -// expected-no-diagnostics #define EVAL_EXPR(testno, expr) int test##testno = sizeof(struct{char qq[expr];}); // -EVAL_EXPR(1, ((char*)-1LL) + 1 == 0 ? 1 : -1) -EVAL_EXPR(2, ((char*)-1LL) + 1 < (char*) -1 ? 1 : -1) +EVAL_EXPR(1, ((char*)-1LL) + 1 == 0 ? 1 : -1) // expected-warning {{folded}} +EVAL_EXPR(2, ((char*)-1LL) + 1 < (char*) -1 ? 1 : -1) // expected-warning {{folded}} diff --git a/clang/test/Sema/const-eval.c b/clang/test/Sema/const-eval.c --- a/clang/test/Sema/const-eval.c +++ b/clang/test/Sema/const-eval.c @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-linux %s -Wno-tautological-pointer-compare -Wno-pointer-to-int-cast -#define EVAL_EXPR(testno, expr) int test##testno = sizeof(struct{char qq[expr];}); +#define EVAL_EXPR(testno, expr) enum { test##testno = (expr) }; struct check_positive##testno { int a[test##testno]; }; int x; EVAL_EXPR(1, (_Bool)&x) EVAL_EXPR(2, (int)(1.0+(double)4)) @@ -14,12 +14,12 @@ EVAL_EXPR(9, !!&x) EVAL_EXPR(10, ((void)1, 12)) void g0(void); -EVAL_EXPR(11, (g0(), 12)) // expected-error {{must have a constant size}} +EVAL_EXPR(11, (g0(), 12)) // expected-error {{not an integer constant expression}} EVAL_EXPR(12, 1.0&&2.0) -EVAL_EXPR(13, x || 3.0) // expected-error {{must have a constant size}} +EVAL_EXPR(13, x || 3.0) // expected-error {{not an integer constant expression}} unsigned int l_19 = 1; -EVAL_EXPR(14, (1 ^ l_19) && 1); // expected-error {{fields must have a constant size}} +EVAL_EXPR(14, (1 ^ l_19) && 1); // expected-error {{not an integer constant expression}} void f() { @@ -36,7 +36,7 @@ EVAL_EXPR(18, ((int)((void*)10 + 10)) == 20 ? 1 : -1); struct s { - int a[(int)-1.0f]; // expected-error {{'a' declared as an array with a negative size}} + int a[(int)-1.0f]; // expected-error {{array size is negative}} }; EVAL_EXPR(19, ((int)&*(char*)10 == 10 ? 1 : -1)); @@ -47,9 +47,9 @@ 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); +int g23[(int)(1.0 / 1.0)] = { 1 }; // expected-warning {{folded to constant array}} +int g24[(int)(1.0 / 1.0)] = { 1 , 2 }; // expected-warning {{folded to constant array}} expected-warning {{excess elements in array initializer}} +int g25[(int)(1.0 + 1.0)], g26 = sizeof(g25); // expected-warning {{folded to constant array}} EVAL_EXPR(26, (_Complex double)0 ? -1 : 1) EVAL_EXPR(27, (_Complex int)0 ? -1 : 1) @@ -116,17 +116,17 @@ // PR12043 float varfloat; const float constfloat = 0; -EVAL_EXPR(43, varfloat && constfloat) // expected-error {{must have a constant size}} +EVAL_EXPR(43, varfloat && constfloat) // expected-error {{not an integer constant expression}} // EVAL_EXPR(45, ((char*)-1) + 1 == 0 ? 1 : -1) EVAL_EXPR(46, ((char*)-1) + 1 < (char*) -1 ? 1 : -1) EVAL_EXPR(47, &x < &x + 1 ? 1 : -1) EVAL_EXPR(48, &x != &x - 1 ? 1 : -1) -EVAL_EXPR(49, &x < &x - 100 ? 1 : -1) // expected-error {{must have a constant size}} +EVAL_EXPR(49, &x < &x - 100 ? 1 : -1) // expected-error {{not an integer constant expression}} extern struct Test50S Test50; -EVAL_EXPR(50, &Test50 < (struct Test50S*)((unsigned long)&Test50 + 10)) // expected-error {{must have a constant size}} +EVAL_EXPR(50, &Test50 < (struct Test50S*)((unsigned long)&Test50 + 10)) // expected-error {{not an integer constant expression}} // EVAL_EXPR(51, 0 != (float)1e99) @@ -136,7 +136,7 @@ void PR24622(); struct PR24622 {} pr24622; -EVAL_EXPR(52, &pr24622 == (void *)&PR24622); // expected-error {{must have a constant size}} +EVAL_EXPR(52, &pr24622 == (void *)&PR24622); // expected-error {{not an integer constant expression}} // We evaluate these by providing 2s' complement semantics in constant // expressions, like we do for integers. diff --git a/clang/test/Sema/darwin-align-cast.c b/clang/test/Sema/darwin-align-cast.c --- a/clang/test/Sema/darwin-align-cast.c +++ b/clang/test/Sema/darwin-align-cast.c @@ -1,5 +1,4 @@ // RUN: %clang_cc1 -fsyntax-only -Wno-pointer-to-int-cast -verify %s -// expected-no-diagnostics typedef long unsigned int __darwin_size_t; typedef long __darwin_ssize_t; typedef __darwin_size_t size_t; @@ -18,6 +17,7 @@ ssize_t sendFileDescriptor(int fd, void *data, size_t nbytes, int sendfd) { union { + // expected-warning@+1 {{folded to constant array}} char control[(((__darwin_size_t)((char *)(sizeof(struct cmsghdr)) + (sizeof(__darwin_size_t) - 1)) &~ (sizeof(__darwin_size_t) - 1)) + ((__darwin_size_t)((char *)(sizeof(int)) + (sizeof(__darwin_size_t) - 1)) &~ (sizeof(__darwin_size_t) - 1)))]; } control_un; return 0; diff --git a/clang/test/Sema/decl-in-prototype.c b/clang/test/Sema/decl-in-prototype.c --- a/clang/test/Sema/decl-in-prototype.c +++ b/clang/test/Sema/decl-in-prototype.c @@ -49,7 +49,7 @@ // function. enum { BB = 0 }; void enum_in_fun_in_fun(void (*fp)(enum { AA, BB } e)) { // expected-warning {{will not be visible}} - SA(1, AA == 5); + SA(1, AA == 5); // expected-error {{variable-sized object may not be initialized}} SA(2, BB == 0); } diff --git a/clang/test/Sema/gnu-flags.c b/clang/test/Sema/gnu-flags.c --- a/clang/test/Sema/gnu-flags.c +++ b/clang/test/Sema/gnu-flags.c @@ -124,7 +124,9 @@ fic = (int)(0.75 * 1000 * 1000) }; static const int size = 100; -void foo(void) { int data[size]; } +int data[size]; + +void foo(void) { int data[size]; } // OK, always a VLA #if ALL || REDECLAREDENUM // expected-note@+4 {{previous definition is here}} diff --git a/clang/test/Sema/i-c-e.c b/clang/test/Sema/i-c-e.c --- a/clang/test/Sema/i-c-e.c +++ b/clang/test/Sema/i-c-e.c @@ -12,7 +12,7 @@ char v[sizeof(__builtin_constant_p(0)) == sizeof(int) ? 1 : -1]; int implicitConversion = 1.0; -char floatArith[(int)(1.0+2.0)]; // expected-warning {{must be an integer constant expression}} +char floatArith[(int)(1.0+2.0)]; // expected-warning {{variable length array folded to constant array as an extension}} // __builtin_constant_p as the condition of ?: allows arbitrary foldable // constants to be transmogrified into i-c-e's. @@ -57,7 +57,7 @@ int comma1[0?1,2:3]; int comma2[1||(1,2)]; // expected-warning {{use of logical '||' with constant operand}} \ // expected-note {{use '|' for a bitwise operation}} -int comma3[(1,2)]; // expected-warning {{size of static array must be an integer constant expression}} +int comma3[(1,2)]; // expected-warning {{variable length array folded to constant array as an extension}} // Pointer + __builtin_constant_p char pbcp[__builtin_constant_p(4) ? (intptr_t)&expr : 0]; // expected-error {{variable length array declaration not allowed at file scope}} diff --git a/clang/test/Sema/offsetof-64.c b/clang/test/Sema/offsetof-64.c --- a/clang/test/Sema/offsetof-64.c +++ b/clang/test/Sema/offsetof-64.c @@ -5,15 +5,15 @@ const unsigned long Size = (1l << 60); struct Chunk1 { - char padding[Size]; - char more_padding[1][Size]; + char padding[Size]; // expected-warning {{folded to constant}} + char more_padding[1][Size]; // expected-warning {{folded to constant}} char data; }; int test1 = __builtin_offsetof(struct Chunk1, data); struct Chunk2 { - char padding[Size][Size][Size]; // expected-error 2{{array is too large}} + char padding[Size][Size][Size]; // expected-error {{array is too large}} char data; }; diff --git a/clang/test/Sema/struct-decl.c b/clang/test/Sema/struct-decl.c --- a/clang/test/Sema/struct-decl.c +++ b/clang/test/Sema/struct-decl.c @@ -5,8 +5,8 @@ }; struct foo { - char name[(int)&((struct bar *)0)->n]; - char name2[(int)&((struct bar *)0)->n - 1]; //expected-error{{'name2' declared as an array with a negative size}} + char name[(int)&((struct bar *)0)->n]; // expected-warning {{folded to constant}} + char name2[(int)&((struct bar *)0)->n - 1]; // expected-error {{array size is negative}} }; // PR3430 diff --git a/clang/test/Sema/typedef-variable-type.c b/clang/test/Sema/typedef-variable-type.c --- a/clang/test/Sema/typedef-variable-type.c +++ b/clang/test/Sema/typedef-variable-type.c @@ -1,8 +1,8 @@ // RUN: %clang_cc1 %s -verify -fsyntax-only -pedantic -Wno-typedef-redefinition -std=c99 // Make sure we accept a single typedef -typedef int (*a)[!.0]; // expected-warning{{size of static array must be an integer constant expression}} +typedef int (*a)[!.0]; // expected-warning{{folded to constant array}} // And make sure we accept identical redefinitions in system headers // (The test uses -Wno-typedef-redefinition to simulate this.) -typedef int (*a)[!.0]; // expected-warning{{size of static array must be an integer constant expression}} +typedef int (*a)[!.0]; // expected-warning{{folded to constant array}} diff --git a/clang/test/Sema/vla.c b/clang/test/Sema/vla.c --- a/clang/test/Sema/vla.c +++ b/clang/test/Sema/vla.c @@ -53,7 +53,7 @@ int (*pr2044c(void))[pr2044b]; // expected-error {{variably modified type}} const int f5_ci = 1; -void f5() { char a[][f5_ci] = {""}; } // expected-warning {{variable length array folded to constant array as an extension}} +void f5() { char a[][f5_ci] = {""}; } // expected-error {{variable-sized object may not be initialized}} // PR5185 void pr5185(int a[*]); @@ -89,3 +89,14 @@ // Not illegal in C, program _might_ be well formed if size == 3. int (*p4)[2][size][3][4][5] = array; } + +void pr44406() { + goto L; // expected-error {{cannot jump}} + int z[(int)(1.0 * 2)]; // expected-note {{bypasses initialization of variable length array}} +L:; +} + +const int pr44406_a = 32; +typedef struct { + char c[pr44406_a]; // expected-warning {{folded to constant array as an extension}} +} pr44406_s; diff --git a/clang/test/SemaCXX/anonymous-struct.cpp b/clang/test/SemaCXX/anonymous-struct.cpp --- a/clang/test/SemaCXX/anonymous-struct.cpp +++ b/clang/test/SemaCXX/anonymous-struct.cpp @@ -131,6 +131,9 @@ typedef struct { // expected-error {{unsupported}} enum X {}; int arr[&f ? 1 : 2]; +#if __cplusplus < 201103L + // expected-warning@-2 {{folded to constant}} +#endif } C; // expected-note {{by this typedef}} } diff --git a/clang/test/SemaCXX/constant-expression.cpp b/clang/test/SemaCXX/constant-expression.cpp --- a/clang/test/SemaCXX/constant-expression.cpp +++ b/clang/test/SemaCXX/constant-expression.cpp @@ -110,7 +110,7 @@ const int recurse2 = recurse1; // expected-note {{here}} const int recurse1 = 1; int array1[recurse1]; // ok -int array2[recurse2]; // expected-warning {{variable length array}} expected-warning {{integer constant expression}} expected-note {{initializer of 'recurse2' is not a constant expression}} +int array2[recurse2]; // expected-warning 2{{variable length array}} expected-note {{initializer of 'recurse2' is not a constant expression}} namespace FloatConvert { typedef int a[(int)42.3]; diff --git a/clang/test/SemaCXX/cxx1z-noexcept-function-type.cpp b/clang/test/SemaCXX/cxx1z-noexcept-function-type.cpp --- a/clang/test/SemaCXX/cxx1z-noexcept-function-type.cpp +++ b/clang/test/SemaCXX/cxx1z-noexcept-function-type.cpp @@ -120,7 +120,7 @@ extern "C" int strncmp(const char *, const char *, decltype(sizeof(0))) noexcept; // Check we recognized both as builtins. - typedef int arr[strcmp("bar", "foo") + 4 * strncmp("foo", "bar", 4)]; + typedef int arr[strcmp("bar", "foo") + 4 * strncmp("foo", "bar", 4)]; // expected-warning {{variable length array}} typedef int arr[3]; } diff --git a/clang/test/SemaCXX/i-c-e-cxx.cpp b/clang/test/SemaCXX/i-c-e-cxx.cpp --- a/clang/test/SemaCXX/i-c-e-cxx.cpp +++ b/clang/test/SemaCXX/i-c-e-cxx.cpp @@ -80,7 +80,7 @@ #endif int PR8836test[(__typeof(sizeof(int)))&reinterpret_cast((((PR8836*)0)->a))]; -// expected-warning@-1 {{folded to constant array as an extension}} +// expected-warning@-1 0-1{{C99 feature}} expected-warning@-1 {{folded to constant array as an extension}} // expected-note@-2 {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}} const int nonconst = 1.0; @@ -89,7 +89,7 @@ #endif int arr[nonconst]; #if __cplusplus <= 199711L -// expected-warning@-2 {{folded to constant array as an extension}} +// expected-warning@-2 0-1{{C99 feature}} expected-warning@-2 {{folded to constant array as an extension}} // expected-note@-3 {{initializer of 'nonconst' is not a constant expression}} #endif diff --git a/clang/test/SemaObjC/gcc-cast-ext.m b/clang/test/SemaObjC/gcc-cast-ext.m --- a/clang/test/SemaObjC/gcc-cast-ext.m +++ b/clang/test/SemaObjC/gcc-cast-ext.m @@ -11,7 +11,7 @@ // GCC allows pointer expressions in integer constant expressions. struct { - char control[((int)(char *)2)]; + char control[((int)(char *)2)]; // expected-warning {{extension}} } xx; @implementation PBXDocBookmark // expected-warning {{method definition for 'autorelease' not found}}\