Support SSA name declarations with pointer type
Currently we fail to parse int * _3; as SSA name and instead get a VAR_DECL because of the way the C frontends declarator specs work. That causes havoc if those supposed SSA names are used in PHIs or in other places where VAR_DECLs are not allowed. The following fixes the pointer case in an ad-hoc way - for more complex type declarators we probably have to find a way to re-use the C frontend grokdeclarator without actually creating a VAR_DECL there (or maybe make it create an SSA name). Pointers appear too often to be neglected though, thus the following ad-hoc fix for this. This also adds verification that we do not end up with SSA names without definitions as can happen when reducing a GIMPLE testcase. Instead of working through segfaults one-by-one we emit errors for all of those at once now. 2022-02-23 Richard Biener <rguenther@suse.de> gcc/c * gimple-parser.cc (c_parser_parse_gimple_body): Diagnose SSA names without definition. (c_parser_gimple_declaration): Handle pointer typed SSA names. gcc/testsuite/ * gcc.dg/gimplefe-49.c: New testcase. * gcc.dg/gimplefe-error-13.c: Likewise.
This commit is contained in:
parent
6e80c4f1ad
commit
f4ed267fa5
|
@ -330,13 +330,17 @@ c_parser_parse_gimple_body (c_parser *cparser, char *gimple_pass,
|
||||||
}
|
}
|
||||||
gsi_remove (&gsi, true);
|
gsi_remove (&gsi, true);
|
||||||
}
|
}
|
||||||
/* Fill SSA name gaps, putting them on the freelist. */
|
/* Fill SSA name gaps, putting them on the freelist and diagnose
|
||||||
|
SSA names without definition. */
|
||||||
for (unsigned i = 1; i < num_ssa_names; ++i)
|
for (unsigned i = 1; i < num_ssa_names; ++i)
|
||||||
if (!ssa_name (i))
|
if (!ssa_name (i))
|
||||||
{
|
{
|
||||||
tree name = make_ssa_name_fn (cfun, integer_type_node, NULL, i);
|
tree name = make_ssa_name_fn (cfun, integer_type_node, NULL, i);
|
||||||
release_ssa_name_fn (cfun, name);
|
release_ssa_name_fn (cfun, name);
|
||||||
}
|
}
|
||||||
|
else if (!SSA_NAME_DEF_STMT (ssa_name (i)))
|
||||||
|
error ("SSA name %qE with version %d has no definition",
|
||||||
|
ssa_name (i), i);
|
||||||
/* No explicit virtual operands (yet). */
|
/* No explicit virtual operands (yet). */
|
||||||
bitmap_obstack_initialize (NULL);
|
bitmap_obstack_initialize (NULL);
|
||||||
update_ssa (TODO_update_ssa_only_virtuals);
|
update_ssa (TODO_update_ssa_only_virtuals);
|
||||||
|
@ -2061,16 +2065,34 @@ c_parser_gimple_declaration (gimple_parser &parser)
|
||||||
/* Handle SSA name decls specially, they do not go into the identifier
|
/* Handle SSA name decls specially, they do not go into the identifier
|
||||||
table but we simply build the SSA name for later lookup. */
|
table but we simply build the SSA name for later lookup. */
|
||||||
unsigned version, ver_offset;
|
unsigned version, ver_offset;
|
||||||
if (declarator->kind == cdk_id
|
/* Handle SSA pointer declarations in a very simplistic ways, we
|
||||||
&& is_gimple_reg_type (specs->type)
|
probably would like to call grokdeclarator in a special mode to
|
||||||
&& c_parser_parse_ssa_name_id (declarator->u.id.id,
|
just build the type of the decl - start_decl already pushes
|
||||||
|
the identifier to the bindings for lookup, something we do not
|
||||||
|
want. */
|
||||||
|
struct c_declarator *id_declarator = declarator;
|
||||||
|
while (id_declarator->kind == cdk_pointer)
|
||||||
|
id_declarator = id_declarator->declarator;
|
||||||
|
if (id_declarator->kind == cdk_id
|
||||||
|
&& (declarator->kind == cdk_pointer
|
||||||
|
|| is_gimple_reg_type (specs->type))
|
||||||
|
&& c_parser_parse_ssa_name_id (id_declarator->u.id.id,
|
||||||
&version, &ver_offset)
|
&version, &ver_offset)
|
||||||
/* The following restricts it to unnamed anonymous SSA names
|
/* The following restricts it to unnamed anonymous SSA names
|
||||||
which fails parsing of named ones in dumps (we could
|
which fails parsing of named ones in dumps (we could
|
||||||
decide to not dump their name for -gimple). */
|
decide to not dump their name for -gimple). */
|
||||||
&& ver_offset == 0)
|
&& ver_offset == 0)
|
||||||
c_parser_parse_ssa_name (parser, declarator->u.id.id, specs->type,
|
{
|
||||||
version, ver_offset);
|
struct c_declarator *p = declarator;
|
||||||
|
tree type = specs->type;
|
||||||
|
while (p->kind == cdk_pointer)
|
||||||
|
{
|
||||||
|
type = build_pointer_type (type);
|
||||||
|
p = p->declarator;
|
||||||
|
}
|
||||||
|
c_parser_parse_ssa_name (parser, id_declarator->u.id.id, type,
|
||||||
|
version, ver_offset);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tree postfix_attrs = NULL_TREE;
|
tree postfix_attrs = NULL_TREE;
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-options "-fgimple" } */
|
||||||
|
|
||||||
|
__GIMPLE (ssa) int *
|
||||||
|
bar (int i, int a, int b)
|
||||||
|
{
|
||||||
|
int * _3;
|
||||||
|
int *p;
|
||||||
|
|
||||||
|
__BB(2):
|
||||||
|
if (i_24(D) <= 0)
|
||||||
|
goto __BB3;
|
||||||
|
else
|
||||||
|
goto __BB4;
|
||||||
|
|
||||||
|
__BB(3):
|
||||||
|
_3 = &a;
|
||||||
|
goto __BB5;
|
||||||
|
|
||||||
|
__BB(4):
|
||||||
|
p_4 = &b;
|
||||||
|
goto __BB5;
|
||||||
|
|
||||||
|
__BB(5):
|
||||||
|
p_5 = __PHI (__BB3: _3, __BB4: p_4);
|
||||||
|
return p_5;
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-options "-fgimple" } */
|
||||||
|
|
||||||
|
__GIMPLE (ssa) void
|
||||||
|
bar (void)
|
||||||
|
{
|
||||||
|
int _3;
|
||||||
|
|
||||||
|
__BB(2):
|
||||||
|
return;
|
||||||
|
} /* { dg-error "version 3 has no definition" } */
|
Loading…
Reference in New Issue