Hi!

_Jv_AllocObject returns a pointer, and as the testcase below shows,
we easily ICE if a wrong prototype is provided for it instead.
There is already other diagnostics (e.g. when it is missing, or when
it is overloaded function), so this ensures at least the return type
is sane.

Wonder about all the other spots where the C++ FE relies on user prototypes
for __cxa* etc. functions, perhaps some sanity checking will be needed too
to avoid ICEs on invalid stuff.

Bootstrapped/regtested on x86_64-linux and i686-linux (including java on
both as usually), ok for trunk?

2016-03-17  Jakub Jelinek  <ja...@redhat.com>

        PR c++/70267
        * init.c (build_new_1): Complain and return error_mark_node
        if alloc_fn is not _Jv_AllocObject function returning pointer.

        * g++.dg/ext/java-3.C: New test.

--- gcc/cp/init.c.jj    2016-03-05 07:46:50.000000000 +0100
+++ gcc/cp/init.c       2016-03-17 17:18:21.326917746 +0100
@@ -2872,6 +2872,14 @@ build_new_1 (vec<tree, va_gc> **placemen
          return error_mark_node;
        }
       alloc_fn = OVL_CURRENT (alloc_fn);
+      if (TREE_CODE (alloc_fn) != FUNCTION_DECL
+         || TREE_CODE (TREE_TYPE (alloc_fn)) != FUNCTION_TYPE
+         || !POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (alloc_fn))))
+       {
+         if (complain & tf_error)
+           error ("%qD is not a function returning a pointer", alloc_fn);
+         return error_mark_node;
+       }
       class_addr = build1 (ADDR_EXPR, jclass_node, class_decl);
       alloc_call = cp_build_function_call_nary (alloc_fn, complain,
                                                class_addr, NULL_TREE);
--- gcc/testsuite/g++.dg/ext/java-3.C.jj        2016-03-17 18:25:26.417381245 
+0100
+++ gcc/testsuite/g++.dg/ext/java-3.C   2016-03-17 18:24:48.000000000 +0100
@@ -0,0 +1,39 @@
+// PR c++/70267
+// { dg-do compile }
+// { dg-options "-O2" }
+
+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;
+
+using java::lang::Foo;
+
+class Foo: public java::lang::Throwable
+{
+  public:static::java::lang::Class class$;
+};
+
+extern "C" Foo _Jv_AllocObject (jclass);
+extern "C" void _Jv_Throw (jthrowable) __attribute__ ((__noreturn__));
+
+void 
+Bar4 (void)
+{
+  Foo * f = new java::lang::Foo;       // { dg-error "is not a function 
returning a pointer" }
+  throw (f);
+}

        Jakub

Reply via email to