[COMMITTED] c++: Fix cast to pointer to VLA.
Jason Merrill
jason@redhat.com
Mon Feb 3 14:20:00 GMT 2020
The C front-end fixed this issue in r257620 by adding a DECL_EXPR from
grokdeclarator. We don't have an easy way to do that in the C++ front-end,
but it works fine to create and prepend a DECL_EXPR when we are genericizing
the NOP_EXPR for the cast.
The C patch wraps the DECL_EXPR in a BIND_EXPR, but that seems unnecessary
in C++; this is just a hook to run gimplify_type_sizes, we aren't actually
declaring anything that we need to worry about scoping for.
Tested x86_64-pc-linux-gnu, applying to trunk.
PR c++/88256
* cp-gimplify.c (predeclare_vla): New.
(cp_genericize_r) [NOP_EXPR]: Call it.
---
gcc/cp/cp-gimplify.c | 31 +++++++++++++++++++
.../compile => c-c++-common}/pr84305.c | 2 ++
2 files changed, 33 insertions(+)
rename gcc/testsuite/{gcc.c-torture/compile => c-c++-common}/pr84305.c (78%)
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index 4fb3a1a8b8a..10ab99515e6 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -1188,6 +1188,36 @@ static tree genericize_spaceship (tree expr)
return genericize_spaceship (type, op0, op1);
}
+/* If EXPR involves an anonymous VLA type, prepend a DECL_EXPR for that type
+ to trigger gimplify_type_sizes; otherwise a cast to pointer-to-VLA confuses
+ the middle-end (c++/88256). */
+
+static tree
+predeclare_vla (tree expr)
+{
+ tree type = TREE_TYPE (expr);
+ if (type == error_mark_node)
+ return expr;
+
+ /* We need to strip pointers for gimplify_type_sizes. */
+ tree vla = type;
+ while (POINTER_TYPE_P (vla))
+ {
+ if (TYPE_NAME (vla))
+ return expr;
+ vla = TREE_TYPE (vla);
+ }
+ if (TYPE_NAME (vla) || !variably_modified_type_p (vla, NULL_TREE))
+ return expr;
+
+ tree decl = build_decl (input_location, TYPE_DECL, NULL_TREE, vla);
+ DECL_ARTIFICIAL (decl) = 1;
+ TYPE_NAME (vla) = decl;
+ tree dexp = build_stmt (input_location, DECL_EXPR, decl);
+ expr = build2 (COMPOUND_EXPR, type, dexp, expr);
+ return expr;
+}
+
/* Perform any pre-gimplification lowering of C++ front end trees to
GENERIC. */
@@ -1648,6 +1678,7 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
break;
case NOP_EXPR:
+ *stmt_p = predeclare_vla (*stmt_p);
if (!wtd->no_sanitize_p
&& sanitize_flags_p (SANITIZE_NULL | SANITIZE_ALIGNMENT)
&& TYPE_REF_P (TREE_TYPE (stmt)))
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr84305.c b/gcc/testsuite/c-c++-common/pr84305.c
similarity index 78%
rename from gcc/testsuite/gcc.c-torture/compile/pr84305.c
rename to gcc/testsuite/c-c++-common/pr84305.c
index 374fa67f593..27150dd5328 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr84305.c
+++ b/gcc/testsuite/c-c++-common/pr84305.c
@@ -1,3 +1,5 @@
+// { dg-additional-options -O3 }
+
int res, a, b;
void *foo;
static void f2 (int arg) { res = ((int (*)[arg][b]) foo)[0][0][0]; }
base-commit: 44f77a6dea2f312ee1743f3dde465c1b8453ee13
--
2.18.1
More information about the Gcc-patches
mailing list