diff options
author | Jason Merrill <jason@redhat.com> | 2020-01-31 21:59:48 -0500 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2020-02-03 09:21:06 -0500 |
commit | 3539fc1317267b30eb7c4ad48d52f4e46b3a198a (patch) | |
tree | 7bb9a2798fc1b9e3a94539e44b31f861b3f99194 /gcc | |
parent | 44f77a6dea2f312ee1743f3dde465c1b8453ee13 (diff) | |
download | gcc-3539fc1317267b30eb7c4ad48d52f4e46b3a198a.zip gcc-3539fc1317267b30eb7c4ad48d52f4e46b3a198a.tar.gz gcc-3539fc1317267b30eb7c4ad48d52f4e46b3a198a.tar.bz2 |
c++: Fix cast to pointer to VLA.
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.
PR c++/88256
* cp-gimplify.c (predeclare_vla): New.
(cp_genericize_r) [NOP_EXPR]: Call it.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/cp-gimplify.c | 31 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/pr84305.c (renamed from gcc/testsuite/gcc.c-torture/compile/pr84305.c) | 2 |
3 files changed, 39 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4e2b0c5..3144688 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2020-02-03 Jason Merrill <jason@redhat.com> + + PR c++/88256 + * cp-gimplify.c (predeclare_vla): New. + (cp_genericize_r) [NOP_EXPR]: Call it. + 2020-02-03 Jun Ma <JunMa@linux.alibaba.com> * coroutines.cc (transform_await_wrapper): Set actor funcion as diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index 4fb3a1a..10ab995 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 index 374fa67..27150dd 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]; } |