aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-typeck.c
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 /gcc/c-typeck.c
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
Diffstat (limited to 'gcc/c-typeck.c')
-rw-r--r--gcc/c-typeck.c35
1 files changed, 33 insertions, 2 deletions
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'.