[PATCH] Fix PR c++/30582: Trouble with __builtin_offsetof and volatile

Volker Reichelt v.reichelt@netcologne.de
Sun Mar 4 21:14:00 GMT 2007


The following code snippet triggers an ICE since GCC 4.0.0:

  struct A
  {
    static int i;
  };

  int j = __builtin_offsetof(volatile A, i);

bug.cc:6: internal compiler error: in fold_offsetof_1, at c-common.c:6316
Please submit a full bug report, [etc.]

The problem is that a COMPOUND_EXPR is generated for the access to A::i
which is not handled in fold_offsetof_1. (The first part of the
COMPOUND_EXPR is used to touch A because of the volatile. This part can
be ignored by __builtin_offsetof.)
The patch below therefore adds a case to handle COMPOUND_EXPRs to 
fold_offsetof_1. Instead of calling fold_offsetof_1 I could use a
fallthrough to the VAR_DECL case. Would that be preferable?

There's a second location where the COMPOUND_EXPR causes hiccups:
In finish_offsetof it isn't handled correctly. This is again fixed
by extracting the second part of the COMPOUND_EXPR.

Bootstrapped and regtested on i686-pc-linux-gnu.
Ok for mainline, 4.2 branch, and 4.1 branch?

Regards,
Volker

:ADDPATCH C++:


2007-03-04  Volker Reichelt  <reichelt@netcologne.de>

	PR c++/30852
	* c-common.c (fold_offsetof_1): Handle COMPOUND_EXPR.

===================================================================
--- gcc/gcc/c-common.c	2007-02-11 02:49:38 +0100
+++ gcc/gcc/c-common.c	2007-02-11 02:48:01 +0100
@@ -6386,6 +6386,12 @@ fold_offsetof_1 (tree expr, tree stop_re
       off = size_binop (MULT_EXPR, TYPE_SIZE_UNIT (TREE_TYPE (expr)), t);
       break;
 
+    case COMPOUND_EXPR:
+      /* Handle static members of volatile structs.  */
+      t = TREE_OPERAND (expr, 1);
+      gcc_assert (TREE_CODE (t) == VAR_DECL);
+      return fold_offsetof_1 (t, stop_ref);
+
     default:
       gcc_unreachable ();
     }
===================================================================

2007-03-04  Volker Reichelt  <reichelt@netcologne.de>

	PR c++/30852
	* semantics.c (finish_offsetof): Handle COMPOUND_EXPR.

===================================================================
--- gcc/gcc/cp/semantics.c	2007-02-11 03:05:10 +0100
+++ gcc/gcc/cp/semantics.c	2007-02-11 03:04:54 +0100
@@ -2933,7 +2933,8 @@ finish_offsetof (tree expr)
       || TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE
       || TREE_CODE (TREE_TYPE (expr)) == UNKNOWN_TYPE)
     {
-      if (TREE_CODE (expr) == COMPONENT_REF)
+      if (TREE_CODE (expr) == COMPONENT_REF
+	  || TREE_CODE (expr) == COMPOUND_EXPR)
 	expr = TREE_OPERAND (expr, 1);
       error ("cannot apply %<offsetof%> to member function %qD", expr);
       return error_mark_node;
===================================================================

2007-03-04  Volker Reichelt  <reichelt@netcologne.de>

	PR c++/30852
	* g++.dg/ext/offsetof1.C: Add cases with volatile.

===================================================================
--- gcc/gcc/testsuite/g++.dg/ext/offsetof1.C	2006-07-15 11:25:46 +0200
+++ gcc/gcc/testsuite/g++.dg/ext/offsetof1.C	2007-02-11 03:05:51 +0100
@@ -8,8 +8,10 @@ struct bar {
 };
 
 int a = __builtin_offsetof(bar, foo);  // { dg-error "static data member" }
+int av = __builtin_offsetof(volatile bar, foo);  // { dg-error "static data member" }
 int b = __builtin_offsetof(bar, baz);  // { dg-error "member function" }
 int b0 = __builtin_offsetof(bar, baz[0]);  // { dg-error "function" }
+int bv0 = __builtin_offsetof(volatile bar, baz[0]);  // { dg-error "function" }
 int c = __builtin_offsetof(bar, ~bar);  // { dg-error "member function" }
 
 typedef int I;
===================================================================



More information about the Gcc-patches mailing list