summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>2009-03-30 01:25:37 +0000
committerjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>2009-03-30 01:25:37 +0000
commit7666d572f2a547f09f39811c7af07f9532251a02 (patch)
treea3701e6d5c0e690302dbeb1ef83b5841596f4999
parentd0aaefa3f61522abeeb64fda0a3261edd749dd61 (diff)
downloadgcc-7666d572f2a547f09f39811c7af07f9532251a02.tar.gz
PR c/35235
* c-typeck.c (build_component_ref): Do not copy qualifiers from non-lvalue to component. testsuite: * gcc.dg/c99-array-lval-8.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@145271 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/c-typeck.c18
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/c99-array-lval-8.c30
4 files changed, 56 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5f2d8ee7727..49bbb0f9d77 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2009-03-30 Joseph Myers <joseph@codesourcery.com>
+
+ PR c/35235
+ * c-typeck.c (build_component_ref): Do not copy qualifiers from
+ non-lvalue to component.
+
2009-03-29 Joseph Myers <joseph@codesourcery.com>
PR preprocessor/34695
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index 674220ca3b0..2559b1d92a8 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -1904,6 +1904,7 @@ build_component_ref (tree datum, tree component)
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;
@@ -1936,19 +1937,30 @@ build_component_ref (tree datum, tree component)
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))
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 2b3a2165a57..23701aae223 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2009-03-30 Joseph Myers <joseph@codesourcery.com>
+
+ PR c/35235
+ * gcc.dg/c99-array-lval-8.c: New test.
+
2009-03-29 Joseph Myers <joseph@codesourcery.com>
PR preprocessor/34695
diff --git a/gcc/testsuite/gcc.dg/c99-array-lval-8.c b/gcc/testsuite/gcc.dg/c99-array-lval-8.c
new file mode 100644
index 00000000000..b5048b66a77
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c99-array-lval-8.c
@@ -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" } */
+}