Commit 5544530a by Paolo Bonzini Committed by Paolo Bonzini

re PR c/21419 (Accepts writting to const via asm)

2005-10-05  Paolo Bonzini  <bonzini@gnu.org>

	PR tree-optimization/21419
	PR tree-optimization/24146
	PR tree-optimization/24151

	* c-typeck.c (readonly_error): Handle USE being lv_asm.
	(build_asm_expr): Call it if outputs are read-only.
	* gimplify.c (gimplify_asm_expr): Remove former fix to PR 21419.

cp:
2005-10-05  Paolo Bonzini  <bonzini@gnu.org>

	PR tree-optimization/21419
	PR tree-optimization/24146
	PR tree-optimization/24151

	* semantics.c (finish_asm_stmt): Call readonly_error if outputs are
	read-only.  Set ASM_VOLATILE_P for asms without outputs.

testsuite:
2005-10-05  Paolo Bonzini  <bonzini@gnu.org>

	PR tree-optimization/21419
	PR tree-optimization/24146
	PR tree-optimization/24151

	* g++.dg/ext/asm7.C: New.
	* g++.dg/ext/asm8.C: New.
	* gcc.dg/asm-1.c: Compile on all targets.
	* gcc.dg/asm-pr24146.c: New.
	* gcc.dg/pr21419.c: Adjust error messages.

From-SVN: r104988
parent c82cdb5d
2005-10-05 Paolo Bonzini <bonzini@gnu.org>
PR tree-optimization/21419
PR tree-optimization/24146
PR tree-optimization/24151
* c-typeck.c (readonly_error): Handle USE being lv_asm.
(build_asm_expr): Call it if outputs are read-only.
* gimplify.c (gimplify_asm_expr): Remove former fix to PR 21419.
2005-10-05 Billy Biggs <billy.biggs@gmail.com> 2005-10-05 Billy Biggs <billy.biggs@gmail.com>
Paolo Bonzini <bonzini@gnu.org> Paolo Bonzini <bonzini@gnu.org>
......
...@@ -2982,13 +2982,14 @@ lvalue_p (tree ref) ...@@ -2982,13 +2982,14 @@ lvalue_p (tree ref)
static void static void
readonly_error (tree arg, enum lvalue_use use) readonly_error (tree arg, enum lvalue_use use)
{ {
gcc_assert (use == lv_assign || use == lv_increment || use == lv_decrement); gcc_assert (use == lv_assign || use == lv_increment || use == lv_decrement
|| use == lv_asm);
/* Using this macro rather than (for example) arrays of messages /* Using this macro rather than (for example) arrays of messages
ensures that all the format strings are checked at compile ensures that all the format strings are checked at compile
time. */ time. */
#define READONLY_MSG(A, I, D) (use == lv_assign \ #define READONLY_MSG(A, I, D, AS) (use == lv_assign ? (A) \
? (A) \ : (use == lv_increment ? (I) \
: (use == lv_increment ? (I) : (D))) : (use == lv_decrement ? (D) : (AS))))
if (TREE_CODE (arg) == COMPONENT_REF) if (TREE_CODE (arg) == COMPONENT_REF)
{ {
if (TYPE_READONLY (TREE_TYPE (TREE_OPERAND (arg, 0)))) if (TYPE_READONLY (TREE_TYPE (TREE_OPERAND (arg, 0))))
...@@ -2996,18 +2997,21 @@ readonly_error (tree arg, enum lvalue_use use) ...@@ -2996,18 +2997,21 @@ readonly_error (tree arg, enum lvalue_use use)
else else
error (READONLY_MSG (G_("assignment of read-only member %qD"), error (READONLY_MSG (G_("assignment of read-only member %qD"),
G_("increment of read-only member %qD"), G_("increment of read-only member %qD"),
G_("decrement of read-only member %qD")), G_("decrement of read-only member %qD"),
G_("read-only member %qD used as %<asm%> output")),
TREE_OPERAND (arg, 1)); TREE_OPERAND (arg, 1));
} }
else if (TREE_CODE (arg) == VAR_DECL) else if (TREE_CODE (arg) == VAR_DECL)
error (READONLY_MSG (G_("assignment of read-only variable %qD"), error (READONLY_MSG (G_("assignment of read-only variable %qD"),
G_("increment of read-only variable %qD"), G_("increment of read-only variable %qD"),
G_("decrement of read-only variable %qD")), G_("decrement of read-only variable %qD"),
G_("read-only variable %qD used as %<asm%> output")),
arg); arg);
else else
error (READONLY_MSG (G_("assignment of read-only location"), error (READONLY_MSG (G_("assignment of read-only location"),
G_("increment of read-only location"), G_("increment of read-only location"),
G_("decrement of read-only location"))); G_("decrement of read-only location"),
G_("read-only location used as %<asm%> output")));
} }
...@@ -6691,6 +6695,14 @@ build_asm_expr (tree string, tree outputs, tree inputs, tree clobbers, ...@@ -6691,6 +6695,14 @@ build_asm_expr (tree string, tree outputs, tree inputs, tree clobbers,
if (!lvalue_or_else (output, lv_asm)) if (!lvalue_or_else (output, lv_asm))
output = error_mark_node; output = error_mark_node;
if (output != error_mark_node
&& (TREE_READONLY (output)
|| TYPE_READONLY (TREE_TYPE (output))
|| ((TREE_CODE (TREE_TYPE (output)) == RECORD_TYPE
|| TREE_CODE (TREE_TYPE (output)) == UNION_TYPE)
&& C_TYPE_FIELDS_READONLY (TREE_TYPE (output)))))
readonly_error (output, lv_asm);
constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (tail))); constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (tail)));
oconstraints[i] = constraint; oconstraints[i] = constraint;
...@@ -6737,12 +6749,10 @@ build_asm_expr (tree string, tree outputs, tree inputs, tree clobbers, ...@@ -6737,12 +6749,10 @@ build_asm_expr (tree string, tree outputs, tree inputs, tree clobbers,
args = build_stmt (ASM_EXPR, string, outputs, inputs, clobbers); args = build_stmt (ASM_EXPR, string, outputs, inputs, clobbers);
/* Simple asm statements are treated as volatile. */ /* asm statements without outputs, including simple ones, are treated
if (simple) as volatile. */
{ ASM_INPUT_P (args) = simple;
ASM_VOLATILE_P (args) = 1; ASM_VOLATILE_P (args) = (noutputs == 0);
ASM_INPUT_P (args) = 1;
}
return args; return args;
} }
......
2005-10-05 Paolo Bonzini <bonzini@gnu.org>
PR tree-optimization/21419
PR tree-optimization/24146
PR tree-optimization/24151
* semantics.c (finish_asm_stmt): Call readonly_error if outputs are
read-only. Set ASM_VOLATILE_P for asms without outputs.
2005-10-05 Nathan Sidwell <nathan@codesourcery.com> 2005-10-05 Nathan Sidwell <nathan@codesourcery.com>
PR c++/23513 PR c++/23513
......
...@@ -1165,18 +1165,17 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands, ...@@ -1165,18 +1165,17 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands,
{ {
tree r; tree r;
tree t; tree t;
int ninputs = list_length (input_operands);
int noutputs = list_length (output_operands);
if (!processing_template_decl) if (!processing_template_decl)
{ {
int ninputs, noutputs;
const char *constraint; const char *constraint;
const char **oconstraints; const char **oconstraints;
bool allows_mem, allows_reg, is_inout; bool allows_mem, allows_reg, is_inout;
tree operand; tree operand;
int i; int i;
ninputs = list_length (input_operands);
noutputs = list_length (output_operands);
oconstraints = (const char **) alloca (noutputs * sizeof (char *)); oconstraints = (const char **) alloca (noutputs * sizeof (char *));
string = resolve_asm_operand_names (string, output_operands, string = resolve_asm_operand_names (string, output_operands,
...@@ -1197,6 +1196,19 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands, ...@@ -1197,6 +1196,19 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands,
if (!lvalue_or_else (operand, lv_asm)) if (!lvalue_or_else (operand, lv_asm))
operand = error_mark_node; operand = error_mark_node;
if (operand != error_mark_node
&& (TREE_READONLY (operand)
|| CP_TYPE_CONST_P (TREE_TYPE (operand))
/* Functions are not modifiable, even though they are
lvalues. */
|| TREE_CODE (TREE_TYPE (operand)) == FUNCTION_TYPE
|| TREE_CODE (TREE_TYPE (operand)) == METHOD_TYPE
/* If it's an aggregate and any field is const, then it is
effectively const. */
|| (CLASS_TYPE_P (TREE_TYPE (operand))
&& C_TYPE_FIELDS_READONLY (TREE_TYPE (operand)))))
readonly_error (operand, "assignment (via 'asm' output)", 0);
constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t))); constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
oconstraints[i] = constraint; oconstraints[i] = constraint;
...@@ -1254,7 +1266,7 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands, ...@@ -1254,7 +1266,7 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands,
r = build_stmt (ASM_EXPR, string, r = build_stmt (ASM_EXPR, string,
output_operands, input_operands, output_operands, input_operands,
clobbers); clobbers);
ASM_VOLATILE_P (r) = volatile_p; ASM_VOLATILE_P (r) = volatile_p || noutputs == 0;
r = maybe_cleanup_point_expr_void (r); r = maybe_cleanup_point_expr_void (r);
return add_stmt (r); return add_stmt (r);
} }
......
...@@ -3604,12 +3604,6 @@ gimplify_asm_expr (tree *expr_p, tree *pre_p, tree *post_p) ...@@ -3604,12 +3604,6 @@ gimplify_asm_expr (tree *expr_p, tree *pre_p, tree *post_p)
parse_output_constraint (&constraint, i, 0, 0, parse_output_constraint (&constraint, i, 0, 0,
&allows_mem, &allows_reg, &is_inout); &allows_mem, &allows_reg, &is_inout);
if (TYPE_READONLY (TREE_TYPE (TREE_VALUE (link))))
{
error ("invalid lvalue in asm output %d", i);
ret = GS_ERROR;
}
if (!allows_reg && allows_mem) if (!allows_reg && allows_mem)
lang_hooks.mark_addressable (TREE_VALUE (link)); lang_hooks.mark_addressable (TREE_VALUE (link));
......
2005-10-05 Paolo Bonzini <bonzini@gnu.org>
PR tree-optimization/21419
PR tree-optimization/24146
PR tree-optimization/24151
* g++.dg/ext/asm7.C: New.
* g++.dg/ext/asm8.C: New.
* gcc.dg/asm-1.c: Compile on all targets.
* gcc.dg/asm-pr24146.c: New.
* gcc.dg/pr21419.c: Adjust error messages.
2005-10-05 Richard Guenther <rguenther@suse.de> 2005-10-05 Richard Guenther <rguenther@suse.de>
PR fortran/24176 PR fortran/24176
/* { dg-do compile } */
const int i = 0;
void f(void)
{
__asm__ __volatile__ ("" : "=m" (i)); /* { dg-error "read-only variable" } */
}
void g(const int set)
{
__asm__ __volatile__ ("" : "=r" (set)); /* { dg-error "read-only parameter" } */
}
/* { dg-do compile } */
/* Test that asm with no outputs are treated as volatile. */
void f(int x)
{
__asm__ ("extended asm not discarded" : : "r" (x));
}
void g (void)
{
__asm__ ("simple asm not discarded");
}
/* { dg-final { scan-assembler "extended asm not discarded" } } */
/* { dg-final { scan-assembler "simple asm not discarded" } } */
/* { dg-do compile { target i?86-*-* x86_64-*-* } } */ /* { dg-do compile } */
struct x { struct x {
int selector; int selector;
......
/* { dg-do compile } */
/* Test that asm with no outputs are treated as volatile. */
void f(int x)
{
__asm__ ("extended asm not discarded" : : "r" (x));
}
void g (void)
{
__asm__ ("simple asm not discarded");
}
/* { dg-final { scan-assembler "extended asm not discarded" } } */
/* { dg-final { scan-assembler "simple asm not discarded" } } */
...@@ -3,13 +3,13 @@ const int i = 0; ...@@ -3,13 +3,13 @@ const int i = 0;
void f(void) void f(void)
{ {
__asm__ __volatile__ ("" : "=m" (i)); /* { dg-error "invalid lvalue in asm output" } */ __asm__ __volatile__ ("" : "=m" (i)); /* { dg-error "read-only variable" } */
} }
void g(const int set) void g(const int set)
{ {
__asm__ __volatile__ ("" : "=r" (set)); /* { dg-error "invalid lvalue in asm output" } */ __asm__ __volatile__ ("" : "=r" (set)); /* { dg-error "read-only location" } */
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment