This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[4.5 C] Fix PR c/35235 (qualifiers on non-lvalue arrays)
- From: "Joseph S. Myers" <joseph at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 4 Feb 2009 21:06:45 +0000 (UTC)
- Subject: [4.5 C] Fix PR c/35235 (qualifiers on non-lvalue arrays)
This patch fixes PR c/35235, where GCC's notions of type qualifiers on
rvalues carried over to being visible in standard C when a non-lvalue
array was converted to a pointer.
Bootstrapped with no regressions on i686-pc-linux-gnu. Applied to
c-4_5-branch. (I originally intended this as a regression fix for trunk,
but it ran into problems with the NOP stripping in
default_function_array_conversion changing some non-lvalues into lvalues,
and I didn't want to perturb that on trunk at this stage. So I put it on
c-4_5-branch, where the NOP stripping has been removed but this patch is
still needed to fix the reported bug, and will merge it to trunk after the
constant expressions changes after 4.5 branches.)
Index: testsuite/ChangeLog.c45
===================================================================
--- testsuite/ChangeLog.c45 (revision 143922)
+++ testsuite/ChangeLog.c45 (working copy)
@@ -1,3 +1,8 @@
+2009-02-04 Joseph Myers <joseph@codesourcery.com>
+
+ PR c/35235
+ * gcc.dg/c99-array-lval-8.c: New test.
+
2008-12-10 Joseph Myers <joseph@codesourcery.com>
* gcc.dg/bconstp-3.c, gcc.dg/bconstp-4.c: New tests.
Index: testsuite/gcc.dg/c99-array-lval-8.c
===================================================================
--- testsuite/gcc.dg/c99-array-lval-8.c (revision 0)
+++ testsuite/gcc.dg/c99-array-lval-8.c (revision 0)
@@ -0,0 +1,30 @@
+/* Test for non-lvalue arrays: test that qualifiers on non-lvalues
+ containing arrays do not remain when those arrays decay to
+ pointers. PR 35235. */
+/* { dg-do compile } */
+/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */
+
+int a;
+
+void
+f (void)
+{
+ const struct {
+ int a[1];
+ } s;
+ int *p1 = s.a; /* { dg-error "qualifiers" } */
+ int *p2 = (a ? s : s).a;
+ /* In this case, the qualifier is properly on the array element type
+ not on the rvalue structure and so is not discarded. */
+ struct {
+ const int a[1];
+ } t;
+ int *p3 = t.a; /* { dg-error "qualifiers" } */
+ int *p4 = (a ? t : t).a; /* { dg-error "qualifiers" } */
+ /* The issue could also lead to code being wrongly accepted. */
+ const struct {
+ int a[1][1];
+ } u;
+ const int (*p5)[1] = u.a;
+ const int (*p6)[1] = (a ? u : u).a; /* { dg-error "pointer" } */
+}
Index: c-typeck.c
===================================================================
--- c-typeck.c (revision 143922)
+++ c-typeck.c (working copy)
@@ -1891,6 +1891,7 @@
enum tree_code code = TREE_CODE (type);
tree field = NULL;
tree ref;
+ bool datum_lvalue = lvalue_p (datum);
if (!objc_is_public (datum, component))
return error_mark_node;
@@ -1923,19 +1924,30 @@
tree subdatum = TREE_VALUE (field);
int quals;
tree subtype;
+ bool use_datum_quals;
if (TREE_TYPE (subdatum) == error_mark_node)
return error_mark_node;
+ /* If this is an rvalue, it does not have qualifiers in C
+ standard terms and we must avoid propagating such
+ qualifiers down to a non-lvalue array that is then
+ converted to a pointer. */
+ use_datum_quals = (datum_lvalue
+ || TREE_CODE (TREE_TYPE (subdatum)) != ARRAY_TYPE);
+
quals = TYPE_QUALS (strip_array_types (TREE_TYPE (subdatum)));
- quals |= TYPE_QUALS (TREE_TYPE (datum));
+ if (use_datum_quals)
+ quals |= TYPE_QUALS (TREE_TYPE (datum));
subtype = c_build_qualified_type (TREE_TYPE (subdatum), quals);
ref = build3 (COMPONENT_REF, subtype, datum, subdatum,
NULL_TREE);
- if (TREE_READONLY (datum) || TREE_READONLY (subdatum))
+ if (TREE_READONLY (subdatum)
+ || (use_datum_quals && TREE_READONLY (datum)))
TREE_READONLY (ref) = 1;
- if (TREE_THIS_VOLATILE (datum) || TREE_THIS_VOLATILE (subdatum))
+ if (TREE_THIS_VOLATILE (subdatum)
+ || (use_datum_quals && TREE_THIS_VOLATILE (datum)))
TREE_THIS_VOLATILE (ref) = 1;
if (TREE_DEPRECATED (subdatum))
Index: ChangeLog.c45
===================================================================
--- ChangeLog.c45 (revision 143922)
+++ ChangeLog.c45 (working copy)
@@ -1,3 +1,9 @@
+2009-02-04 Joseph Myers <joseph@codesourcery.com>
+
+ PR c/35235
+ * c-typeck.c (build_component_ref): Do not copy qualifiers from
+ non-lvalue to component.
+
2009-01-17 Joseph Myers <joseph@codesourcery.com>
* builtins.c (fold_builtin_sincos): Build COMPOUND_EXPR in
--
Joseph S. Myers
joseph@codesourcery.com