re PR c/21419 (Accepts writting to const via asm)
authorPaolo Bonzini <bonzini@gnu.org>
Wed, 5 Oct 2005 12:17:16 +0000 (12:17 +0000)
committerPaolo Bonzini <bonzini@gcc.gnu.org>
Wed, 5 Oct 2005 12:17:16 +0000 (12:17 +0000)
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

gcc/ChangeLog
gcc/c-typeck.c
gcc/cp/ChangeLog
gcc/cp/semantics.c
gcc/gimplify.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/asm7.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/asm8.C [new file with mode: 0644]
gcc/testsuite/gcc.dg/asm-1.c
gcc/testsuite/gcc.dg/asm-pr24146.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr21419.c

index 24f14e9..4a87d1f 100644 (file)
@@ -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>
 
index a72dac6..8a90476 100644 (file)
@@ -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;
 }
index c79a926..3a1737d 100644 (file)
@@ -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
index c7392b0..80885c5 100644 (file)
@@ -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);
 }
index 7047918..52012eb 100644 (file)
@@ -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));
 
index b24ca2c..eb8812f 100644 (file)
@@ -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 (file)
index 0000000..a5cad00
--- /dev/null
@@ -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 (file)
index 0000000..0b1be7d
--- /dev/null
@@ -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" } } */
+
index ac4b6be..3bf5c29 100644 (file)
@@ -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 (file)
index 0000000..0b1be7d
--- /dev/null
@@ -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" } } */
+
index f1e9cb9..dc8f602 100644 (file)
@@ -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" } */
 }