This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[tree-ssa] fix some asm failures


Don't abort on stupid user tricks.  The gimplifier issues an error
and then smashes the offending asm statement away, so noone else
has to care.


r~


        * gimplify.c (gimplify_expr): Return bool.  Bail gracefully if
        fb_mayfail is set.
        (gimplify_asm_expr): Take pointer-to-expr.  Allow gimplify_expr
        to fail for lvalues, and issue appropriate error messages.  Zap
        the entire asm statement on failure.
        * tree-simple.h (enum fallback_t): Add fb_mayfail.

        * gcc.dg/asm-7.c: Update expected error text.

Index: gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/gimplify.c,v
retrieving revision 1.1.2.94
diff -u -p -r1.1.2.94 gimplify.c
--- gimplify.c	14 Oct 2003 07:14:23 -0000	1.1.2.94
+++ gimplify.c	15 Oct 2003 03:06:09 -0000
@@ -58,7 +58,7 @@ static void gimplify_return_expr (tree, 
 static tree build_addr_expr (tree);
 static tree build_addr_expr_with_type (tree, tree);
 static tree add_stmt_to_compound (tree, tree);
-static void gimplify_asm_expr (tree, tree *, tree *);
+static void gimplify_asm_expr (tree *, tree *, tree *);
 static void gimplify_bind_expr (tree *, tree *);
 static inline void remove_suffix (char *, int);
 static void push_gimplify_context (void);
@@ -326,7 +326,7 @@ gimplify_stmt (tree *stmt_p)
         bit is set, an rvalue is OK.  If the 2 bit is set, an lvalue is OK.
         If both are set, either is OK, but an lvalue is preferable.  */
 
-int
+bool
 gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
 	       int (* gimple_test_f) (tree), fallback_t fallback)
 {
@@ -337,9 +337,10 @@ gimplify_expr (tree *expr_p, tree *pre_p
   int is_statement = (pre_p == NULL);
   location_t *locus;
   location_t saved_location;
+  bool ret_ok = true;
 
   if (*expr_p == NULL_TREE)
-    return 1;
+    return true;
 
   /* Go ahead and strip type nops before we test our predicate.  */
   STRIP_MAIN_TYPE_NOPS (*expr_p);
@@ -582,7 +583,7 @@ gimplify_expr (tree *expr_p, tree *pre_p
 	  break;
 
 	case ASM_EXPR:
-	  gimplify_asm_expr (*expr_p, pre_p, post_p);
+	  gimplify_asm_expr (expr_p, pre_p, post_p);
 	  break;
 
 	case TRY_FINALLY_EXPR:
@@ -744,6 +745,13 @@ gimplify_expr (tree *expr_p, tree *pre_p
       else
 	*expr_p = get_formal_tmp_var (*expr_p, pre_p);
     }
+  else if (fallback & fb_mayfail)
+    {
+      /* If this is an asm statement, and the user asked for the impossible,
+	 don't abort.  Fail and let gimplify_asm_expr issue an error.  */
+      ret_ok = false;
+      goto out;
+    }
   else
     {
       fprintf (stderr, "gimplification failed:\n");
@@ -766,7 +774,7 @@ gimplify_expr (tree *expr_p, tree *pre_p
 
  out:
   input_location = saved_location;
-  return 1;
+  return ret_ok;
 }
 
 /* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both
@@ -2219,20 +2227,22 @@ gimplify_addr_expr (tree *expr_p, tree *
    value; output operands should be a gimple lvalue.  */
 
 static void
-gimplify_asm_expr (tree expr, tree *pre_p, tree *post_p)
+gimplify_asm_expr (tree *expr_p, tree *pre_p, tree *post_p)
 {
+  tree expr = *expr_p;
   int noutputs = list_length (ASM_OUTPUTS (expr));
   const char **oconstraints
     = (const char **) alloca ((noutputs) * sizeof (const char *));
   int i;
   tree link;
   const char *constraint;
-  bool allows_mem, allows_reg, is_inout;
+  bool allows_mem, allows_reg, is_inout, success;
 
   ASM_STRING (expr)
     = resolve_asm_operand_names (ASM_STRING (expr), ASM_OUTPUTS (expr),
 				 ASM_INPUTS (expr));
 
+  success = true;
   for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = TREE_CHAIN (link))
     {
       oconstraints[i] = constraint
@@ -2244,8 +2254,12 @@ gimplify_asm_expr (tree expr, tree *pre_
       if (!allows_reg && allows_mem)
 	(*lang_hooks.mark_addressable) (TREE_VALUE (link));
 
-      gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
-		     is_gimple_lvalue, fb_lvalue);
+      if (!gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
+			  is_gimple_lvalue, fb_lvalue | fb_mayfail))
+	{
+	  error ("invalid lvalue in asm output %d", i);
+	  success = false;
+	}
 
       if (is_inout && allows_reg)
 	{
@@ -2269,7 +2283,7 @@ gimplify_asm_expr (tree expr, tree *pre_
 	}
     }
 
-  for (link = ASM_INPUTS (expr); link; link = TREE_CHAIN (link))
+  for (link = ASM_INPUTS (expr); link; ++i, link = TREE_CHAIN (link))
     {
       constraint
 	= TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
@@ -2280,13 +2294,21 @@ gimplify_asm_expr (tree expr, tree *pre_
       if (!allows_reg && allows_mem)
 	{
 	  (*lang_hooks.mark_addressable) (TREE_VALUE (link));
-	  gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
-			 is_gimple_lvalue, fb_lvalue);
+	  if (!gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
+			      is_gimple_lvalue, fb_lvalue | fb_mayfail))
+	    {
+	      error ("memory input %d is not directly addressable", i);
+	      success = false;
+	    }
 	}
       else
 	gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
 		       is_gimple_val, fb_rvalue);
     }
+
+  /* If we encountered an invalid asm, don't hork the optimizers.  */
+  if (!success)
+    *expr_p = build_empty_stmt ();
 }
 
 /* If EXPR is a boolean expression, make sure it has BOOLEAN_TYPE.  */
Index: tree-simple.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-simple.h,v
retrieving revision 1.1.4.33
diff -u -p -r1.1.4.33 tree-simple.h
--- tree-simple.h	14 Oct 2003 00:12:58 -0000	1.1.4.33
+++ tree-simple.h	15 Oct 2003 03:06:09 -0000
@@ -83,11 +83,12 @@ void add_tree (tree, tree *);
 /* FIXME we should deduce this from the predicate.  */
 typedef enum fallback_t {
   fb_none = 0,
-  fb_rvalue=1,
-  fb_lvalue=2,
-  fb_either=1|2
+  fb_rvalue = 1,
+  fb_lvalue = 2,
+  fb_mayfail = 4,
+  fb_either= fb_rvalue | fb_lvalue
 } fallback_t;
-int gimplify_expr (tree *, tree *, tree *, int (*) (tree), fallback_t);
+bool gimplify_expr (tree *, tree *, tree *, int (*) (tree), fallback_t);
 int gimplify_stmt (tree *);
 int gimplify_body (tree *, tree);
 
Index: testsuite/gcc.dg/asm-7.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/asm-7.c,v
retrieving revision 1.3.6.1
diff -u -p -r1.3.6.1 asm-7.c
--- testsuite/gcc.dg/asm-7.c	21 Jul 2003 13:52:28 -0000	1.3.6.1
+++ testsuite/gcc.dg/asm-7.c	15 Oct 2003 03:06:30 -0000
@@ -12,8 +12,8 @@ void test(void)
   __asm__ ("" : : "m"(r));	/* { dg-warning "address of register" } */
   __asm__ ("" : : "m"(i));
   __asm__ ("" : : "m"(m));
-  __asm__ ("" : : "m"(0));	/* { dg-warning "input without lvalue" } */
-  __asm__ ("" : : "m"(i+1));	/* { dg-warning "input without lvalue" } */
+  __asm__ ("" : : "m"(0));	/* { dg-error "" } */
+  __asm__ ("" : : "m"(i+1));	/* { dg-error "" } */
   __asm__ ("" : : "m"(*p++));
 
   __asm__ ("" : : "g"(r));


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]