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:
Richard Biener 2022-02-23 11:05:50 +01:00
parent 6e80c4f1ad
commit f4ed267fa5
3 changed files with 66 additions and 6 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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" } */