diff options
author | Joseph Myers <joseph@codesourcery.com> | 2009-03-30 02:25:37 +0100 |
---|---|---|
committer | Joseph Myers <jsm28@gcc.gnu.org> | 2009-03-30 02:25:37 +0100 |
commit | 1e57bf475bf7651b30a5a3199bc669617c5004a6 (patch) | |
tree | a3701e6d5c0e690302dbeb1ef83b5841596f4999 | |
parent | 25d4deb101277208e94bac3af595d004801027de (diff) | |
download | gcc-1e57bf475bf7651b30a5a3199bc669617c5004a6.zip gcc-1e57bf475bf7651b30a5a3199bc669617c5004a6.tar.gz gcc-1e57bf475bf7651b30a5a3199bc669617c5004a6.tar.bz2 |
re PR c/35235 (struct/union rvalue qualifiers must not propagate to members)
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.
From-SVN: r145271
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/c-typeck.c | 18 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/c99-array-lval-8.c | 30 |
4 files changed, 56 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5f2d8ee..49bbb0f 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 674220c..2559b1d 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 2b3a216..23701aa 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 0000000..b5048b6 --- /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" } */ +} |