]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c/27676 (gcc is overly strict in assignment to read-only data)
authorJoseph Myers <joseph@codesourcery.com>
Sat, 18 Apr 2009 23:21:34 +0000 (00:21 +0100)
committerJoseph Myers <jsm28@gcc.gnu.org>
Sat, 18 Apr 2009 23:21:34 +0000 (00:21 +0100)
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.

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

From-SVN: r146336

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

index 4035b2c90ebc8e4eee7056220246b83ca3d0762b..405aefa6983676b1c2d47023f75c64c65e249639 100644 (file)
@@ -1,3 +1,10 @@
+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
index bacfdc0e8493e78c1de51d717a1a254103cfd8a5..77eafbff0098dfac88fc6b82bf66ce75034b22b6 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 a2b0bb043c3c5f75e4e4703e4fa847029fe8d64b..c87827bd08b36899e09799871a01ba4860c6eac9 100644 (file)
@@ -1,3 +1,8 @@
+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
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" } */
+}