This is the mail archive of the
java@gcc.gnu.org
mailing list for the Java project.
Re: aliasing warnings during libgcj build
- From: Andrew Haley <aph at redhat dot com>
- To: Richard Guenther <rguenther at suse dot de>
- Cc: java at gcc dot gnu dot org
- Date: Tue, 13 Dec 2005 16:53:09 +0000
- Subject: Re: aliasing warnings during libgcj build
- References: <Pine.LNX.4.63.0512121220510.6048@t148.fhfr.qr>
Richard Guenther writes:
> The following code from java::lang::Class causes an aliasing warning:
>
> class java::lang::Class : public java::lang::Object
> {
> public:
> ...
> inline jclass getComponentType (void)
> {
> return isArray () ? (* (jclass *) &methods) : 0;
> }
> ...
> // Methods. If this is an array class, then this field holds a
> // pointer to the element type.
> _Jv_Method *methods;
> ...
> };
>
>
> First of all, taking the address of methods before casting looks
> fishy here and from the comments I would have written
>
> return isArray () ? (* (jclass *) methods) : 0;
>
> here (so at least the comment needs clarification). The proper
> fix here is to use a union (matching the code above):
>
> union {
> _Jv_Method *m;
> jclass c; // or jclass *c, if the comment is really correct
> } methods;
>
>
> The code as current may cause miscompilations, especially because
> getComponentType is inline.
The fix for this I've attached is almost unbelievably trivial, but
there is at least the possibility that this might not be a
binary-compatible change. That is to say,
union {
_Jv_Method *methods;
jclass element_type;
};
might actually have different alignment/padding from
_Jv_Method *methods;
To avoid this possibility, it might actually be best to declare
methods as type void*.
Andrew.
Index: java/lang/natClassLoader.cc
===================================================================
*** java/lang/natClassLoader.cc (revision 108423)
--- java/lang/natClassLoader.cc (working copy)
*************** _Jv_NewArrayClass (jclass element, java:
*** 435,441 ****
= java::lang::Object::class$.vtable_method_count;
// Stash the pointer to the element type.
! array_class->methods = (_Jv_Method *) element;
// Register our interfaces.
static jclass interfaces[] =
--- 435,441 ----
= java::lang::Object::class$.vtable_method_count;
// Stash the pointer to the element type.
! array_class->element_type = element;
// Register our interfaces.
static jclass interfaces[] =
Index: java/lang/Class.h
===================================================================
*** java/lang/Class.h (revision 108423)
--- java/lang/Class.h (working copy)
*************** public:
*** 336,342 ****
inline jclass getComponentType (void)
{
! return isArray () ? (* (jclass *) &methods) : 0;
}
jboolean isAssignableFrom (jclass cls);
--- 336,342 ----
inline jclass getComponentType (void)
{
! return isArray () ? element_type : 0;
}
jboolean isAssignableFrom (jclass cls);
*************** private:
*** 514,520 ****
_Jv_Constants constants;
// Methods. If this is an array class, then this field holds a
// pointer to the element type.
! _Jv_Method *methods;
// Number of methods. If this class is primitive, this holds the
// character used to represent this type in a signature.
jshort method_count;
--- 514,523 ----
_Jv_Constants constants;
// Methods. If this is an array class, then this field holds a
// pointer to the element type.
! union {
! _Jv_Method *methods;
! jclass element_type;
! };
// Number of methods. If this class is primitive, this holds the
// character used to represent this type in a signature.
jshort method_count;