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]

[C++ PATCH] Fix 9881, break something else


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;
}

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