[GIMPLE FE] avoid ICE with same ssa version number for multiple names

Prathamesh Kulkarni prathamesh.kulkarni@linaro.org
Wed Feb 15 12:15:00 GMT 2017


Hi,
For the following (invalid) test-case:

void __GIMPLE () foo (int a)
{
  int t0;
  int _1;
  _1 = a;
  t0_1 = a;
}

results in following ICE:
gimplefe-error-4.c: In function ‘foo’:
gimplefe-error-4.c:20:1: error: SSA_NAME_DEF_STMT is wrong
 }
 ^
Expected definition statement:
_1 = a_2(D);

Actual definition statement:
_1 = a_2(D);
gimplefe-error-4.c:20:1: internal compiler error: verify_ssa failed
0xe1458b verify_ssa(bool, bool)
../../gcc/gcc/tree-ssa.c:1184
0xb0d1ed execute_function_todo
../../gcc/gcc/passes.c:1973
0xb0dad5 execute_todo
../../gcc/gcc/passes.c:2016

The reason for ICE is that in c_parser_parse_ssa_name, ssa_name (1)
returns tree node for _1, and "t0_1" gets replaced by "_1"
resulting in multiple definitions for _1.

The attached patch checks if multiple ssa names have same version
number and emits a diagnostic in that case, for the above case:
gimplefe-error-4.c: In function ‘foo’:
gimplefe-error-4.c:10:3: error: ssa version ‘1’ used anonymously and in ‘t0’
   t0_1 = a;
   ^~~~

OK to commit after bootstrap+test ?

Thanks,
Prathamesh
-------------- next part --------------
2017-02-15  Prathamesh Kulkarni  <prathamesh.kulkarni@linaro.org>

c/
	* gimple-parser.c (c_parser_parse_ssa_name): Emit diagnostic if same
	ssa version is used with multiple names.

testsuite/
	* gcc.dg/gimplefe-error-4.c: New test.

diff --git a/gcc/c/gimple-parser.c b/gcc/c/gimple-parser.c
index d959877..2e163f4 100644
--- a/gcc/c/gimple-parser.c
+++ b/gcc/c/gimple-parser.c
@@ -672,29 +672,49 @@ c_parser_parse_ssa_name (c_parser *parser,
     }
   else
     {
+      /* Separate var name from version.  */
+      char *var_name = XNEWVEC (char, ver_offset + 1);
+      memcpy (var_name, token, ver_offset);
+      var_name[ver_offset] = '\0';
+      /* lookup for parent decl.  */
+      id = get_identifier (var_name);
+      tree parent = lookup_name (id);
+      if (! parent || parent == error_mark_node)
+	{
+	  c_parser_error (parser, "base variable or SSA name undeclared");
+	  XDELETEVEC (var_name);
+	  return error_mark_node;
+	}
       if (version < num_ssa_names)
 	name = ssa_name (version);
       if (! name)
 	{
-	  /* Separate var name from version.  */
-	  char *var_name = XNEWVEC (char, ver_offset + 1);
-	  memcpy (var_name, token, ver_offset);
-	  var_name[ver_offset] = '\0';
-	  /* lookup for parent decl.  */
-	  id = get_identifier (var_name);
-	  tree parent = lookup_name (id);
-	  XDELETEVEC (var_name);
-	  if (! parent || parent == error_mark_node)
-	    {
-	      c_parser_error (parser, "base variable or SSA name undeclared"); 
-	      return error_mark_node;
-	    }
 	  if (VECTOR_TYPE_P (TREE_TYPE (parent))
 	      || TREE_CODE (TREE_TYPE (parent)) == COMPLEX_TYPE)
 	    DECL_GIMPLE_REG_P (parent) = 1;
 	  name = make_ssa_name_fn (cfun, parent,
 				   gimple_build_nop (), version);
 	}
+      else if (!SSA_NAME_IDENTIFIER (name))
+ 	{
+	  error_at (input_location, "ssa version %<%d%> used anonymously"
+		    " and in %<%s%>", version, var_name);
+	  XDELETEVEC (var_name);
+	  return error_mark_node;
+	}
+      else
+	{
+	  const char *ssaname = IDENTIFIER_POINTER (SSA_NAME_IDENTIFIER (name));
+	  if (strcmp (ssaname, var_name))
+	    {
+	      error_at (input_location, "ssa version %<%d%> used for"
+			" multiple names %<%s%>, %<%s%>", version,
+			ssaname, var_name);
+	      XDELETEVEC (var_name);
+	      return error_mark_node;
+	    }
+	}
+      XDELETEVEC (var_name);
     }
 
   return name;
diff --git a/gcc/testsuite/gcc.dg/gimplefe-error-4.c b/gcc/testsuite/gcc.dg/gimplefe-error-4.c
new file mode 100644
index 0000000..a3c652e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gimplefe-error-4.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-fgimple" } */
+
+void __GIMPLE () foo (int a)
+{
+  int t0;
+  int _1;
+
+  _1 = a;
+  t0_1 = a; /* { dg-error "used anonymously and in 't0'" } */
+}
+
+void __GIMPLE () bar (int a)
+{
+  int t0;
+  int t1;
+
+  t0_1 = a;
+  t1_1 = a; /* { dg-error "multiple names 't0', 't1'" } */
+}


More information about the Gcc-patches mailing list