This fixes PR60750 by removing the premature (and bogus) optimization
of omitting VDEFs for noreturn calls (in this case the call is still
returning via EH and you also have to consider it returning abnormally).

Bootstrap & regtest running on x86_64-unknown-linux-gnu.

Richard.

2014-04-04  Richard Biener  <rguent...@suse.de>

        PR middle-end/60750
        * tree-ssa-operands.c (maybe_add_call_vops): Also add VDEFs
        for noreturn calls.
        * tree-cfgcleanup.c (fixup_noreturn_call): Do not remove VDEFs.

        * g++.dg/torture/pr60750.C: New testcase.

Index: gcc/tree-ssa-operands.c
===================================================================
*** gcc/tree-ssa-operands.c     (revision 209059)
--- gcc/tree-ssa-operands.c     (working copy)
*************** maybe_add_call_vops (struct function *fn
*** 648,657 ****
       call-clobbered.  */
    if (!(call_flags & ECF_NOVOPS))
      {
!       /* A 'pure' or a 'const' function never call-clobbers anything.
!        A 'noreturn' function might, but since we don't return anyway
!        there is no point in recording that.  */
!       if (!(call_flags & (ECF_PURE | ECF_CONST | ECF_NORETURN)))
        add_virtual_operand (fn, stmt, opf_def);
        else if (!(call_flags & ECF_CONST))
        add_virtual_operand (fn, stmt, opf_use);
--- 649,656 ----
       call-clobbered.  */
    if (!(call_flags & ECF_NOVOPS))
      {
!       /* A 'pure' or a 'const' function never call-clobbers anything.  */
!       if (!(call_flags & (ECF_PURE | ECF_CONST)))
        add_virtual_operand (fn, stmt, opf_def);
        else if (!(call_flags & ECF_CONST))
        add_virtual_operand (fn, stmt, opf_use);
Index: gcc/tree-cfgcleanup.c
===================================================================
*** gcc/tree-cfgcleanup.c       (revision 209059)
--- gcc/tree-cfgcleanup.c       (working copy)
*************** fixup_noreturn_call (gimple stmt)
*** 586,594 ****
        update_stmt (stmt);
        changed = true;
      }
-   /* Similarly remove VDEF if there is any.  */
-   else if (gimple_vdef (stmt))
-     update_stmt (stmt);
    return changed;
  }
  
--- 592,597 ----
Index: gcc/testsuite/g++.dg/torture/pr60750.C
===================================================================
*** gcc/testsuite/g++.dg/torture/pr60750.C      (revision 0)
--- gcc/testsuite/g++.dg/torture/pr60750.C      (working copy)
***************
*** 0 ****
--- 1,21 ----
+ // { dg-do run }
+ // { dg-options "-std=c++11" }
+ 
+ #include <string>
+ #include <stdexcept>
+ 
+ const std::string err_prefix = "Problem: ";
+ void thrower (std::string msg)
+ {
+   throw std::runtime_error(err_prefix + std::move(msg));
+ }
+ 
+ int main(int argc, char **argv)
+ {
+   try {
+       std::string base = "hello";
+       thrower(std::move(base));
+   } catch (const std::runtime_error &e) {
+   }
+   return 0;
+ }

Reply via email to