summaryrefslogtreecommitdiff
path: root/gcc/tree-nested.c
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2006-12-21 13:13:15 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2006-12-21 13:13:15 +0000
commit2c84951a3d95a39e4bb81af7a41ae4ae569898be (patch)
tree69466bf4e0591fc2f8589b38412c0b9a5d416980 /gcc/tree-nested.c
parent98154846568061a379099dc36ace942b0f07e826 (diff)
downloadgcc-2c84951a3d95a39e4bb81af7a41ae4ae569898be.tar.gz
PR middle-end/30262
PR middle-end/30263 * tree-nested.c (walk_asm_expr): New function. (walk_stmts): Use it for ASM_EXPR. * gcc.c-torture/execute/20061220-1.c: New test. * gcc.dg/gomp/asm-1.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@120106 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-nested.c')
-rw-r--r--gcc/tree-nested.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
index 42aef328841..166debb22c0 100644
--- a/gcc/tree-nested.c
+++ b/gcc/tree-nested.c
@@ -546,6 +546,47 @@ get_nl_goto_field (struct nesting_info *info)
return field;
}
+/* Helper function for walk_stmts. Walk output operands of an ASM_EXPR. */
+
+static void
+walk_asm_expr (struct walk_stmt_info *wi, tree stmt)
+{
+ int noutputs = list_length (ASM_OUTPUTS (stmt));
+ const char **oconstraints
+ = (const char **) alloca ((noutputs) * sizeof (const char *));
+ int i;
+ tree link;
+ const char *constraint;
+ bool allows_mem, allows_reg, is_inout;
+
+ wi->is_lhs = true;
+ for (i=0, link = ASM_OUTPUTS (stmt); link; ++i, link = TREE_CHAIN (link))
+ {
+ constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
+ oconstraints[i] = constraint;
+ parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
+ &allows_reg, &is_inout);
+
+ wi->val_only = (allows_reg || !allows_mem);
+ walk_tree (&TREE_VALUE (link), wi->callback, wi, NULL);
+ }
+
+ for (link = ASM_INPUTS (stmt); link; link = TREE_CHAIN (link))
+ {
+ constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
+ parse_input_constraint (&constraint, 0, 0, noutputs, 0,
+ oconstraints, &allows_mem, &allows_reg);
+
+ wi->val_only = (allows_reg || !allows_mem);
+ /* Although input "m" is not really a LHS, we need a lvalue. */
+ wi->is_lhs = !wi->val_only;
+ walk_tree (&TREE_VALUE (link), wi->callback, wi, NULL);
+ }
+
+ wi->is_lhs = false;
+ wi->val_only = true;
+}
+
/* Iterate over all sub-statements of *TP calling walk_tree with
WI->CALLBACK for every sub-expression in each statement found. */
@@ -628,6 +669,10 @@ walk_stmts (struct walk_stmt_info *wi, tree *tp)
wi->is_lhs = false;
break;
+ case ASM_EXPR:
+ walk_asm_expr (wi, *tp);
+ break;
+
default:
wi->val_only = true;
walk_tree (tp, wi->callback, wi, NULL);