This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
[gcjx] Patch: FYI: varargs -vs- type inference
- From: Tom Tromey <tromey at redhat dot com>
- To: Java Patch List <java-patches at gcc dot gnu dot org>
- Date: 01 Dec 2005 19:01:52 -0700
- Subject: [gcjx] Patch: FYI: varargs -vs- type inference
- Reply-to: tromey at redhat dot com
I'm checking this in on the gcjx branch.
This fixes type inference to understand that varargs processing only
happens in the 3rd phase of method invocation processing. The test
case for this looks like:
public class va2
{
public static class vaList<T> { }
public static <T> vaList<T> asList(final T... a)
{
return null;
}
public static void m(vaList<String> x) { }
public static void doit(String[] args)
{
m(asList(args));
}
}
Without this patch we think that the asList call returns a
vaList<String[]> and not a vaList<String>.
Tom
Index: ChangeLog
from Tom Tromey <tromey@redhat.com>
* model/method.cc (method_conversion_p): Updated for new argument
to unify.
* unify.cc (unify): Added is_varargs argument.
(unifier::unify): Likewise.
* unify.hh (unify): Added is_varargs argument.
Index: model/method.cc
===================================================================
--- model/method.cc (revision 107604)
+++ model/method.cc (working copy)
@@ -312,7 +312,8 @@
model_type_map typeargs;
// FIXME: error detection?
// FIXME: pass in argument for varargs handling.
- unify (args, this, return_type->type (), assign_type, typeargs);
+ unify (args, this, return_type->type (), assign_type, typeargs,
+ phase == PHASE_3);
return do_method_conversion_p (typeargs, args, phase);
}
return do_method_conversion_p (args, phase);
Index: unify.cc
===================================================================
--- unify.cc (revision 107683)
+++ unify.cc (working copy)
@@ -24,6 +24,16 @@
// U << V : U convertible to V by method invoc. conv.
+ // This is used to avoid memory leaks when creating temporary
+ // wildcards and other objects during unification.
+static std::list<ref_element> gcprolist;
+
+static void
+gcpro (const ref_element &elt)
+{
+ gcprolist.push_back (elt);
+}
+
/// This class implements the type inference algorithm as explained in
/// the JLS 3. Names in this class are general chosen to follow the
/// JLS. Reading the text is strongly advised, this code is not
@@ -43,10 +53,6 @@
// The formal type parameters for the method.
std::set<model_type_variable *> formal_type_params;
- // This is used to avoid memory leaks when creating temporary
- // wildcards and other objects during unification.
- std::list<ref_element> gcpro;
-
// Location we should use when creating things.
// FIXME: a request element would be better.
location where;
@@ -198,7 +204,9 @@
std::list<model_class *> classes;
classes.push_back (left);
classes.push_back (right);
- return new model_intersection_type (where, classes);
+ model_intersection_type *r = new model_intersection_type (where, classes);
+ gcpro (r);
+ return r;
}
// Compute the least containing type argument for a pair of classes.
@@ -243,8 +251,8 @@
new_bound = compute_glb (left, rbound);
else
new_bound = compute_lub (left, rbound);
+ gcpro (new_bound);
result = new model_wildcard (where, new_bound, rw->super_p ());
- gcpro.push_back (result);
}
else if (left == right)
result = left;
@@ -252,8 +260,8 @@
{
model_class *lub = compute_lub (left, right);
result = new model_wildcard (where, lub);
- gcpro.push_back (result);
}
+ gcpro (result);
return result;
}
@@ -655,7 +663,7 @@
}
void unify (const std::list<model_type *> &actual, model_method *method,
- model_type_map &result)
+ model_type_map &result, bool is_varargs)
{
std::list<model_type *> formal;
get_formal_argument_types (method, formal);
@@ -678,7 +686,7 @@
else
{
ft = *fi++;
- if (method->varargs_p () && fi == formal.end ())
+ if (is_varargs && method->varargs_p () && fi == formal.end ())
{
// The type of the last formal argument must be an
// array type. Every subsequent actual argument must
@@ -712,11 +720,12 @@
model_method *method,
model_type *declared_return_type,
model_type *assignment_type,
- model_type_map &result)
+ model_type_map &result,
+ bool is_varargs)
{
// FIXME: correct location.
unifier u (method->get_location (), declared_return_type, assignment_type);
- u.unify (actual, method, result);
+ u.unify (actual, method, result, is_varargs);
}
model_class *
Index: unify.hh
===================================================================
--- unify.hh (revision 107604)
+++ unify.hh (working copy)
@@ -30,13 +30,15 @@
/// of this method is converted by assignment conversion. If no
/// assignment conversion is performed, should be NULL.
/// @param result the resulting actual argument types
+/// @param is_varargs true if varargs matching should be done
/// FIXME: actual result type ... ?
void
unify (const std::list<model_type *> &actual,
model_method *method,
model_type *declared_return_type,
model_type *assignment_type,
- model_type_map &result);
+ model_type_map &result,
+ bool is_varargs);
/// Compute the LUB of two classes.
model_class *compute_lub (model_element *request, model_class *,