This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR c++/30582: Trouble with __builtin_offsetof and volatile
- From: Volker Reichelt <v dot reichelt at netcologne dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 4 Mar 2007 22:50:57 +0100 (CET)
- Subject: [PATCH] Fix PR c++/30582: Trouble with __builtin_offsetof and volatile
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;
===================================================================