From 5544530ae53f6a1063641ae448bc9cd62c8f6ee7 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 5 Oct 2005 12:17:16 +0000 Subject: [PATCH] re PR c/21419 (Accepts writting to const via asm) 2005-10-05 Paolo Bonzini 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 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 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 --- gcc/ChangeLog | 10 ++++++++++ gcc/c-typeck.c | 36 +++++++++++++++++++++++------------- gcc/cp/ChangeLog | 9 +++++++++ gcc/cp/semantics.c | 20 ++++++++++++++++---- gcc/gimplify.c | 6 ------ gcc/testsuite/ChangeLog | 12 ++++++++++++ gcc/testsuite/g++.dg/ext/asm7.C | 14 ++++++++++++++ gcc/testsuite/g++.dg/ext/asm8.C | 16 ++++++++++++++++ gcc/testsuite/gcc.dg/asm-1.c | 2 +- gcc/testsuite/gcc.dg/asm-pr24146.c | 16 ++++++++++++++++ gcc/testsuite/gcc.dg/pr21419.c | 4 ++-- 11 files changed, 119 insertions(+), 26 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ext/asm7.C create mode 100644 gcc/testsuite/g++.dg/ext/asm8.C create mode 100644 gcc/testsuite/gcc.dg/asm-pr24146.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 24f14e9..4a87d1f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2005-10-05 Paolo Bonzini + + 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 Paolo Bonzini diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index a72dac6..8a90476 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 % 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 % 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 % 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 c79a926..3a1737d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2005-10-05 Paolo Bonzini + + 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 PR c++/23513 diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index c7392b0..80885c5 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 7047918..52012eb 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 b24ca2c..eb8812f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,15 @@ +2005-10-05 Paolo Bonzini + + 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 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 0000000..a5cad00 --- /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 0000000..0b1be7d --- /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 ac4b6be..3bf5c29 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 0000000..0b1be7d --- /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 f1e9cb9..dc8f602 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" } */ } -- 2.7.4