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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P4                          |P2

--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
With:
--- gcc/cfgexpand.c.jj  2021-05-20 09:03:54.147700369 +0200
+++ gcc/cfgexpand.c     2021-05-31 20:48:28.078548261 +0200
@@ -3082,6 +3082,7 @@ expand_asm_stmt (gasm *stmt)
   unsigned ninputs = gimple_asm_ninputs (stmt);
   unsigned nlabels = gimple_asm_nlabels (stmt);
   unsigned i;
+  bool error_seen = false;

   /* ??? Diagnose during gimplification?  */
   if (ninputs + noutputs + nlabels > MAX_RECOG_OPERANDS)
@@ -3140,6 +3141,7 @@ expand_asm_stmt (gasm *stmt)
                {
                  /* ??? Diagnose during gimplification?  */
                  error ("unknown register name %qs in %<asm%>", regname);
+                 error_seen = true;
                }
              else if (j == -4)
                {
@@ -3202,7 +3204,10 @@ expand_asm_stmt (gasm *stmt)
                && REG_P (DECL_RTL (output_tvec[j]))
                && HARD_REGISTER_P (DECL_RTL (output_tvec[j]))
                && output_hregno == REGNO (DECL_RTL (output_tvec[j])))
-             error ("invalid hard register usage between output operands");
+             {
+               error ("invalid hard register usage between output operands");
+               error_seen = true;
+             }

          /* Verify matching constraint operands use the same hard register
             and that the non-matching constraint operands do not use the same
@@ -3225,13 +3230,19 @@ expand_asm_stmt (gasm *stmt)
                  }
                if (i == match
                    && output_hregno != input_hregno)
-                 error ("invalid hard register usage between output operand "
-                        "and matching constraint operand");
+                 {
+                   error ("invalid hard register usage between output "
+                          "operand and matching constraint operand");
+                   error_seen = true;
+                 }
                else if (early_clobber_p
                         && i != match
                         && output_hregno == input_hregno)
-                 error ("invalid hard register usage between earlyclobber "
-                        "operand and input operand");
+                 {
+                   error ("invalid hard register usage between "
+                          "earlyclobber operand and input operand");
+                   error_seen = true;
+                 }
              }
        }

@@ -3307,7 +3318,10 @@ expand_asm_stmt (gasm *stmt)
            op = validize_mem (op);

          if (! allows_reg && !MEM_P (op))
-           error ("output number %d not directly addressable", i);
+           {
+             error ("output number %d not directly addressable", i);
+             error_seen = true;
+           }
          if ((! allows_mem && MEM_P (op) && GET_MODE (op) != BLKmode)
              || GET_CODE (op) == CONCAT)
            {
@@ -3347,6 +3361,19 @@ expand_asm_stmt (gasm *stmt)
        inout_opnum.safe_push (i);
     }

+  const char *str = gimple_asm_string (stmt);
+  if (error_seen)
+    {
+      ninputs = 0;
+      noutputs = 0;
+      inout_opnum.truncate (0);
+      output_rvec.truncate (0);
+      clobber_rvec.truncate (0);
+      constraints.truncate (0);
+      CLEAR_HARD_REG_SET (clobbered_regs);
+      str = "";
+    }
+
   auto_vec<rtx, MAX_RECOG_OPERANDS> input_rvec;
   auto_vec<machine_mode, MAX_RECOG_OPERANDS> input_mode;

@@ -3405,7 +3432,7 @@ expand_asm_stmt (gasm *stmt)
     }

   /* For in-out operands, copy output rtx to input rtx.  */
-  unsigned ninout = inout_opnum.length();
+  unsigned ninout = inout_opnum.length ();
   for (i = 0; i < ninout; i++)
     {
       int j = inout_opnum[i];
@@ -3459,7 +3486,7 @@ expand_asm_stmt (gasm *stmt)

   rtx body = gen_rtx_ASM_OPERANDS ((noutputs == 0 ? VOIDmode
                                    : GET_MODE (output_rvec[0])),
-                                  ggc_strdup (gimple_asm_string (stmt)),
+                                  ggc_strdup (str),
                                   "", 0, argvec, constraintvec,
                                   labelvec, locus);
   MEM_VOLATILE_P (body) = gimple_asm_volatile_p (stmt);

ICEs on:
/* PR inline-asm/100785 */

struct S { int a : 1; };

void
foo (struct S *x)
{
  __asm__ ("" : "+m" (x->a));   /* { dg-error "not directly addressable" } */
}

void
bar (struct S *x)
{
  __asm__ ("" : "=m" (x->a));   /* { dg-error "not directly addressable" } */
}

void
baz (struct S *x)
{
  __asm__ ("" : : "m" (x->a));  /* { dg-error "not directly addressable" } */
}

in foo and bar are fixed, but baz is actually not diagnosed at all and just
ICEs.
So bumping priority to P2, as this isn't error-recovery in the baz case
anymore.

Reply via email to