This is the mail archive of the java@gcc.gnu.org mailing list for the Java 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]

Re: aliasing warnings during libgcj build


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;


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