From efed193e0ae854a5a6e33a4fb8ec08be07533582 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Thu, 17 Aug 2006 00:10:46 +0100 Subject: [PATCH] re PR c/27697 (incorrect warning about constness of pointer to an array in a const struct) PR c/27697 * c-typeck.c (build_component_ref): Combine qualifiers of structure or union and field. testsuite: * gcc.dg/qual-component-1.c: New test. From-SVN: r116194 --- gcc/ChangeLog | 6 + gcc/c-typeck.c | 8 +- gcc/testsuite/ChangeLog | 5 + gcc/testsuite/gcc.dg/qual-component-1.c | 232 ++++++++++++++++++++++++ 4 files changed, 250 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/qual-component-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bd98986eef4..29fa23fa3c4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2006-08-16 Joseph S. Myers + + PR c/27697 + * c-typeck.c (build_component_ref): Combine qualifiers of + structure or union and field. + 2006-08-16 Zdenek Dvorak PR rtl-optimization/28071 diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 2fbd89f5c2d..dee7414e43a 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -1809,11 +1809,17 @@ build_component_ref (tree datum, tree component) do { tree subdatum = TREE_VALUE (field); + int quals; + tree subtype; if (TREE_TYPE (subdatum) == error_mark_node) return error_mark_node; - ref = build3 (COMPONENT_REF, TREE_TYPE (subdatum), datum, subdatum, + quals = TYPE_QUALS (strip_array_types (TREE_TYPE (subdatum))); + 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)) TREE_READONLY (ref) = 1; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5d71321d72e..ce97baf7965 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2006-08-16 Joseph S. Myers + + PR c/27697 + * gcc.dg/qual-component-1.c: New test. + 2006-08-16 Volker Reichelt PR c++/28593 diff --git a/gcc/testsuite/gcc.dg/qual-component-1.c b/gcc/testsuite/gcc.dg/qual-component-1.c new file mode 100644 index 00000000000..58054348173 --- /dev/null +++ b/gcc/testsuite/gcc.dg/qual-component-1.c @@ -0,0 +1,232 @@ +/* Test qualification of components of qualified structures or unions: + should have qualifiers from both the component and the structure or + union. Bug 27697 from Frank Victor Fischer. */ +/* Origin: Joseph Myers */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +struct s { + int a; + int b[1]; + int c[2][3]; + const int d; + const int e[1]; + const int f[2][3]; +}; + +union u { + int a; + int b[1]; + int c[2][3]; + const int d; + const int e[1]; + const int f[2][3]; +}; + +struct cs { + const struct s x; +}; + +struct s v1; +union u *v2; +const struct s *v3; +const union u v4; +struct cs v5; + +void +f (void) +{ + v1.a = 0; + v1.b[0] = 0; + *v1.b = 0; + v1.c[0][0] = 0; + *v1.c[0] = 0; + **v1.c = 0; + v1.d = 0; /* { dg-error "error: assignment of read-only" } */ + v1.e[0] = 0; /* { dg-error "error: assignment of read-only" } */ + *v1.e = 0; /* { dg-error "error: assignment of read-only" } */ + v1.f[0][0] = 0; /* { dg-error "error: assignment of read-only" } */ + *v1.f[0] = 0; /* { dg-error "error: assignment of read-only" } */ + **v1.f = 0; /* { dg-error "error: assignment of read-only" } */ + + v2->a = 0; + v2->b[0] = 0; + *v2->b = 0; + v2->c[0][0] = 0; + *v2->c[0] = 0; + **v2->c = 0; + v2->d = 0; /* { dg-error "error: assignment of read-only" } */ + v2->e[0] = 0; /* { dg-error "error: assignment of read-only" } */ + *v2->e = 0; /* { dg-error "error: assignment of read-only" } */ + v2->f[0][0] = 0; /* { dg-error "error: assignment of read-only" } */ + *v2->f[0] = 0; /* { dg-error "error: assignment of read-only" } */ + **v2->f = 0; /* { dg-error "error: assignment of read-only" } */ + + v3->a = 0; /* { dg-error "error: assignment of read-only" } */ + v3->b[0] = 0; /* { dg-error "error: assignment of read-only" } */ + *v3->b = 0; /* { dg-error "error: assignment of read-only" } */ + v3->c[0][0] = 0; /* { dg-error "error: assignment of read-only" } */ + *v3->c[0] = 0; /* { dg-error "error: assignment of read-only" } */ + **v3->c = 0; /* { dg-error "error: assignment of read-only" } */ + v3->d = 0; /* { dg-error "error: assignment of read-only" } */ + v3->e[0] = 0; /* { dg-error "error: assignment of read-only" } */ + *v3->e = 0; /* { dg-error "error: assignment of read-only" } */ + v3->f[0][0] = 0; /* { dg-error "error: assignment of read-only" } */ + *v3->f[0] = 0; /* { dg-error "error: assignment of read-only" } */ + **v3->f = 0; /* { dg-error "error: assignment of read-only" } */ + + v4.a = 0; /* { dg-error "error: assignment of read-only" } */ + v4.b[0] = 0; /* { dg-error "error: assignment of read-only" } */ + *v4.b = 0; /* { dg-error "error: assignment of read-only" } */ + v4.c[0][0] = 0; /* { dg-error "error: assignment of read-only" } */ + *v4.c[0] = 0; /* { dg-error "error: assignment of read-only" } */ + **v4.c = 0; /* { dg-error "error: assignment of read-only" } */ + v4.d = 0; /* { dg-error "error: assignment of read-only" } */ + v4.e[0] = 0; /* { dg-error "error: assignment of read-only" } */ + *v4.e = 0; /* { dg-error "error: assignment of read-only" } */ + v4.f[0][0] = 0; /* { dg-error "error: assignment of read-only" } */ + *v4.f[0] = 0; /* { dg-error "error: assignment of read-only" } */ + **v4.f = 0; /* { dg-error "error: assignment of read-only" } */ + + v5.x.a = 0; /* { dg-error "error: assignment of read-only" } */ + v5.x.b[0] = 0; /* { dg-error "error: assignment of read-only" } */ + *v5.x.b = 0; /* { dg-error "error: assignment of read-only" } */ + v5.x.c[0][0] = 0; /* { dg-error "error: assignment of read-only" } */ + *v5.x.c[0] = 0; /* { dg-error "error: assignment of read-only" } */ + **v5.x.c = 0; /* { dg-error "error: assignment of read-only" } */ + v5.x.d = 0; /* { dg-error "error: assignment of read-only" } */ + v5.x.e[0] = 0; /* { dg-error "error: assignment of read-only" } */ + *v5.x.e = 0; /* { dg-error "error: assignment of read-only" } */ + v5.x.f[0][0] = 0; /* { dg-error "error: assignment of read-only" } */ + *v5.x.f[0] = 0; /* { dg-error "error: assignment of read-only" } */ + **v5.x.f = 0; /* { dg-error "error: assignment of read-only" } */ +} + +void +g (void) +{ + { + int *a = &v1.a; + int (*b)[1] = &v1.b; + int (*c)[2][3] = &v1.c; + int (*cc)[3] = v1.c; + const int (*ff)[3] = v1.c; /* { dg-warning "warning: initialization from incompatible pointer type" } */ + a = &v1.a; + b = &v1.b; + c = &v1.c; + cc = v1.c; + ff = v1.c; /* { dg-warning "warning: assignment from incompatible pointer type" } */ + } + { + const int *d = &v1.d; + const int (*e)[1] = &v1.e; + const int (*f)[2][3] = &v1.f; + const int (*ff)[3] = v1.f; + int (*cc)[3] = v1.f; /* { dg-warning "warning: initialization from incompatible pointer type" } */ + d = &v1.d; + e = &v1.e; + f = &v1.f; + ff = v1.f; + cc = v1.f; /* { dg-warning "warning: assignment from incompatible pointer type" } */ + } + + { + int *a = &v2->a; + int (*b)[1] = &v2->b; + int (*c)[2][3] = &v2->c; + int (*cc)[3] = v2->c; + const int (*ff)[3] = v2->c; /* { dg-warning "warning: initialization from incompatible pointer type" } */ + a = &v2->a; + b = &v2->b; + c = &v2->c; + cc = v2->c; + ff = v2->c; /* { dg-warning "warning: assignment from incompatible pointer type" } */ + } + { + const int *d = &v2->d; + const int (*e)[1] = &v2->e; + const int (*f)[2][3] = &v2->f; + const int (*ff)[3] = v2->f; + int (*cc)[3] = v2->f; /* { dg-warning "warning: initialization from incompatible pointer type" } */ + d = &v2->d; + e = &v2->e; + f = &v2->f; + ff = v2->f; + cc = v2->f; /* { dg-warning "warning: assignment from incompatible pointer type" } */ + } + + { + const int *d = &v3->a; + const int (*e)[1] = &v3->b; + const int (*f)[2][3] = &v3->c; + const int (*ff)[3] = v3->c; + int (*cc)[3] = v3->c; /* { dg-warning "warning: initialization from incompatible pointer type" } */ + d = &v3->a; + e = &v3->b; + f = &v3->c; + ff = v3->c; + cc = v3->c; /* { dg-warning "warning: assignment from incompatible pointer type" } */ + } + { + const int *d = &v3->d; + const int (*e)[1] = &v3->e; + const int (*f)[2][3] = &v3->f; + const int (*ff)[3] = v3->f; + int (*cc)[3] = v3->f; /* { dg-warning "warning: initialization from incompatible pointer type" } */ + d = &v3->d; + e = &v3->e; + f = &v3->f; + ff = v3->f; + cc = v3->f; /* { dg-warning "warning: assignment from incompatible pointer type" } */ + } + + { + const int *d = &v4.a; + const int (*e)[1] = &v4.b; + const int (*f)[2][3] = &v4.c; + const int (*ff)[3] = v4.c; + int (*cc)[3] = v4.c; /* { dg-warning "warning: initialization from incompatible pointer type" } */ + d = &v4.a; + e = &v4.b; + f = &v4.c; + ff = v4.c; + cc = v4.c; /* { dg-warning "warning: assignment from incompatible pointer type" } */ + } + { + const int *d = &v4.d; + const int (*e)[1] = &v4.e; + const int (*f)[2][3] = &v4.f; + const int (*ff)[3] = v4.f; + int (*cc)[3] = v4.f; /* { dg-warning "warning: initialization from incompatible pointer type" } */ + d = &v4.d; + e = &v4.e; + f = &v4.f; + ff = v4.f; + cc = v4.f; /* { dg-warning "warning: assignment from incompatible pointer type" } */ + } + + { + const int *d = &v5.x.a; + const int (*e)[1] = &v5.x.b; + const int (*f)[2][3] = &v5.x.c; + const int (*ff)[3] = v5.x.c; + int (*cc)[3] = v5.x.c; /* { dg-warning "warning: initialization from incompatible pointer type" } */ + d = &v5.x.a; + e = &v5.x.b; + f = &v5.x.c; + ff = v5.x.c; + cc = v5.x.c; /* { dg-warning "warning: assignment from incompatible pointer type" } */ + } + { + const int *d = &v5.x.d; + const int (*e)[1] = &v5.x.e; + const int (*f)[2][3] = &v5.x.f; + const int (*ff)[3] = v5.x.f; + int (*cc)[3] = v5.x.f; /* { dg-warning "warning: initialization from incompatible pointer type" } */ + d = &v5.x.d; + e = &v5.x.e; + f = &v5.x.f; + ff = v5.x.f; + cc = v5.x.f; /* { dg-warning "warning: assignment from incompatible pointer type" } */ + } +}