This patch extends the generation of exception handling information to
cover all asm statements, when -fnon-call-exceptions is given.  The
previous patch only enabled this for volatile asms.

The previously added test cases are adjusted to cover this change.

gcc/
2020-03-11  Jan W. Jagersma  <jwjager...@gmail.com>

        PR inline-asm/93981
        * tree-eh.c (tree_could_trap_p): Return true for case ASM_EXPR.
        (stmt_could_throw_p): Likewise, for GIMPLE_ASM.
        * rtlanal.c (may_trap_p_1): Likewise, for ASM_OPERANDS.
        * doc/extend.texi: Document this change in the appropriate
        subsection.

gcc/testsuite/
2020-03-11  Jan W. Jagersma  <jwjager...@gmail.com>

        PR inline-asm/93981
        * g++.dg/eh/pr93981.C: Cover non-volatile throwing asms.
        * g++.target/i386/pr93981.C: Likewise.
---
 gcc/doc/extend.texi                     | 10 +++----
 gcc/rtlanal.c                           |  4 +--
 gcc/testsuite/g++.dg/eh/pr93981.C       | 22 ++++++++++++---
 gcc/testsuite/g++.target/i386/pr93981.C | 36 ++++++++++++++++++++++---
 gcc/tree-eh.c                           |  4 +--
 5 files changed, 60 insertions(+), 16 deletions(-)

diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index b51e34c617a..43929d9b129 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -9454,6 +9454,11 @@ printf("%d\n", dst);
 
 This code copies @code{src} to @code{dst} and add 1 to @code{dst}.
 
+When non-call exceptions (@option{-fnon-call-exceptions}) are enabled, an
+@code{asm} statement is also allowed to throw exceptions.  If it does, then its
+register output operands are assumed to be clobbered and will not be used.
+Memory operands, however, are always considered valid.
+
 @anchor{Volatile}
 @subsubsection Volatile
 @cindex volatile @code{asm}
@@ -9577,11 +9582,6 @@ errors during compilation if your @code{asm} code 
defines symbols or labels.
 Using @samp{%=} 
 (@pxref{AssemblerTemplate}) may help resolve this problem.
 
-When non-call exceptions (@option{-fnon-call-exceptions}) are enabled, a
-@code{volatile asm} statement is also allowed to throw exceptions.  If it does,
-then its register output operands are assumed to be clobbered and will not be
-used.  Memory operands, however, are always considered valid.
-
 @anchor{AssemblerTemplate}
 @subsubsection Assembler Template
 @cindex @code{asm} assembler template
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index c7ab86e228b..e7eb2dad11b 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -2831,13 +2831,11 @@ may_trap_p_1 (const_rtx x, unsigned flags)
       return targetm.unspec_may_trap_p (x, flags);
 
     case UNSPEC_VOLATILE:
+    case ASM_OPERANDS:
     case ASM_INPUT:
     case TRAP_IF:
       return 1;
 
-    case ASM_OPERANDS:
-      return MEM_VOLATILE_P (x);
-
       /* Memory ref can trap unless it's a static var or a stack slot.  */
     case MEM:
       /* Recognize specific pattern of stack checking probes.  */
diff --git a/gcc/testsuite/g++.dg/eh/pr93981.C 
b/gcc/testsuite/g++.dg/eh/pr93981.C
index a9adb5c069e..2e0d1cb881c 100644
--- a/gcc/testsuite/g++.dg/eh/pr93981.C
+++ b/gcc/testsuite/g++.dg/eh/pr93981.C
@@ -3,7 +3,7 @@
 // { dg-options "-fnon-call-exceptions" }
 
 void
-f ()
+foo ()
 {
   try
     {
@@ -11,8 +11,24 @@ f ()
     }
   catch (...)
     {
-      asm ("#catch");
+      asm ("#catch-v");
     }
 }
 
-// { dg-final { scan-assembler "#catch" } }
+int
+bar ()
+{
+  int i;
+  try
+    {
+      asm ("#try" : "=rm" (i));
+    }
+  catch (...)
+    {
+      asm ("#catch-nv");
+    }
+  return i;
+}
+
+// { dg-final { scan-assembler "#catch-v" } }
+// { dg-final { scan-assembler "#catch-nv" } }
diff --git a/gcc/testsuite/g++.target/i386/pr93981.C 
b/gcc/testsuite/g++.target/i386/pr93981.C
index 7a3117901f9..e4b5d7cd90f 100644
--- a/gcc/testsuite/g++.target/i386/pr93981.C
+++ b/gcc/testsuite/g++.target/i386/pr93981.C
@@ -15,7 +15,7 @@ sigill (int)
 }
 
 int
-test_mem ()
+test_mem_v ()
 {
   int i = 2;
   try
@@ -30,7 +30,7 @@ test_mem ()
 }
 
 int
-test_reg ()
+test_reg_v ()
 {
   int i = 8;
   try
@@ -44,6 +44,36 @@ test_reg ()
   return i;
 }
 
+int
+test_mem_nv ()
+{
+  int i = 32;
+  try
+    {
+      asm ("mov%z0 $16, %0; ud2" : "=m" (i));
+    }
+  catch (const illegal_opcode&)
+    {
+      if (i == 16) return 0;
+    }
+  return i;
+}
+
+int
+test_reg_nv ()
+{
+  int i = 128;
+  try
+    {
+      asm ("mov%z0 $64, %0; ud2" : "=r" (i));
+    }
+  catch (const illegal_opcode&)
+    {
+      if (i == 128) return 0;
+    }
+  return i;
+}
+
 int
 main ()
 {
@@ -51,5 +81,5 @@ main ()
   sa.sa_handler = sigill;
   sa.sa_flags = SA_NODEFER;
   sigaction (SIGILL, &sa, 0);
-  return test_mem () | test_reg ();
+  return test_mem_v () | test_reg_v () | test_mem_nv () | test_reg_nv ();
 }
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index 58b16aa763a..b2e17099320 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -2760,7 +2760,7 @@ tree_could_trap_p (tree expr)
       return !TREE_THIS_NOTRAP (expr);
 
     case ASM_EXPR:
-      return TREE_THIS_VOLATILE (expr);
+      return true;
 
     case CALL_EXPR:
       t = get_callee_fndecl (expr);
@@ -2964,7 +2964,7 @@ stmt_could_throw_p (function *fun, gimple *stmt)
     case GIMPLE_ASM:
       if (fun && !fun->can_throw_non_call_exceptions)
         return false;
-      return gimple_asm_volatile_p (as_a <gasm *> (stmt));
+      return true;
 
     default:
       return false;
-- 
2.25.1

Reply via email to