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
This commit is contained in:
Joseph Myers 2009-04-19 00:21:34 +01:00 committed by Joseph Myers
parent 7d0a3061a8
commit f37acdf9b1
4 changed files with 59 additions and 2 deletions

View 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

View 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'.

View 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

View File

@ -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" } */
}