[committed] FIx a tree sharing issue in generic-match.c (PR c++/80297)

Jakub Jelinek jakub@redhat.com
Tue Apr 4 19:18:00 GMT 2017


Hi!

While generic tree sharing is usually harmless, because we unshare
everything before gimplification, on the following testcase a match.pd
pattern that uses @1 twice introduces tree sharing during the C
gimplification langhook, so after everything has been unshared.

The following patch fixes it by unsharing uses of captures except for the
last use.  Bootstrapped/regtested on x86_64-linux and i686-linux, acked
by Richard in the PR, committed to trunk.

2017-04-04  Jakub Jelinek  <jakub@redhat.com>
	    Richard Biener  <rguenther@suse.de>

	PR c++/80297
	* genmatch.c (capture::gen_transform): For GENERIC unshare_expr
	captures used multiple times, except for the last use.
	* generic-match-head.c: Include gimplify.h.

	* g++.dg/torture/pr80297.C: New test.

--- gcc/genmatch.c.jj	2017-03-19 11:57:19.000000000 +0100
+++ gcc/genmatch.c	2017-04-04 13:23:15.053251358 +0200
@@ -2525,7 +2525,18 @@ capture::gen_transform (FILE *f, int ind
 	}
     }
 
-  fprintf_indent (f, indent, "%s = captures[%u];\n", dest, where);
+  /* If in GENERIC some capture is used multiple times, unshare it except
+     when emitting the last use.  */
+  if (!gimple
+      && cinfo->info.exists ()
+      && cinfo->info[cinfo->info[where].same_as].result_use_count > 1)
+    {
+      fprintf_indent (f, indent, "%s = unshare_expr (captures[%u]);\n",
+		      dest, where);
+      cinfo->info[cinfo->info[where].same_as].result_use_count--;
+    }
+  else
+    fprintf_indent (f, indent, "%s = captures[%u];\n", dest, where);
 
   /* ???  Stupid tcc_comparison GENERIC trees in COND_EXPRs.  Deal
      with substituting a capture of that.  */
--- gcc/generic-match-head.c.jj	2017-01-01 12:45:38.000000000 +0100
+++ gcc/generic-match-head.c	2017-04-04 13:18:38.437884559 +0200
@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3.
 #include "builtins.h"
 #include "dumpfile.h"
 #include "case-cfn-macros.h"
+#include "gimplify.h"
 
 
 /* Routine to determine if the types T1 and T2 are effectively
--- gcc/testsuite/g++.dg/torture/pr80297.C.jj	2017-04-04 13:47:45.254048537 +0200
+++ gcc/testsuite/g++.dg/torture/pr80297.C	2017-04-04 13:47:29.000000000 +0200
@@ -0,0 +1,12 @@
+// PR c++/80297
+// { dg-do compile }
+
+extern const unsigned long int b;
+extern const long long int c;
+
+int
+foo ()
+{
+  int a = 809 >> -(b & !c) + b - (long long)(b & !c);
+  return a;
+}

	Jakub



More information about the Gcc-patches mailing list