From: Jason Merrill Date: Fri, 31 Jan 2020 22:10:30 +0000 (-0500) Subject: c++: Fix sizeof VLA lambda capture. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=00a49cd840f60774b0e9e0109fb10559bc9a9194;p=gcc.git c++: Fix sizeof VLA lambda capture. sizeof a VLA type is not a constant in C or the GNU C++ extension, so we need to capture the VLA even in unevaluated context. For PR60855 we stopped looking through a previous capture, but we also need to capture the first time the variable is mentioned. PR c++/86216 * semantics.c (process_outer_var_ref): Capture VLAs even in unevaluated context. --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index cae1c918d30..999348d2e29 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2020-01-31 Jason Merrill + PR c++/86216 + * semantics.c (process_outer_var_ref): Capture VLAs even in + unevaluated context. + PR c++/14179 * decl.c (reshape_init_array_1): Reuse a single CONSTRUCTOR with non-aggregate elements. diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index a489e2cf399..90f1e18e48a 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -3524,8 +3524,15 @@ tree process_outer_var_ref (tree decl, tsubst_flags_t complain, bool odr_use) { if (cp_unevaluated_operand) - /* It's not a use (3.2) if we're in an unevaluated context. */ - return decl; + { + tree type = TREE_TYPE (decl); + if (!dependent_type_p (type) + && variably_modified_type_p (type, NULL_TREE)) + /* VLAs are used even in unevaluated context. */; + else + /* It's not a use (3.2) if we're in an unevaluated context. */ + return decl; + } if (decl == error_mark_node) return decl; diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-vla5.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-vla5.C new file mode 100644 index 00000000000..f3390b2d09f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-vla5.C @@ -0,0 +1,13 @@ +// PR c++/86216 +// { dg-do compile { target c++11 } } +// { dg-additional-options -Wno-vla } + +template void b(int n, T arg) { + int buffer[arg]; + int buffer2[arg][arg]; + [&] { + n = sizeof(buffer); + n = sizeof(buffer2); // { dg-bogus "sorry" "" { xfail *-*-* } } + }(); +} +int main() { b(2, 3); }