aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4>2005-10-05 12:17:16 +0000
committerbonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4>2005-10-05 12:17:16 +0000
commit89552023e3b457cea4844ab574b86bd3039497fa (patch)
tree56889bd0e587b4c391a24d46c92ac8f2af4f0978
parent7098b9ea217715357c201c4a9f24d557ce1f797f (diff)
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@104988 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/c-typeck.c36
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/semantics.c20
-rw-r--r--gcc/gimplify.c6
-rw-r--r--gcc/testsuite/ChangeLog12
-rw-r--r--gcc/testsuite/g++.dg/ext/asm7.C14
-rw-r--r--gcc/testsuite/g++.dg/ext/asm8.C16
-rw-r--r--gcc/testsuite/gcc.dg/asm-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/asm-pr24146.c16
-rw-r--r--gcc/testsuite/gcc.dg/pr21419.c4
11 files changed, 119 insertions, 26 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 24f14e9b83d..4a87d1f8b54 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+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>
Paolo Bonzini <bonzini@gnu.org>
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index a72dac6aa67..8a90476181f 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -2982,13 +2982,14 @@ lvalue_p (tree ref)
static void
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
ensures that all the format strings are checked at compile
time. */
-#define READONLY_MSG(A, I, D) (use == lv_assign \
- ? (A) \
- : (use == lv_increment ? (I) : (D)))
+#define READONLY_MSG(A, I, D, AS) (use == lv_assign ? (A) \
+ : (use == lv_increment ? (I) \
+ : (use == lv_decrement ? (D) : (AS))))
if (TREE_CODE (arg) == COMPONENT_REF)
{
if (TYPE_READONLY (TREE_TYPE (TREE_OPERAND (arg, 0))))
@@ -2996,18 +2997,21 @@ readonly_error (tree arg, enum lvalue_use use)
else
error (READONLY_MSG (G_("assignment 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));
}
else if (TREE_CODE (arg) == VAR_DECL)
error (READONLY_MSG (G_("assignment 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);
else
error (READONLY_MSG (G_("assignment 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,
if (!lvalue_or_else (output, lv_asm))
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)));
oconstraints[i] = constraint;
@@ -6737,12 +6749,10 @@ build_asm_expr (tree string, tree outputs, tree inputs, tree clobbers,
args = build_stmt (ASM_EXPR, string, outputs, inputs, clobbers);
- /* Simple asm statements are treated as volatile. */
- if (simple)
- {
- ASM_VOLATILE_P (args) = 1;
- ASM_INPUT_P (args) = 1;
- }
+ /* asm statements without outputs, including simple ones, are treated
+ as volatile. */
+ ASM_INPUT_P (args) = simple;
+ ASM_VOLATILE_P (args) = (noutputs == 0);
return args;
}
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index c79a926c136..3a1737d49e1 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,12 @@
+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>
PR c++/23513
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index c7392b034ce..80885c564a7 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -1165,18 +1165,17 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands,
{
tree r;
tree t;
+ int ninputs = list_length (input_operands);
+ int noutputs = list_length (output_operands);
if (!processing_template_decl)
{
- int ninputs, noutputs;
const char *constraint;
const char **oconstraints;
bool allows_mem, allows_reg, is_inout;
tree operand;
int i;
- ninputs = list_length (input_operands);
- noutputs = list_length (output_operands);
oconstraints = (const char **) alloca (noutputs * sizeof (char *));
string = resolve_asm_operand_names (string, output_operands,
@@ -1197,6 +1196,19 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands,
if (!lvalue_or_else (operand, lv_asm))
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)));
oconstraints[i] = constraint;
@@ -1254,7 +1266,7 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands,
r = build_stmt (ASM_EXPR, string,
output_operands, input_operands,
clobbers);
- ASM_VOLATILE_P (r) = volatile_p;
+ ASM_VOLATILE_P (r) = volatile_p || noutputs == 0;
r = maybe_cleanup_point_expr_void (r);
return add_stmt (r);
}
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 70479181fea..52012ebc9cc 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -3604,12 +3604,6 @@ gimplify_asm_expr (tree *expr_p, tree *pre_p, tree *post_p)
parse_output_constraint (&constraint, i, 0, 0,
&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)
lang_hooks.mark_addressable (TREE_VALUE (link));
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b24ca2cbfed..eb8812fa840 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,15 @@
+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>
PR fortran/24176
diff --git a/gcc/testsuite/g++.dg/ext/asm7.C b/gcc/testsuite/g++.dg/ext/asm7.C
new file mode 100644
index 00000000000..a5cad007371
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/asm7.C
@@ -0,0 +1,14 @@
+/* { 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" } */
+}
+
+
diff --git a/gcc/testsuite/g++.dg/ext/asm8.C b/gcc/testsuite/g++.dg/ext/asm8.C
new file mode 100644
index 00000000000..0b1be7da7de
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/asm8.C
@@ -0,0 +1,16 @@
+/* { 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" } } */
+
diff --git a/gcc/testsuite/gcc.dg/asm-1.c b/gcc/testsuite/gcc.dg/asm-1.c
index ac4b6be4b10..3bf5c29c4cd 100644
--- a/gcc/testsuite/gcc.dg/asm-1.c
+++ b/gcc/testsuite/gcc.dg/asm-1.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-do compile } */
struct x {
int selector;
diff --git a/gcc/testsuite/gcc.dg/asm-pr24146.c b/gcc/testsuite/gcc.dg/asm-pr24146.c
new file mode 100644
index 00000000000..0b1be7da7de
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/asm-pr24146.c
@@ -0,0 +1,16 @@
+/* { 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" } } */
+
diff --git a/gcc/testsuite/gcc.dg/pr21419.c b/gcc/testsuite/gcc.dg/pr21419.c
index f1e9cb92468..dc8f602e6b2 100644
--- a/gcc/testsuite/gcc.dg/pr21419.c
+++ b/gcc/testsuite/gcc.dg/pr21419.c
@@ -3,13 +3,13 @@ const int i = 0;
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)
{
- __asm__ __volatile__ ("" : "=r" (set)); /* { dg-error "invalid lvalue in asm output" } */
+ __asm__ __volatile__ ("" : "=r" (set)); /* { dg-error "read-only location" } */
}