summaryrefslogtreecommitdiffstats
path: root/gcc/c-typeck.c
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2004-12-29 01:22:15 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2004-12-29 01:22:15 +0000
commit8b0d0af63af4bfde34f0c935c2cd27b6dc6b226d (patch)
tree54bc73bf49c5c1cd15ddc720798149307cd44186 /gcc/c-typeck.c
parente3165e92adecec5bf4ae7a8732fa353d21a12c3e (diff)
downloadppe42-gcc-8b0d0af63af4bfde34f0c935c2cd27b6dc6b226d.tar.gz
ppe42-gcc-8b0d0af63af4bfde34f0c935c2cd27b6dc6b226d.zip
PR inline-asm/15740
* gimplify.c (gimplify_asm_expr): Move resolve asm names ... * c-typeck.c (build_asm_expr): ... here. Validate input constraints. Mark memory inputs addressable. * semantics.c (finish_asm_stmt): Resolve asm names. Validate input constraints. Mark memory inputs addressable. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@92693 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c-typeck.c')
-rw-r--r--gcc/c-typeck.c72
1 files changed, 50 insertions, 22 deletions
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index d2963b37454..5eae3aa7d5e 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -6287,47 +6287,74 @@ build_asm_expr (tree string, tree outputs, tree inputs, tree clobbers,
tree args;
int i;
const char *constraint;
+ const char **oconstraints;
bool allows_mem, allows_reg, is_inout;
- int ninputs;
- int noutputs;
+ int ninputs, noutputs;
ninputs = list_length (inputs);
noutputs = list_length (outputs);
+ oconstraints = (const char **) alloca (noutputs * sizeof (const char *));
+
+ string = resolve_asm_operand_names (string, outputs, inputs);
/* Remove output conversions that change the type but not the mode. */
for (i = 0, tail = outputs; tail; ++i, tail = TREE_CHAIN (tail))
{
tree output = TREE_VALUE (tail);
+
+ /* ??? Really, this should not be here. Users should be using a
+ proper lvalue, dammit. But there's a long history of using casts
+ in the output operands. In cases like longlong.h, this becomes a
+ primitive form of typechecking -- if the cast can be removed, then
+ the output operand had a type of the proper width; otherwise we'll
+ get an error. Gross, but ... */
STRIP_NOPS (output);
- TREE_VALUE (tail) = output;
- lvalue_or_else (output, lv_asm);
+
+ if (!lvalue_or_else (output, lv_asm))
+ output = error_mark_node;
constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (tail)));
+ oconstraints[i] = constraint;
- if (!parse_output_constraint (&constraint, i, ninputs, noutputs,
- &allows_mem, &allows_reg, &is_inout))
- {
- /* By marking this operand as erroneous, we will not try
- to process this operand again in expand_asm_operands. */
- TREE_VALUE (tail) = error_mark_node;
- continue;
- }
+ if (parse_output_constraint (&constraint, i, ninputs, noutputs,
+ &allows_mem, &allows_reg, &is_inout))
+ {
+ /* If the operand is going to end up in memory,
+ mark it addressable. */
+ if (!allows_reg && !c_mark_addressable (output))
+ output = error_mark_node;
+ }
+ else
+ output = error_mark_node;
- /* If the operand is a DECL that is going to end up in
- memory, assume it is addressable. This is a bit more
- conservative than it would ideally be; the exact test is
- buried deep in expand_asm_operands and depends on the
- DECL_RTL for the OPERAND -- which we don't have at this
- point. */
- if (!allows_reg && DECL_P (output))
- c_mark_addressable (output);
+ TREE_VALUE (tail) = output;
}
/* Perform default conversions on array and function inputs.
Don't do this for other types as it would screw up operands
expected to be in memory. */
- for (tail = inputs; tail; tail = TREE_CHAIN (tail))
- TREE_VALUE (tail) = default_function_array_conversion (TREE_VALUE (tail));
+ for (i = 0, tail = inputs; tail; ++i, tail = TREE_CHAIN (tail))
+ {
+ tree input;
+
+ constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (tail)));
+ input = TREE_VALUE (tail);
+
+ input = default_function_array_conversion (input);
+
+ if (parse_input_constraint (&constraint, i, ninputs, noutputs, 0,
+ oconstraints, &allows_mem, &allows_reg))
+ {
+ /* If the operand is going to end up in memory,
+ mark it addressable. */
+ if (!allows_reg && allows_mem && !c_mark_addressable (input))
+ input = error_mark_node;
+ }
+ else
+ input = error_mark_node;
+
+ TREE_VALUE (tail) = input;
+ }
args = build_stmt (ASM_EXPR, string, outputs, inputs, clobbers);
@@ -6337,6 +6364,7 @@ build_asm_expr (tree string, tree outputs, tree inputs, tree clobbers,
ASM_VOLATILE_P (args) = 1;
ASM_INPUT_P (args) = 1;
}
+
return args;
}
OpenPOWER on IntegriCloud