aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2009-04-19 00:21:34 +0100
committerJoseph Myers <jsm28@gcc.gnu.org>2009-04-19 00:21:34 +0100
commitf37acdf9b1089f74cd5ca953fbe508ae7e9e34c0 (patch)
tree9cf337c7fba41b385386e352cb0ce692c4edb4cf
parent7d0a3061a8364ff56ace51413f29b50416fda3a0 (diff)
downloadgcc-f37acdf9b1089f74cd5ca953fbe508ae7e9e34c0.zip
gcc-f37acdf9b1089f74cd5ca953fbe508ae7e9e34c0.tar.gz
gcc-f37acdf9b1089f74cd5ca953fbe508ae7e9e34c0.tar.bz2
re PR c/27676 (gcc is overly strict in assignment to read-only data)
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
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/c-typeck.c35
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/lvalue-5.c14
4 files changed, 59 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4035b2c..405aefa 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index bacfdc0..77eafbf 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -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'.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index a2b0bb0..c87827b 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..514f35e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lvalue-5.c
@@ -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" } */
+}