This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[committed] FIx a tree sharing issue in generic-match.c (PR c++/80297)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Richard Biener <rguenther at suse dot de>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Tue, 4 Apr 2017 21:18:02 +0200
- Subject: [committed] FIx a tree sharing issue in generic-match.c (PR c++/80297)
- Authentication-results: sourceware.org; auth=none
- Authentication-results: ext-mx06.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com
- Authentication-results: ext-mx06.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=jakub at redhat dot com
- Dkim-filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 741E43D967
- Dmarc-filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 741E43D967
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
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