From: "Giovanni Bajo" <giovannibajo@libero.it>
To: "Bernardo Innocenti" <bernie@develer.com>
Subject: libjava e amici
Date: Thu, 20 Nov 2003 00:50:36 +0100

Finalmente ho avuto 10 minuti per guardare il problema del breakage dell'altro
giorno, era una minchiata.

Quando viene fatta una new di un oggetto di quelli Java (in C++), il frontend
crea una chiamata alla funzione _Jv_AllocObject, che però NON è un built-in, ma
una funzione normale che deve essere dichiarata. Il mio patch fa in modo che
tutte le dichiarazioni di funzioni siano overload set (anche se poi non c'è
nessun overload, ma una sola funzione), perché questo fixa vari bug e aiuterà a
pulire il codice. Ma il codice hard-codato che generava la chiamata a
_Jv_AllocObject non si aspettava di trovarsi un overload, e quindi abortiva. La
stessa cosa per quando viene fatta una throw di un oggetto Java, e ho fixato
anche quella.

Questa è la patch aggiornata. Mi fai per favore un bootstrap completo
c/c++/java, e un bel make check-g++? Grazie. Se funziona, preparo la testcase
per questa cosa e risubmitto.

Giovanni


2003-10-29  Giovanni Bajo  <giovannibajo@libero.it>

        PR c++/2294
        * name-lookup.c (push_overloaded_decl): Always construct an 
        OVERLOAD unless the declaration is a built-in.
        (set_namespace_binding): While binding OVERLOADs with only one
        declaration, we still need to call supplement_binding.
        * init.c (build_new_1): Deal with an OVERLOAD set when
        looking up for _Jv_AllocObject.
        * except.c (build_throw): Likewise for _Jv_Throw.

2003-10-29  Giovanni Bajo  <giovannibajo@libero.it>

        PR c++/2294
        * g++.dg/lookup/using9.c: New test.
        * g++.dg/lookup/java1.c: New test.


Index: name-lookup.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/name-lookup.c,v
retrieving revision 1.16
diff -c -p -r1.16 name-lookup.c
*** gcc/cp/name-lookup.c       14 Oct 2003 20:34:41 -0000      1.16
--- gcc/cp/name-lookup.c       19 Nov 2003 23:28:37 -0000
*************** push_overloaded_decl (tree decl, int fla
*** 1994,2000 ****
        }
      }

!   if (old || TREE_CODE (decl) == TEMPLATE_DECL)
      {
        if (old && TREE_CODE (old) != OVERLOAD)
        new_binding = ovl_cons (decl, ovl_cons (old, NULL_TREE));
--- 1997,2003 ----
        }
      }

!   if (!DECL_ARTIFICIAL (decl))
      {
        if (old && TREE_CODE (old) != OVERLOAD)
        new_binding = ovl_cons (decl, ovl_cons (old, NULL_TREE));
*************** push_overloaded_decl (tree decl, int fla
*** 2004,2010 ****
        OVL_USED (new_binding) = 1;
      }
    else
-     /* NAME is not ambiguous.  */
      new_binding = decl;

    if (doing_global)
--- 2007,2012 ----
*************** set_namespace_binding (tree name, tree s
*** 2862,2868 ****
    if (scope == NULL_TREE)
      scope = global_namespace;
    b = binding_for_name (NAMESPACE_LEVEL (scope), name);
!   if (!b->value || TREE_CODE (val) == OVERLOAD || val == error_mark_node)
      b->value = val;
    else
      supplement_binding (b, val);
--- 2867,2877 ----
    if (scope == NULL_TREE)
      scope = global_namespace;
    b = binding_for_name (NAMESPACE_LEVEL (scope), name);
!   if (!b->value
!       /* If OVL_CHAIN is NULL, it's the first FUNCTION_DECL for this name,
!        and we still need to call supplement_binding.  */
!       || (TREE_CODE (val) == OVERLOAD && OVL_CHAIN (val))
!       || val == error_mark_node)
      b->value = val;
    else
      supplement_binding (b, val);
Index: init.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/init.c,v
retrieving revision 1.345
diff -c -p -r1.345 init.c
*** gcc/cp/init.c      7 Oct 2003 07:07:03 -0000       1.345
--- gcc/cp/init.c      19 Nov 2003 23:28:51 -0000
*************** build_new_1 (tree exp)
*** 2005,2015 ****
        tree class_size = size_in_bytes (true_type);
        static const char alloc_name[] = "_Jv_AllocObject";
        use_java_new = 1;
!       alloc_decl = IDENTIFIER_GLOBAL_VALUE (get_identifier (alloc_name));
!       if (alloc_decl == NULL_TREE)
  	fatal_error ("call to Java constructor with `%s' undefined",
  		     alloc_name);
! 
        class_addr = build1 (ADDR_EXPR, jclass_node, class_decl);
        alloc_call = (build_function_call
                    (alloc_decl,
--- 2005,2020 ----
        tree class_size = size_in_bytes (true_type);
        static const char alloc_name[] = "_Jv_AllocObject";
        use_java_new = 1;
!       if (!get_global_value_if_present (get_identifier (alloc_name),
!                                       &alloc_decl))
        fatal_error ("call to Java constructor with `%s' undefined",
                     alloc_name);
!       if (is_overloaded_fn (alloc_decl))
!       {
!       if (really_overloaded_fn (alloc_decl))
!         fatal_error ("`%s' should never be overloaded", alloc_name);
!       alloc_decl = OVL_FUNCTION (alloc_decl);
!       }
        class_addr = build1 (ADDR_EXPR, jclass_node, class_decl);
        alloc_call = (build_function_call
  		     (alloc_decl,
Index: except.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/except.c,v
retrieving revision 1.160
diff -c -p -r1.160 except.c
*** gcc/cp/except.c    29 Sep 2003 21:19:10 -0000      1.160
--- gcc/cp/except.c    19 Nov 2003 23:28:55 -0000
*************** build_throw (tree exp)
*** 637,642 ****
--- 637,643 ----
 
    if (exp && decl_is_java_type (TREE_TYPE (exp), 1))
      {
+       static const char throw_name[] = "_Jv_Throw";
        tree fn = get_identifier ("_Jv_Throw");
        if (!get_global_value_if_present (fn, &fn))
  	{
*************** build_throw (tree exp)
*** 645,650 ****
--- 646,657 ----
	  tmp = build_function_type (ptr_type_node, tmp);
  	  fn = push_throw_library_fn (fn, tmp);
  	}
+       else if (is_overloaded_fn (fn))
+ 	{
+ 	  if (really_overloaded_fn (fn))
+ 	    fatal_error ("`%s' should never be overloaded", throw_name);
+ 	  fn = OVL_FUNCTION (fn);
+       }
  
        exp = build_function_call (fn, tree_cons (NULL_TREE, exp, NULL_TREE));
      }


// { dg-do compile }
// Origin: C++ Standard Draft (7.3.3/12)
// PR c++/2294: using declarations should not conflict, but only cause
//  an ambiguous overload set to be created.

namespace B {
  void f(int);     // { dg-error "note" }
  void f(double);  // { dg-error "note" }
}

namespace C {
  void f(int);     // { dg-error "note" }
  void f(double);  // { dg-error "note" }
  void f(char);    // { dg-error "note" }
}

void h()
{
  using B::f;
  using C::f;
  f('h');
  f(1);         // { dg-error "ambiguous" }
  void f(int);  // { dg-error "previous using declaration" }
}

void m()
{
  void f(int);
  using B::f;   // { dg-error "already declared" }
}



// { dg-do compile }
// Origin: Giovanni Bajo <giovannibajo at libero dot it>
// Make sure that Java special functions can be called correctly.

extern "Java"
{
  typedef __java_int jint;
  namespace java
  {
  namespace lang
    {
      class Class;
      class Object;
      class Throwable {};
      class Foo;
    }
  }
}

typedef struct java::lang::Object* jobject;
typedef struct java::lang::Throwable* jthrowable;
typedef class java::lang::Class* jclass;

extern "C" jobject _Jv_AllocObject (jclass, jint) __attribute__((__malloc__));
extern "C" void _Jv_Throw (jthrowable) __attribute__ ((__noreturn__));

class java::lang::Foo : public java::lang::Throwable
{
public:
  static ::java::lang::Class class$;
};

void Bar(void)
{
  throw (new java::lang::Foo);
}




