re PR middle-end/33692 (Type checking error with address-of and volatile)
authorRichard Guenther <rguenther@suse.de>
Tue, 9 Oct 2007 15:51:46 +0000 (15:51 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 9 Oct 2007 15:51:46 +0000 (15:51 +0000)
2007-10-09  Richard Guenther  <rguenther@suse.de>

PR middle-end/33692
* gimplify.c (canonicalize_component_ref): Honor qualifiers
of referenced structure and component.

* gcc.dg/pr33692.c: New testcase.

From-SVN: r129167

gcc/ChangeLog
gcc/gimplify.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr33692.c [new file with mode: 0644]

index d10a6c5..c8fcf6a 100644 (file)
@@ -1,3 +1,9 @@
+2007-10-09  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/33692
+       * gimplify.c (canonicalize_component_ref): Honor qualifiers
+       of referenced structure and component.
+
 2007-10-09  Kenneth Zadeck <zadeck@naturalbridge.com>
 
        PR middle-end/33669
index 00a3cf1..df6ecd3 100644 (file)
@@ -1555,17 +1555,31 @@ canonicalize_component_ref (tree *expr_p)
   else
     type = TREE_TYPE (TREE_OPERAND (expr, 1));
 
+  /* One could argue that all the stuff below is not necessary for
+     the non-bitfield case and declare it a FE error if type
+     adjustment would be needed.  */
   if (TREE_TYPE (expr) != type)
     {
+#ifdef ENABLE_TYPES_CHECKING
       tree old_type = TREE_TYPE (expr);
+#endif
+      int type_quals;
+
+      /* We need to preserve qualifiers and propagate them from
+        operand 0.  */
+      type_quals = TYPE_QUALS (type)
+       | TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr, 0)));
+      if (TYPE_QUALS (type) != type_quals)
+       type = build_qualified_type (TYPE_MAIN_VARIANT (type), type_quals);
 
       /* Set the type of the COMPONENT_REF to the underlying type.  */
       TREE_TYPE (expr) = type;
 
-      /* And wrap the whole thing inside a NOP_EXPR.  */
-      expr = build1 (NOP_EXPR, old_type, expr);
-
-      *expr_p = expr;
+#ifdef ENABLE_TYPES_CHECKING
+      /* It is now a FE error, if the conversion from the canonical
+        type to the original expression type is not useless.  */
+      gcc_assert (useless_type_conversion_p (old_type, type));
+#endif
     }
 }
 
index c37814b..ea1aa88 100644 (file)
@@ -1,3 +1,8 @@
+2007-10-09  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/33692
+       * gcc.dg/pr33692.c: New testcase.
+
 2007-10-09  Kenneth Zadeck <zadeck@naturalbridge.com>
 
        PR middle-end/33669
diff --git a/gcc/testsuite/gcc.dg/pr33692.c b/gcc/testsuite/gcc.dg/pr33692.c
new file mode 100644 (file)
index 0000000..08ee332
--- /dev/null
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+
+/* We ICEd with type-checking enabled.  */
+
+typedef struct { int i; } snd_pcm_info_t;
+typedef struct { snd_pcm_info_t info; } snd_pcm_shm_ctrl_t;
+void snd_pcm_info(snd_pcm_info_t *);
+int pcm_shm_cmd(volatile snd_pcm_shm_ctrl_t *ctrl)
+{
+  snd_pcm_info((snd_pcm_info_t *) &ctrl->info);
+}
+