OSDN Git Service

PR c/27676
authorjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 18 Apr 2009 23:21:34 +0000 (23:21 +0000)
committerjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 18 Apr 2009 23:21:34 +0000 (23:21 +0000)
* c-typeck.c (readonly_warning): new.
(build_unary_op, build_modify_expr): Use readonly_warning for
storing into something readonly but not const-qualified.

testsuite:
* gcc.dg/lvalue-5.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@146336 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/c-typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/lvalue-5.c [new file with mode: 0644]

index 4035b2c..405aefa 100644 (file)
@@ -1,5 +1,12 @@
 2009-04-18  Joseph Myers  <joseph@codesourcery.com>
 
+       PR c/27676
+       * c-typeck.c (readonly_warning): new.
+       (build_unary_op, build_modify_expr): Use readonly_warning for
+       storing into something readonly but not const-qualified.
+
+2009-04-18  Joseph Myers  <joseph@codesourcery.com>
+
        PR c/22367
        * c-typeck.c (build_unary_op): Check for taking address of
        expression of type void.
index bacfdc0..77eafbf 100644 (file)
@@ -107,6 +107,7 @@ static void set_nonincremental_init (void);
 static void set_nonincremental_init_from_string (tree);
 static tree find_init_member (tree);
 static void readonly_error (tree, enum lvalue_use);
+static void readonly_warning (tree, enum lvalue_use);
 static int lvalue_or_else (const_tree, enum lvalue_use);
 static int lvalue_p (const_tree);
 static void record_maybe_used_decl (tree);
@@ -3323,7 +3324,7 @@ build_unary_op (location_t location,
          }
 
        /* Report a read-only lvalue.  */
-       if (TREE_READONLY (arg))
+       if (TYPE_READONLY (argtype))
          {
            readonly_error (arg,
                            ((code == PREINCREMENT_EXPR
@@ -3331,6 +3332,11 @@ build_unary_op (location_t location,
                             ? lv_increment : lv_decrement));
            return error_mark_node;
          }
+       else if (TREE_READONLY (arg))
+         readonly_warning (arg,
+                           ((code == PREINCREMENT_EXPR
+                             || code == POSTINCREMENT_EXPR)
+                            ? lv_increment : lv_decrement));
 
        if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE)
          val = boolean_increment (code, arg);
@@ -3540,6 +3546,29 @@ readonly_error (tree arg, enum lvalue_use use)
           arg);
 }
 
+/* Give a warning for storing in something that is read-only in GCC
+   terms but not const in ISO C terms.  */
+
+static void
+readonly_warning (tree arg, enum lvalue_use use)
+{
+  switch (use)
+    {
+    case lv_assign:
+      warning (0, "assignment of read-only location %qE", arg);
+      break;
+    case lv_increment:
+      warning (0, "increment of read-only location %qE", arg);
+      break;
+    case lv_decrement:
+      warning (0, "decrement of read-only location %qE", arg);
+      break;
+    default:
+      gcc_unreachable ();
+    }
+  return;
+}
+
 
 /* Return nonzero if REF is an lvalue valid for this language;
    otherwise, print an error message and return zero.  USE says
@@ -4292,7 +4321,7 @@ build_modify_expr (location_t location,
 
   /* Give an error for storing in something that is 'const'.  */
 
-  if (TREE_READONLY (lhs) || TYPE_READONLY (lhstype)
+  if (TYPE_READONLY (lhstype)
       || ((TREE_CODE (lhstype) == RECORD_TYPE
           || TREE_CODE (lhstype) == UNION_TYPE)
          && C_TYPE_FIELDS_READONLY (lhstype)))
@@ -4300,6 +4329,8 @@ build_modify_expr (location_t location,
       readonly_error (lhs, lv_assign);
       return error_mark_node;
     }
+  else if (TREE_READONLY (lhs))
+    readonly_warning (lhs, lv_assign);
 
   /* If storing into a structure or union member,
      it has probably been given type `int'.
index a2b0bb0..c87827b 100644 (file)
@@ -1,5 +1,10 @@
 2009-04-18  Joseph Myers  <joseph@codesourcery.com>
 
+       PR c/27676
+       * gcc.dg/lvalue-5.c: New test.
+
+2009-04-18  Joseph Myers  <joseph@codesourcery.com>
+
        PR c/22367
        * gcc.dg/lvalue-6.c, gcc.dg/lvalue-7.c: New tests.
 
diff --git a/gcc/testsuite/gcc.dg/lvalue-5.c b/gcc/testsuite/gcc.dg/lvalue-5.c
new file mode 100644 (file)
index 0000000..514f35e
--- /dev/null
@@ -0,0 +1,14 @@
+/* Test assignment to elements of a string literal is a warning, not
+   an error.  PR 27676.  */
+/* { dg-do compile } */
+/* { dg-options "-pedantic-errors" } */
+
+void
+f (void)
+{
+  "foo"[0] = 0; /* { dg-warning "assignment of read-only location" } */
+  "foo"[0]++; /* { dg-warning "increment of read-only location" } */
+  "foo"[0]--; /* { dg-warning "decrement of read-only location" } */
+  ++"foo"[0]; /* { dg-warning "increment of read-only location" } */
+  --"foo"[0]; /* { dg-warning "decrement of read-only location" } */
+}