[gcjx] raw type fixes

Tom Tromey tromey@redhat.com
Mon Nov 7 21:46:00 GMT 2005


I'm checking this in on the gcjx branch.

This fixes some bugs introduced by the raw type change.  In
particular:

* access checking was broken
* we needed to find the raw type in name classification, not in the
  forwarding type resolution code
* doing capture conversion in widening reference promotion turns out
  to be broken; the spec is somewhat unclear here (at least, I didn't
  understand it)

More to come.

Tom

Index: ChangeLog
from  Tom Tromey  <tromey@redhat.com>
	* access.cc (unwrap_raw_class): New function.
	(accessible_p): Use it.
	(trampoline_required_p): Likewise.
	* model/fwdtype.cc (maybe_get_erasure): Removed.
	(resolve): Don't take erasure.
	* name.cc (maybe_get_erasure): New function.
	(classify_type_name): Use it.
	* conversions.cc (widen_instantiation): Don't do capture
	conversion.
	* model/wildcard.cc (contains_p): Handle case where other
	wildcard does not have a bound.

Index: conversions.cc
===================================================================
--- conversions.cc	(revision 106607)
+++ conversions.cc	(working copy)
@@ -199,9 +199,11 @@
     }
 
   // Now we check 'contains' of each type argument.
-  model_class_instance *from_i
-    = capture_conversion (from /* FIXME */,
-			  assert_cast<model_class_instance *> (from));
+  model_class_instance *from_i = assert_cast<model_class_instance *> (from);
+  // The spec says to do capture conversion on 'from_i' here, but then
+  // it does not define the 'contains' operation on type variables.
+  // This causes us to reject valid assignments.  Instead we just keep
+  // the un-captured parameterization, which does the right thing.
   model_class_instance *to_i = assert_cast<model_class_instance *> (to);
   std::list<model_class *> from_args, to_args;
   from_i->get_type_map (from_args);
Index: model/fwdtype.cc
===================================================================
--- model/fwdtype.cc	(revision 106607)
+++ model/fwdtype.cc	(working copy)
@@ -21,14 +21,6 @@
 
 #include "typedefs.hh"
 
-static model_class *
-maybe_get_erasure (model_class *klass)
-{
-  if (! klass->type_variable_p () && ! klass->wildcard_p ())
-    klass = assert_cast<model_class *> (klass->erasure ());
-  return klass;
-}
-
 owner<model_forwarding_type>
 model_forwarding_type::array ()
 {
@@ -82,9 +74,6 @@
 
   // FIXME null return
   resolved_type = classify_type_name (scope, this, name);
-  model_class *k = dynamic_cast<model_class *> (resolved_type);
-  if (k)
-    resolved_type = maybe_get_erasure (k);
 }
 
 void
@@ -170,8 +159,7 @@
   model_type *r = classify_type_name (scope, this, name, context);
   if (! r->reference_p ())
     throw error ("reference type expected");
-  model_class *k = assert_cast<model_class *> (r);
-  resolved_type = maybe_get_erasure (k);
+  resolved_type = r;
 }
 
 void
Index: model/wildcard.cc
===================================================================
--- model/wildcard.cc	(revision 106309)
+++ model/wildcard.cc	(working copy)
@@ -51,10 +51,11 @@
   if (! other->wildcard_p ())
     return false;
   model_wildcard *w = assert_cast<model_wildcard *> (other);
-  // FIXME: maybe a bound is ok?
-  if (w->super_p () != is_super || ! w->get_bound ())
+  if (w->super_p () != is_super)
     return false;
   model_class *other_bound = w->get_bound ();
+  if (other_bound == NULL)
+    other_bound = global->get_compiler ()->java_lang_Object ();
   if (is_super)
     return other_bound->assignable_from_p (k);
   return k->assignable_from_p (other_bound);
Index: access.cc
===================================================================
--- access.cc	(revision 105944)
+++ access.cc	(working copy)
@@ -1,6 +1,6 @@
 // Access control.
 
-// Copyright (C) 2004 Free Software Foundation, Inc.
+// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
 //
 // This file is part of GCC.
 //
@@ -21,6 +21,21 @@
 
 #include "typedefs.hh"
 
+static model_class *
+unwrap_raw_class (model_class *k)
+{
+  model_raw_class *raw = dynamic_cast<model_raw_class *> (k);
+  if (raw)
+    k = raw->get_parent ();
+  else
+    {
+      model_class_instance *classi = dynamic_cast<model_class_instance *> (k);
+      if (classi)
+	k = classi->get_parent ();
+    }
+  return k;
+}
+
 bool
 accessible_p (model_type *t, IContext *request)
 {
@@ -30,7 +45,7 @@
 
   if (t->primitive_p ())
     return true;
-  model_class *klass = assert_cast<model_class *> (t);
+  model_class *klass = unwrap_raw_class (assert_cast<model_class *> (t));
 
   if (! klass->member_p ())
     {
@@ -59,7 +74,8 @@
       // the declarer.  Note the initial cast will return NULL when
       // REQUEST is a package.
       model_class *declarer = klass->get_declaring_class ();
-      for (model_class *prot = dynamic_cast<model_class *> (request);
+      for (model_class *prot
+	     = unwrap_raw_class (dynamic_cast<model_class *> (request));
 	   prot;
 	   prot = prot->get_lexically_enclosing_class ())
 	{
@@ -73,9 +89,11 @@
       // Access is permitted only within the body of the top-level
       // class enclosing the declaration.
       klass = klass->get_top_level_class ();
-      while (request != NULL && request != klass)
-	request = request->get_lexically_enclosing_class ();
-      return request == klass;
+      model_class *req_class
+	= unwrap_raw_class (dynamic_cast<model_class *> (request));
+      while (req_class != NULL && req_class != klass)
+	req_class = req_class->get_lexically_enclosing_class ();
+      return req_class == klass;
     }
 
   // Default access, but also one case of protected access.
@@ -111,8 +129,8 @@
     }
 
   if (dynamic_cast<model_class *> (request) != NULL)
-    request = assert_cast<model_class *> (assert_cast<model_class *> (request)->erasure ());
-  declarer = assert_cast<model_class *> (declarer->erasure ());
+    request = unwrap_raw_class (assert_cast<model_class *> (request));
+  declarer = unwrap_raw_class (declarer);
 
   // Make sure we can access the declaring class.
   if (! accessible_p (declarer, request))
@@ -179,6 +197,7 @@
 		       model_class **result)
 {
   assert (result);
+  request = unwrap_raw_class (request);
 
   // Access to the same class is fine.
   model_class *tclass = target->get_declaring_class ();
Index: name.cc
===================================================================
--- name.cc	(revision 105944)
+++ name.cc	(working copy)
@@ -89,6 +89,14 @@
 }
 
 static model_class *
+maybe_get_erasure (model_class *klass)
+{
+  if (! klass->type_variable_p () && ! klass->wildcard_p ())
+    klass = assert_cast<model_class *> (klass->erasure ());
+  return klass;
+}
+
+static model_class *
 check_deprecated (model_class *klass, model_element *request)
 {
   assert (klass);
@@ -119,7 +127,12 @@
 // 	(*i)->error ("could resolve to %1") % (*i);
     }
   else if (memtypes.size () == 1)
-    return check_deprecated (*(memtypes.begin ()), request);
+    {
+      model_class *result = check_deprecated (*(memtypes.begin ()), request);
+      // We only ever want to return the raw type.  Parameterization
+      // is handled elsewhere.
+      return maybe_get_erasure (result);
+    }
 
   throw type_not_found_error (request->get_location (),
 			      "type named %1 is undefined")
@@ -186,7 +199,7 @@
 	% qualname;
     }
 
-  return check_deprecated (result, request);
+  return maybe_get_erasure (check_deprecated (result, request));
 }
 
 model_field *



More information about the Java-patches mailing list