This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Patch for c/27697


This patch fixes bug 27697, a P2 C front-end regression involving both
rejection of valid code and acceptance of invalid code involving
qualified structures or unions.  The qualifiers on a COMPONENT_REF
need to be the union of those on the field and those on the containing
structure or union.

Bootstrapped with no regressions on i686-pc-linux-gnu.  Applied to
mainline and 4.1 branch.  Not applied to 4.0 branch because one of the
test assertions fails there (probably through lack of other relevant
array qualifier patches).

2006-08-16  Joseph S. Myers  <joseph@codesourcery.com>

	PR c/27697
	* c-typeck.c (build_component_ref): Combine qualifiers of
	structure or union and field.

testsuite:
2006-08-16  Joseph S. Myers  <joseph@codesourcery.com>

	PR c/27697
	* gcc.dg/qual-component-1.c: New test.

diff -rupN GCC.orig/gcc/c-typeck.c GCC/gcc/c-typeck.c
--- GCC.orig/gcc/c-typeck.c	2006-08-16 11:27:15.000000000 +0000
+++ GCC/gcc/c-typeck.c	2006-08-16 17:16:46.000000000 +0000
@@ -1809,11 +1809,17 @@ build_component_ref (tree datum, tree co
       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 -rupN GCC.orig/gcc/testsuite/gcc.dg/qual-component-1.c GCC/gcc/testsuite/gcc.dg/qual-component-1.c
--- GCC.orig/gcc/testsuite/gcc.dg/qual-component-1.c	1970-01-01 00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/gcc.dg/qual-component-1.c	2006-08-16 17:15:15.000000000 +0000
@@ -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 <joseph@codesourcery.com> */
+/* { 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" } */
+  }
+}

-- 
Joseph S. Myers
joseph@codesourcery.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]