[Bug c++/106057] New: Missed stmt_can_throw_external check in stmt_kills_ref_p

hubicka at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Wed Jun 22 16:26:28 GMT 2022


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106057

            Bug ID: 106057
           Summary: Missed stmt_can_throw_external check in
                    stmt_kills_ref_p
           Product: gcc
           Version: 13.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: hubicka at gcc dot gnu.org
  Target Milestone: ---

int a;
int b;

__attribute__((const))
int maybethrow()
{
        if (!b)
                throw(0);
        return 0;
}

void
test()
{
        a=1;
        a=maybethrow();
        a=0;
}
int
main()
{
        try {
                test();
        }
        catch(int) {
                if (!a)
                        __builtin_abort ();
        }
        return 0;
}

aborts when built with -O2 while I think it should not.  The bug is that
 a=maybethrow()
is considered a kill which it is not since exception happens earlier.

I think we need:
diff --git a/gcc/tree-ssa-alias.cc b/gcc/tree-ssa-alias.cc
index b1e7a2d5afc..7307e386f96 100644
--- a/gcc/tree-ssa-alias.cc
+++ b/gcc/tree-ssa-alias.cc
@@ -3337,7 +3338,9 @@ stmt_kills_ref_p (gimple *stmt, ao_ref *ref)
         ???  We only need to care about the RHS throwing.  For aggregate
         assignments or similar calls and non-call exceptions the LHS
         might throw as well.  */
-      && !stmt_can_throw_internal (cfun, stmt))
+      && !stmt_can_throw_internal (cfun, stmt)
+      && (!stmt_can_throw_external (cfun, stmt)
+         || !ref_may_alias_global_p (ref, false)))
     {
       tree lhs = gimple_get_lhs (stmt);
       /* If LHS is literally a base of the access we are done.  */


More information about the Gcc-bugs mailing list