Support SSA name declarations with pointer type
authorRichard Biener <rguenther@suse.de>
Wed, 23 Feb 2022 10:05:50 +0000 (11:05 +0100)
committerRichard Biener <rguenther@suse.de>
Wed, 23 Feb 2022 11:15:30 +0000 (12:15 +0100)
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.

gcc/c/gimple-parser.cc
gcc/testsuite/gcc.dg/gimplefe-49.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gimplefe-error-13.c [new file with mode: 0644]

index 3107523..d1afd42 100644 (file)
@@ -330,13 +330,17 @@ c_parser_parse_gimple_body (c_parser *cparser, char *gimple_pass,
                  }
                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)
            if (!ssa_name (i))
              {
                tree name = make_ssa_name_fn (cfun, integer_type_node, NULL, i);
                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).  */
          bitmap_obstack_initialize (NULL);
          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
          table but we simply build the SSA name for later lookup.  */
       unsigned version, ver_offset;
-      if (declarator->kind == cdk_id
-         && is_gimple_reg_type (specs->type)
-         && c_parser_parse_ssa_name_id (declarator->u.id.id,
+      /* Handle SSA pointer declarations in a very simplistic ways, we
+        probably would like to call grokdeclarator in a special mode to
+        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)
          /* The following restricts it to unnamed anonymous SSA names
             which fails parsing of named ones in dumps (we could
             decide to not dump their name for -gimple).  */
          && 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
        {
          tree postfix_attrs = NULL_TREE;
diff --git a/gcc/testsuite/gcc.dg/gimplefe-49.c b/gcc/testsuite/gcc.dg/gimplefe-49.c
new file mode 100644 (file)
index 0000000..d28dc70
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.dg/gimplefe-error-13.c b/gcc/testsuite/gcc.dg/gimplefe-error-13.c
new file mode 100644 (file)
index 0000000..637ed32
--- /dev/null
@@ -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" } */