From e1201dff2f7404ab263a8e75e97e4c0ad72c7e72 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 4 Apr 2017 21:14:47 +0200 Subject: [PATCH] re PR c++/80297 (Compiler time crash: type mismatch in binary expression) 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. Co-Authored-By: Richard Biener From-SVN: r246693 --- gcc/ChangeLog | 8 ++++++++ gcc/generic-match-head.c | 1 + gcc/genmatch.c | 13 ++++++++++++- gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/g++.dg/torture/pr80297.C | 12 ++++++++++++ 5 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/torture/pr80297.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d537ac5099a..ac9ab8ad960 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2017-04-04 Jakub Jelinek + Richard Biener + + 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. + 2017-04-04 Jakub Jelinek PR tree-optimization/79390 diff --git a/gcc/generic-match-head.c b/gcc/generic-match-head.c index 1392d029f3e..04e0854fd75 100644 --- a/gcc/generic-match-head.c +++ b/gcc/generic-match-head.c @@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see #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 diff --git a/gcc/genmatch.c b/gcc/genmatch.c index 93d5b21d0be..5621aa05b59 100644 --- a/gcc/genmatch.c +++ b/gcc/genmatch.c @@ -2525,7 +2525,18 @@ capture::gen_transform (FILE *f, int indent, const char *dest, bool gimple, } } - 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. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6d1ed2227b7..bdb1c01c6e6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2017-04-04 Jakub Jelinek + PR c++/80297 + * g++.dg/torture/pr80297.C: New test. + PR tree-optimization/79390 * gcc.target/i386/pr79390.c: New test. * gcc.dg/ifcvt-4.c: Use -mtune-ctrl=^one_if_conv_insn for i?86/x86_64. diff --git a/gcc/testsuite/g++.dg/torture/pr80297.C b/gcc/testsuite/g++.dg/torture/pr80297.C new file mode 100644 index 00000000000..3b246e4b638 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr80297.C @@ -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; +}