diff options
author | Joseph Myers <joseph@codesourcery.com> | 2009-04-19 00:21:34 +0100 |
---|---|---|
committer | Joseph Myers <jsm28@gcc.gnu.org> | 2009-04-19 00:21:34 +0100 |
commit | f37acdf9b1089f74cd5ca953fbe508ae7e9e34c0 (patch) | |
tree | 9cf337c7fba41b385386e352cb0ce692c4edb4cf | |
parent | 7d0a3061a8364ff56ace51413f29b50416fda3a0 (diff) | |
download | gcc-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/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/c-typeck.c | 35 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/lvalue-5.c | 14 |
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" } */ +} |