diff options
Diffstat (limited to 'gcc/cp/semantics.c')
| -rw-r--r-- | gcc/cp/semantics.c | 76 |
1 files changed, 59 insertions, 17 deletions
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index c82d2911381..2bb4051affc 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -894,23 +894,65 @@ finish_asm_stmt (cv_qualifier, string, output_operands, } if (!processing_template_decl) - for (t = input_operands; t; t = TREE_CHAIN (t)) - { - tree converted_operand - = decay_conversion (TREE_VALUE (t)); - - /* If the type of the operand hasn't been determined (e.g., - because it involves an overloaded function), then issue an - error message. There's no context available to resolve the - overloading. */ - if (TREE_TYPE (converted_operand) == unknown_type_node) - { - cp_error ("type of asm operand `%E' could not be determined", - TREE_VALUE (t)); - converted_operand = error_mark_node; - } - TREE_VALUE (t) = converted_operand; - } + { + int i; + int ninputs; + int noutputs; + + for (t = input_operands; t; t = TREE_CHAIN (t)) + { + tree converted_operand + = decay_conversion (TREE_VALUE (t)); + + /* If the type of the operand hasn't been determined (e.g., + because it involves an overloaded function), then issue + an error message. There's no context available to + resolve the overloading. */ + if (TREE_TYPE (converted_operand) == unknown_type_node) + { + cp_error ("type of asm operand `%E' could not be determined", + TREE_VALUE (t)); + converted_operand = error_mark_node; + } + TREE_VALUE (t) = converted_operand; + } + + ninputs = list_length (input_operands); + noutputs = list_length (output_operands); + + for (i = 0, t = output_operands; t; t = TREE_CHAIN (t), ++i) + { + bool allows_mem; + bool allows_reg; + bool is_inout; + const char *constraint; + tree operand; + + constraint = TREE_STRING_POINTER (TREE_PURPOSE (t)); + operand = TREE_VALUE (output_operands); + + if (!parse_output_constraint (&constraint, + i, ninputs, noutputs, + &allows_mem, + &allows_reg, + &is_inout)) + { + /* By marking the type as erroneous, we will not try to + process this operand again in expand_asm_operands. */ + TREE_TYPE (operand) = error_mark_node; + continue; + } + + /* 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 (operand)) + mark_addressable (operand); + } + } r = build_stmt (ASM_STMT, cv_qualifier, string, output_operands, input_operands, |

