mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-22 15:00:55 +08:00
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.
This commit is contained in:
parent
44f77a6dea
commit
3539fc1317
@ -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
|
||||
|
@ -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)))
|
||||
|
@ -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]; }
|
Loading…
x
Reference in New Issue
Block a user