This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] Fix 9881, break something else
- From: Nathan Sidwell <nathan at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Mark Mitchell <mark at codesourcery dot com>
- Date: Sun, 20 Apr 2003 13:18:36 +0100
- Subject: [C++ PATCH] Fix 9881, break something else
- Organization: Codesourcery LLC
Hi,
this patch fixes 9881, by reverting my 2002-08-08 patch which allowed
address of packed member to work (but introduced this regression).
The problem is that by not folding &m.field, we don't treat it as
an address-constant-expression, and thus it is not a static initializer.
By folding it, we lose the packedness of the address, and thus
segfault when deferencing it on strict aligned architecture.
Why is the type of a packed field, T, rather than
__attribute__((unaligned)) T? That would seem to solve the problem.
IMO, fixing 9881 is more important than handling *&m.packed_field.
built & tested on i686-pc-linux-gnu, ok?
nathan
--
Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC
The voices in my head said this was stupid too
nathan at codesourcery dot com : http://www.cs.bris.ac.uk/~nathan/ : nathan at acm dot org
2003-04-19 Nathan Sidwell <nathan at codesourcery dot com>
PR 9881
* typeck.c (build_unary_op): Fold all COMPONENT_REF addr
expressions. Reverts my 2002-08-08 patch.
Index: cp/typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck.c,v
retrieving revision 1.455
diff -c -3 -p -r1.455 typeck.c
*** cp/typeck.c 13 Apr 2003 01:45:33 -0000 1.455
--- cp/typeck.c 19 Apr 2003 18:23:23 -0000
*************** build_unary_op (code, xarg, noconvert)
*** 4504,4522 ****
&& TREE_CODE (TREE_OPERAND (arg, 1)) == BASELINK)
arg = BASELINK_FUNCTIONS (TREE_OPERAND (arg, 1));
! if (TREE_CODE (arg) == COMPONENT_REF
! && DECL_C_BIT_FIELD (TREE_OPERAND (arg, 1)))
{
error ("attempt to take address of bit-field structure member `%D'",
TREE_OPERAND (arg, 1));
return error_mark_node;
}
! else if (TREE_CODE (arg) == COMPONENT_REF
! && TREE_CODE (TREE_OPERAND (arg, 0)) == INDIRECT_REF
! && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (arg, 0), 0))
! == INTEGER_CST))
{
! /* offsetof idiom, fold it. */
tree field = TREE_OPERAND (arg, 1);
tree rval = build_unary_op (ADDR_EXPR, TREE_OPERAND (arg, 0), 0);
tree binfo = lookup_base (TREE_TYPE (TREE_TYPE (rval)),
--- 4504,4522 ----
&& TREE_CODE (TREE_OPERAND (arg, 1)) == BASELINK)
arg = BASELINK_FUNCTIONS (TREE_OPERAND (arg, 1));
! if (TREE_CODE (arg) != COMPONENT_REF)
! addr = build_address (arg);
! else if (DECL_C_BIT_FIELD (TREE_OPERAND (arg, 1)))
{
error ("attempt to take address of bit-field structure member `%D'",
TREE_OPERAND (arg, 1));
return error_mark_node;
}
! else
{
! /* Unfortunately we cannot just build an address
! expression here, because we would not handle
! address-constant-expressions or offsetof correctly. */
tree field = TREE_OPERAND (arg, 1);
tree rval = build_unary_op (ADDR_EXPR, TREE_OPERAND (arg, 0), 0);
tree binfo = lookup_base (TREE_TYPE (TREE_TYPE (rval)),
*************** build_unary_op (code, xarg, noconvert)
*** 4529,4536 ****
addr = fold (build (PLUS_EXPR, argtype, rval,
cp_convert (argtype, byte_position (field))));
}
- else
- addr = build_address (arg);
if (TREE_CODE (argtype) == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (argtype)) == METHOD_TYPE)
--- 4529,4534 ----
// { dg-do run }
// Copyright (C) 2003 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 19 Apr 2003 <nathan at codesourcery dot com>
// PR 9881. address-constant-expression not static initialized
struct bar {
double p;
}; // bar
bar v;
static bool error = false;
struct foo {
static double *a;
static double *b;
static double storage;
};
struct baz {
baz () {
if (foo::a != &v.p)
error = true;
if (foo::b != &foo::storage)
error = true;
}
};
baz f; // Get constructor to run before any other non-static initializers
double *foo::a = &(((bar *)(&v))->p);
double *foo::b = &(((bar *)(&foo::storage))->p);
double foo::storage = 0.0;
int main() {
return error;
}