From 77103685ff4b50b3c4d7ee76688bdf452acc82c7 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 5 Jun 2020 16:36:27 -0400 Subject: [PATCH] tree-inline: Fix VLA handling [PR95552] The problem in this testcase comes from cloning the constructor into complete and base variants. When we clone the body the first time, walk_tree_1 calls copy_tree_body_r on the type of the artificial TYPE_DECL we made for the VLA type without calling it on the decl itself, so we overwrite the type of the TYPE_DECL without copying the decl first. This has been broken since we started inserting a TYPE_DECL for anonymous VLAs in r7-457. This patch fixes walk_tree_1 to call the function on the TYPE_DECL, as we do for other decls of a DECL_EXPR. gcc/ChangeLog: PR c++/95552 * tree.c (walk_tree_1): Call func on the TYPE_DECL of a DECL_EXPR. gcc/testsuite/ChangeLog: PR c++/95552 * g++.dg/ext/vla23.C: New test. --- gcc/testsuite/g++.dg/ext/vla23.C | 14 ++++++++++++++ gcc/tree.c | 6 ++++++ 2 files changed, 20 insertions(+) create mode 100644 gcc/testsuite/g++.dg/ext/vla23.C diff --git a/gcc/testsuite/g++.dg/ext/vla23.C b/gcc/testsuite/g++.dg/ext/vla23.C new file mode 100644 index 00000000000..317a824b2f3 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vla23.C @@ -0,0 +1,14 @@ +// PR c++/95552 +// Test for VLA and cloned constructor. +// { dg-additional-options -Wno-vla } +// { dg-require-effective-target alloca } + +struct VB { }; +struct ViewDom: virtual VB +{ + ViewDom(int i) { char (*a)[i]; } +}; +void element( ) +{ + ViewDom a(2); +} diff --git a/gcc/tree.c b/gcc/tree.c index 7197b4720ce..805f669a945 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -12212,6 +12212,12 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data, Note that DECLs get walked as part of processing the BIND_EXPR. */ if (TREE_CODE (DECL_EXPR_DECL (*tp)) == TYPE_DECL) { + /* Call the function for the decl so e.g. copy_tree_body_r can + replace it with the remapped one. */ + result = (*func) (&DECL_EXPR_DECL (*tp), &walk_subtrees, data); + if (result || !walk_subtrees) + return result; + tree *type_p = &TREE_TYPE (DECL_EXPR_DECL (*tp)); if (TREE_CODE (*type_p) == ERROR_MARK) return NULL_TREE; -- 2.30.2