This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[tree-ssa] fix some asm failures
- From: Richard Henderson <rth at twiddle dot net>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 14 Oct 2003 20:16:26 -0700
- Subject: [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));