C++ PATCH: Check pod-class
Nathan Sidwell
nathan@acm.org
Thu Apr 8 07:21:00 GMT 1999
Jason Merrill wrote:
> In the standard, it's spelled POD, not PoD.
Check. For some reason I've had PoD erroneously etched onto my brain.
> Please avoid re-indenting code when reasonable, to make cvs annotate more
> useful. Often this means that if you need a new variable
> (i.e. field_type), you add it at the top of the function.
Check. Actually, this showed up several places in finish_struct_1 where we
repeatedly used the member's type, or looked into its array core. I hold the
member's type in an existing variable, TYPE, which I moved up from an inner
scope.
> The sense of the flag should be reversed so it indicates non-POD, so that
> internally generated classes are considered POD by default.
Check. I was trying to avoid double negatives...
> The warnings you've added to build_component_ref need to be more verbose;
> tell them what they can't do, not just why.
Check, they now say "using member function `foo' with NULL ptr to `class X'" or
equivalent.
> Never use IDENTIFIER_POINTER in printing an diagnostic in the C++ frontend.
> Use cp_error et al instead.
Check. My fault for copying some errant code -- I've tidied an additional
instance in typeck.c too.
> We need to get you an account on egcs so you can check things in
> yourself...
I'll hold off submitting an exception specification patch for a bit then.
As ever, no new regressions. Hope it's ok this time :-)
Enjoy
nathan
--
Dr Nathan Sidwell :: Computer Science Department :: Bristol University
You can up the bandwidth, but you can't up the speed of light
nathan@acm.org http://www.cs.bris.ac.uk/~nathan/ nathan@cs.bris.ac.uk
egcs/gcc/cp/ChangeLog:
Thu Apr 8 13:28:36 BST 1999 Nathan Sidwell <nathan@acm.org>
* call.c (convert_arg_to_ellipsis): Use pod_type_p.
* cp-tree.h (struct lang_type): Added non_pod_class flag.
(CLASSTYPE_NON_POD_P): New macro to access it.
(build_component_addr): Remove prototype.
* class.c (finish_struct_1): Determine non-PODness.
Check for arrays of pointers (-Weffc++).
Remove array inspection duplicated code.
* tree.c (pod_type_p): Use CLASSTYPE_NON_POD_P.
* typeck.c (build_component_addr): Make static. Remove MSG
argument.
(build_component_ref): Check for `offsetof' idiom, and warn on
undefined uses.
(build_component_addr): Likewise. Remove MSG parameter, clean up
comment.
(build_x_function_call): Use cp_error.
(build_unary_op): Change call of build_component_addr.
Index: egcs/gcc/cp/call.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/call.c,v
retrieving revision 1.140
diff -c -3 -p -r1.140 call.c
*** call.c 1999/04/02 15:36:02 1.140
--- call.c 1999/04/08 13:03:17
*************** convert_like (convs, expr)
*** 3142,3162 ****
}
/* ARG is being passed to a varargs function. Perform any conversions
! required. Return the converted value. */
tree
convert_arg_to_ellipsis (arg)
tree arg;
{
if (TREE_CODE (TREE_TYPE (arg)) == REAL_TYPE
&& (TYPE_PRECISION (TREE_TYPE (arg))
< TYPE_PRECISION (double_type_node)))
/* Convert `float' to `double'. */
arg = cp_convert (double_type_node, arg);
- else if (IS_AGGR_TYPE (TREE_TYPE (arg))
- && ! TYPE_HAS_TRIVIAL_INIT_REF (TREE_TYPE (arg)))
- cp_warning ("cannot pass objects of type `%T' through `...'",
- TREE_TYPE (arg));
else
/* Convert `short' and `char' to full-size `int'. */
arg = default_conversion (arg);
--- 3142,3163 ----
}
/* ARG is being passed to a varargs function. Perform any conversions
! required. Array/function to pointer decay must have already happened.
! Return the converted value. */
tree
convert_arg_to_ellipsis (arg)
tree arg;
{
+ if (! pod_type_p (TREE_TYPE (arg)))
+ cp_warning ("cannot pass objects of non-POD type `%#T' through `...'",
+ TREE_TYPE (arg));
+
if (TREE_CODE (TREE_TYPE (arg)) == REAL_TYPE
&& (TYPE_PRECISION (TREE_TYPE (arg))
< TYPE_PRECISION (double_type_node)))
/* Convert `float' to `double'. */
arg = cp_convert (double_type_node, arg);
else
/* Convert `short' and `char' to full-size `int'. */
arg = default_conversion (arg);
Index: egcs/gcc/cp/class.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/class.c,v
retrieving revision 1.141
diff -c -3 -p -r1.141 class.c
*** class.c 1999/04/03 01:23:24 1.141
--- class.c 1999/04/08 13:03:21
*************** finish_struct_1 (t, warn_anon)
*** 3097,3102 ****
--- 3097,3103 ----
int cant_have_const_ctor;
int no_const_asn_ref;
int has_mutable = 0;
+ int non_pod_class = 0;
/* The index of the first base class which has virtual
functions. Only applied to non-virtual baseclasses. */
*************** finish_struct_1 (t, warn_anon)
*** 3243,3248 ****
--- 3244,3250 ----
last_x = NULL_TREE;
for (x = fields; x; x = TREE_CHAIN (x))
{
+ tree type = TREE_TYPE (x);
GNU_xref_member (current_class_name, x);
if (TREE_CODE (x) == FIELD_DECL)
*************** finish_struct_1 (t, warn_anon)
*** 3284,3304 ****
/* Perform error checking that did not get done in
grokdeclarator. */
! if (TREE_CODE (TREE_TYPE (x)) == FUNCTION_TYPE)
{
cp_error_at ("field `%D' invalidly declared function type",
x);
! TREE_TYPE (x) = build_pointer_type (TREE_TYPE (x));
}
! else if (TREE_CODE (TREE_TYPE (x)) == METHOD_TYPE)
{
cp_error_at ("field `%D' invalidly declared method type", x);
! TREE_TYPE (x) = build_pointer_type (TREE_TYPE (x));
}
! else if (TREE_CODE (TREE_TYPE (x)) == OFFSET_TYPE)
{
cp_error_at ("field `%D' invalidly declared offset type", x);
! TREE_TYPE (x) = build_pointer_type (TREE_TYPE (x));
}
#if 0
--- 3286,3309 ----
/* Perform error checking that did not get done in
grokdeclarator. */
! if (TREE_CODE (type) == FUNCTION_TYPE)
{
cp_error_at ("field `%D' invalidly declared function type",
x);
! type = build_pointer_type (type);
! TREE_TYPE (x) = type;
}
! else if (TREE_CODE (type) == METHOD_TYPE)
{
cp_error_at ("field `%D' invalidly declared method type", x);
! type = build_pointer_type (type);
! TREE_TYPE (x) = type;
}
! else if (TREE_CODE (type) == OFFSET_TYPE)
{
cp_error_at ("field `%D' invalidly declared offset type", x);
! type = build_pointer_type (type);
! TREE_TYPE (x) = type;
}
#if 0
*************** finish_struct_1 (t, warn_anon)
*** 3336,3341 ****
--- 3341,3348 ----
Also do a little ANSI jig if necessary. */
if (TREE_CODE (TREE_TYPE (x)) == REFERENCE_TYPE)
{
+ non_pod_class = 1;
+
if (DECL_INITIAL (x) == NULL_TREE)
ref_sans_init = 1;
*************** finish_struct_1 (t, warn_anon)
*** 3355,3366 ****
}
}
! if (TREE_CODE (TREE_TYPE (x)) == POINTER_TYPE)
has_pointers = 1;
! if (DECL_MUTABLE_P (x) || TYPE_HAS_MUTABLE_P (TREE_TYPE (x)))
has_mutable = 1;
/* If any field is const, the structure type is pseudo-const. */
if (TREE_READONLY (x))
{
--- 3362,3380 ----
}
}
! while (TREE_CODE (type) == ARRAY_TYPE)
! type = TREE_TYPE (type);
!
! if (TREE_CODE (type) == POINTER_TYPE)
has_pointers = 1;
! if (DECL_MUTABLE_P (x) || TYPE_HAS_MUTABLE_P (type))
has_mutable = 1;
+ if (! pod_type_p (type) || TYPE_PTRMEM_P (type)
+ || TYPE_PTRMEMFUNC_P (type))
+ non_pod_class = 1;
+
/* If any field is const, the structure type is pseudo-const. */
if (TREE_READONLY (x))
{
*************** finish_struct_1 (t, warn_anon)
*** 3388,3401 ****
{
/* A field that is pseudo-const makes the structure
likewise. */
! tree t1 = TREE_TYPE (x);
! while (TREE_CODE (t1) == ARRAY_TYPE)
! t1 = TREE_TYPE (t1);
! if (IS_AGGR_TYPE (t1))
{
! if (C_TYPE_FIELDS_READONLY (t1))
C_TYPE_FIELDS_READONLY (t) = 1;
! if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (t1))
const_sans_init = 1;
}
}
--- 3402,3412 ----
{
/* A field that is pseudo-const makes the structure
likewise. */
! if (IS_AGGR_TYPE (type))
{
! if (C_TYPE_FIELDS_READONLY (type))
C_TYPE_FIELDS_READONLY (t) = 1;
! if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (type))
const_sans_init = 1;
}
}
*************** finish_struct_1 (t, warn_anon)
*** 3407,3413 ****
/* Invalid bit-field size done by grokfield. */
/* Detect invalid bit-field type. */
if (DECL_INITIAL (x)
! && ! INTEGRAL_TYPE_P (TREE_TYPE (x)))
{
cp_error_at ("bit-field `%#D' with non-integral type", x);
DECL_INITIAL (x) = NULL;
--- 3418,3424 ----
/* Invalid bit-field size done by grokfield. */
/* Detect invalid bit-field type. */
if (DECL_INITIAL (x)
! && ! (type == TREE_TYPE (x) && INTEGRAL_TYPE_P (type)))
{
cp_error_at ("bit-field `%#D' with non-integral type", x);
DECL_INITIAL (x) = NULL;
*************** finish_struct_1 (t, warn_anon)
*** 3455,3474 ****
TYPE_PRECISION (long_long_unsigned_type_node));
cp_error_at (" in declaration of `%D'", x);
}
! else if (width > TYPE_PRECISION (TREE_TYPE (x))
! && TREE_CODE (TREE_TYPE (x)) != ENUMERAL_TYPE
! && TREE_CODE (TREE_TYPE (x)) != BOOLEAN_TYPE)
{
cp_warning_at ("width of `%D' exceeds its type", x);
}
! else if (TREE_CODE (TREE_TYPE (x)) == ENUMERAL_TYPE
! && ((min_precision (TYPE_MIN_VALUE (TREE_TYPE (x)),
! TREE_UNSIGNED (TREE_TYPE (x))) > width)
! || (min_precision (TYPE_MAX_VALUE (TREE_TYPE (x)),
! TREE_UNSIGNED (TREE_TYPE (x))) > width)))
{
cp_warning_at ("`%D' is too small to hold all values of `%#T'",
! x, TREE_TYPE (x));
}
if (DECL_INITIAL (x))
--- 3466,3485 ----
TYPE_PRECISION (long_long_unsigned_type_node));
cp_error_at (" in declaration of `%D'", x);
}
! else if (width > TYPE_PRECISION (type)
! && TREE_CODE (type) != ENUMERAL_TYPE
! && TREE_CODE (type) != BOOLEAN_TYPE)
{
cp_warning_at ("width of `%D' exceeds its type", x);
}
! else if (TREE_CODE (type) == ENUMERAL_TYPE
! && ((min_precision (TYPE_MIN_VALUE (type),
! TREE_UNSIGNED (type)) > width)
! || (min_precision (TYPE_MAX_VALUE (type),
! TREE_UNSIGNED (type)) > width)))
{
cp_warning_at ("`%D' is too small to hold all values of `%#T'",
! x, type);
}
if (DECL_INITIAL (x))
*************** finish_struct_1 (t, warn_anon)
*** 3486,3507 ****
#ifdef PCC_BITFIELD_TYPE_MATTERS
if (PCC_BITFIELD_TYPE_MATTERS)
DECL_ALIGN (x) = MAX (DECL_ALIGN (x),
! TYPE_ALIGN (TREE_TYPE (x)));
#endif
}
}
}
else
/* Non-bit-fields are aligned for their type. */
! DECL_ALIGN (x) = MAX (DECL_ALIGN (x), TYPE_ALIGN (TREE_TYPE (x)));
}
else
{
- tree type = TREE_TYPE (x);
-
- while (TREE_CODE (type) == ARRAY_TYPE)
- type = TREE_TYPE (type);
-
if (TYPE_LANG_SPECIFIC (type) && ! ANON_UNION_P (x)
&& ! TYPE_PTRMEMFUNC_P (type))
{
--- 3497,3513 ----
#ifdef PCC_BITFIELD_TYPE_MATTERS
if (PCC_BITFIELD_TYPE_MATTERS)
DECL_ALIGN (x) = MAX (DECL_ALIGN (x),
! TYPE_ALIGN (type));
#endif
}
}
}
else
/* Non-bit-fields are aligned for their type. */
! DECL_ALIGN (x) = MAX (DECL_ALIGN (x), TYPE_ALIGN (type));
}
else
{
if (TYPE_LANG_SPECIFIC (type) && ! ANON_UNION_P (x)
&& ! TYPE_PTRMEMFUNC_P (type))
{
*************** finish_struct_1 (t, warn_anon)
*** 3606,3611 ****
--- 3612,3620 ----
if (! IS_SIGNATURE (t))
CLASSTYPE_NON_AGGREGATE (t)
= ! aggregate || has_virtual || TYPE_HAS_CONSTRUCTOR (t);
+ CLASSTYPE_NON_POD_P (t)
+ = non_pod_class || CLASSTYPE_NON_AGGREGATE (t)
+ || TYPE_HAS_DESTRUCTOR (t) || TYPE_HAS_ASSIGN_REF (t);
TYPE_HAS_REAL_ASSIGN_REF (t) |= TYPE_HAS_ASSIGN_REF (t);
TYPE_HAS_COMPLEX_ASSIGN_REF (t)
|= TYPE_HAS_ASSIGN_REF (t) || TYPE_USES_VIRTUAL_BASECLASSES (t);
Index: egcs/gcc/cp/cp-tree.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.213
diff -c -3 -p -r1.213 cp-tree.h
*** cp-tree.h 1999/04/02 15:36:01 1.213
--- cp-tree.h 1999/04/08 13:03:24
*************** struct lang_type
*** 727,737 ****
unsigned non_aggregate : 1;
unsigned is_partial_instantiation : 1;
unsigned has_mutable : 1;
/* The MIPS compiler gets it wrong if this struct also
does not fill out to a multiple of 4 bytes. Add a
member `dummy' with new bits if you go over the edge. */
! unsigned dummy : 11;
} type_flags;
int vsize;
--- 727,738 ----
unsigned non_aggregate : 1;
unsigned is_partial_instantiation : 1;
unsigned has_mutable : 1;
+ unsigned non_pod_class : 1;
/* The MIPS compiler gets it wrong if this struct also
does not fill out to a multiple of 4 bytes. Add a
member `dummy' with new bits if you go over the edge. */
! unsigned dummy : 10;
} type_flags;
int vsize;
*************** struct lang_type
*** 1001,1006 ****
--- 1002,1011 ----
#define CLASSTYPE_HAS_MUTABLE(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_mutable)
#define TYPE_HAS_MUTABLE_P(NODE) (cp_has_mutable_p (NODE))
+ /* Determine class PODness.
+ Nonzero means that this class type is a pod class. */
+ #define CLASSTYPE_NON_POD_P(NODE) (TYPE_LANG_SPECIFIC (NODE)->type_flags.non_pod_class)
+
/* A list of class types of which this type is a friend. The
TREE_VALUE is normally a TYPE, but will be a TEMPLATE_DECL in the
case of a template friend. */
*************** extern tree convert_arguments PROTO((t
*** 3410,3416 ****
extern tree build_x_binary_op PROTO((enum tree_code, tree, tree));
extern tree build_binary_op PROTO((enum tree_code, tree, tree, int));
extern tree build_binary_op_nodefault PROTO((enum tree_code, tree, tree, enum tree_code));
- extern tree build_component_addr PROTO((tree, tree, const char *));
extern tree build_x_unary_op PROTO((enum tree_code, tree));
extern tree build_unary_op PROTO((enum tree_code, tree, int));
extern tree unary_complex_lvalue PROTO((enum tree_code, tree));
--- 3415,3420 ----
Index: egcs/gcc/cp/tree.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/tree.c,v
retrieving revision 1.103
diff -c -3 -p -r1.103 tree.c
*** tree.c 1999/03/31 18:59:19 1.103
--- tree.c 1999/04/08 13:03:48
*************** int
*** 2673,2701 ****
pod_type_p (t)
tree t;
{
- tree f;
-
while (TREE_CODE (t) == ARRAY_TYPE)
t = TREE_TYPE (t);
! if (! IS_AGGR_TYPE (t))
return 1;
!
! if (CLASSTYPE_NON_AGGREGATE (t)
! || TYPE_HAS_COMPLEX_ASSIGN_REF (t)
! || TYPE_HAS_DESTRUCTOR (t))
return 0;
-
- for (f = TYPE_FIELDS (t); f; f = TREE_CHAIN (f))
- {
- if (TREE_CODE (f) != FIELD_DECL)
- continue;
-
- if (TREE_CODE (TREE_TYPE (f)) == REFERENCE_TYPE
- || TYPE_PTRMEMFUNC_P (TREE_TYPE (f))
- || TYPE_PTRMEM_P (TREE_TYPE (f)))
- return 0;
- }
-
return 1;
}
--- 2673,2684 ----
pod_type_p (t)
tree t;
{
while (TREE_CODE (t) == ARRAY_TYPE)
t = TREE_TYPE (t);
! if (! CLASS_TYPE_P (t))
return 1;
! if (CLASSTYPE_NON_POD_P (t))
return 0;
return 1;
}
Index: egcs/gcc/cp/typeck.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/typeck.c,v
retrieving revision 1.150
diff -c -3 -p -r1.150 typeck.c
*** typeck.c 1999/04/02 15:36:57 1.150
--- typeck.c 1999/04/08 13:03:52
*************** static tree convert_sequence PROTO((tree
*** 55,60 ****
--- 55,61 ----
#endif
static tree lookup_anon_field PROTO((tree, tree));
static tree pointer_diff PROTO((tree, tree, tree));
+ static tree build_component_addr PROTO((tree, tree));
static tree qualify_type PROTO((tree, tree));
static tree get_delta_difference PROTO((tree, tree, int));
static int comp_cv_target_types PROTO((tree, tree, int));
*************** build_component_ref (datum, component, b
*** 2035,2040 ****
--- 2036,2042 ----
register tree ref;
tree field_type;
int type_quals;
+ int off_null_ptr = 0;
if (processing_template_decl)
return build_min_nt (COMPONENT_REF, datum, component);
*************** build_component_ref (datum, component, b
*** 2128,2133 ****
--- 2130,2145 ----
return TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 1);
}
+ {
+ /* Determine if this is an offsetof idiom. */
+ tree probe = datum;
+
+ while (TREE_CODE (probe) == COMPONENT_REF)
+ probe = TREE_OPERAND (probe, 0);
+ off_null_ptr = (TREE_CODE (probe) == INDIRECT_REF
+ && integer_zerop (TREE_OPERAND (probe, 0)));
+ }
+
/* Look up component name in the structure type definition. */
if (CLASSTYPE_VFIELD (basetype)
&& DECL_NAME (CLASSTYPE_VFIELD (basetype)) == component)
*************** build_component_ref (datum, component, b
*** 2168,2174 ****
now. Otherwise, we have to wait and see what context it is
used in; a component_ref involving a non-static member
function can only be used in a call (expr.ref). */
!
if (TREE_CHAIN (fndecls) == NULL_TREE
&& TREE_CODE (TREE_VALUE (fndecls)) == FUNCTION_DECL)
{
--- 2180,2190 ----
now. Otherwise, we have to wait and see what context it is
used in; a component_ref involving a non-static member
function can only be used in a call (expr.ref). */
!
! if (off_null_ptr)
! cp_warning ("using member function `%D' with NULL ptr to `%#T'",
! name, TREE_TYPE (datum));
!
if (TREE_CHAIN (fndecls) == NULL_TREE
&& TREE_CODE (TREE_VALUE (fndecls)) == FUNCTION_DECL)
{
*************** build_component_ref (datum, component, b
*** 2209,2214 ****
--- 2225,2235 ----
mark_used (field);
else
TREE_USED (field) = 1;
+
+ if (off_null_ptr && TREE_CODE (field) == VAR_DECL)
+ cp_warning ("using static member `%D' with NULL ptr to `%#T'",
+ name, TREE_TYPE (datum));
+
return field;
}
}
*************** build_component_ref (datum, component, b
*** 2225,2230 ****
--- 2246,2255 ----
base = TYPE_CONTEXT (base);
}
+ if (base != basetype && off_null_ptr && ! pod_type_p (basetype))
+ cp_warning ("using non-POD type `%#T' with NULL ptr",
+ basetype);
+
/* Handle base classes here... */
if (base != basetype && TYPE_USES_COMPLEX_INHERITANCE (basetype))
{
*************** build_x_function_call (function, params,
*** 2685,2692 ****
{
if (current_class_type == NULL_TREE)
{
! error ("object missing in call to method `%s'",
! IDENTIFIER_POINTER (function));
return error_mark_node;
}
/* Yow: call from a static member function. */
--- 2710,2716 ----
{
if (current_class_type == NULL_TREE)
{
! cp_error ("object missing in call to method `%D'", function);
return error_mark_node;
}
/* Yow: call from a static member function. */
*************** pointer_diff (op0, op1, ptrtype)
*** 4248,4264 ****
}
/* Handle the case of taking the address of a COMPONENT_REF.
! Called by `build_unary_op' and `build_up_reference'.
ARG is the COMPONENT_REF whose address we want.
! ARGTYPE is the pointer type that this address should have.
! MSG is an error message to print if this COMPONENT_REF is not
! addressable (such as a bitfield). */
! tree
! build_component_addr (arg, argtype, msg)
tree arg, argtype;
- const char *msg;
{
tree field = TREE_OPERAND (arg, 1);
tree basetype = decl_type_context (field);
--- 4272,4285 ----
}
/* Handle the case of taking the address of a COMPONENT_REF.
! Called by `build_unary_op'.
ARG is the COMPONENT_REF whose address we want.
! ARGTYPE is the pointer type that this address should have. */
! static tree
! build_component_addr (arg, argtype)
tree arg, argtype;
{
tree field = TREE_OPERAND (arg, 1);
tree basetype = decl_type_context (field);
*************** build_component_addr (arg, argtype, msg)
*** 4266,4274 ****
my_friendly_assert (TREE_CODE (field) == FIELD_DECL, 981018);
if (DECL_C_BIT_FIELD (field))
{
! error (msg, IDENTIFIER_POINTER (DECL_NAME (field)));
return error_mark_node;
}
--- 4287,4308 ----
my_friendly_assert (TREE_CODE (field) == FIELD_DECL, 981018);
+ if (! pod_type_p (basetype))
+ {
+ /* Determine if this is an offsetof idiom. */
+ tree probe = arg;
+
+ while (TREE_CODE (probe) == COMPONENT_REF)
+ probe = TREE_OPERAND (probe, 0);
+ if (TREE_CODE (probe) == INDIRECT_REF
+ && integer_zerop (TREE_OPERAND (probe, 0)))
+ cp_warning ("using non-POD type `%#T' with NULL ptr", basetype);
+ }
+
if (DECL_C_BIT_FIELD (field))
{
! cp_error ("attempt to take address of bit-field structure member `%D'",
! field);
return error_mark_node;
}
*************** build_unary_op (code, xarg, noconvert)
*** 4731,4739 ****
tree addr;
if (TREE_CODE (arg) == COMPONENT_REF)
! addr = build_component_addr
! (arg, argtype,
! "attempt to take address of bit-field structure member `%s'");
else
addr = build1 (ADDR_EXPR, argtype, arg);
--- 4765,4771 ----
tree addr;
if (TREE_CODE (arg) == COMPONENT_REF)
! addr = build_component_addr (arg, argtype);
else
addr = build1 (ADDR_EXPR, argtype, arg);
More information about the Gcc-patches
mailing list