2007-11-23 Jakub Jelinek PR c++/30293 PR c++/30294 * decl.c (cp_finish_decl): Disallow variable or field definitions if extern "Java" aggregates. (grokparms): Disallow parameters with extern "Java" aggregates. (check_function_type): Disallow function return values with extern "Java" aggregates. * init.c (build_new_1): Disallow placement new with extern "Java" aggregates. * g++.dg/ext/java-2.C: New test. --- gcc/cp/decl.c.jj 2007-11-19 17:46:41.000000000 +0100 +++ gcc/cp/decl.c 2007-11-22 13:34:52.000000000 +0100 @@ -5349,6 +5349,20 @@ cp_finish_decl (tree decl, tree init, bo is *not* defined. */ && (!DECL_EXTERNAL (decl) || init)) { + if (TYPE_FOR_JAVA (type) && IS_AGGR_TYPE (type)) + { + tree jclass + = IDENTIFIER_GLOBAL_VALUE (get_identifier ("jclass")); + /* Allow libjava/prims.cc define primitive classes. */ + if (init != NULL_TREE + || jclass == NULL_TREE + || TREE_CODE (jclass) != TYPE_DECL + || !POINTER_TYPE_P (TREE_TYPE (jclass)) + || !same_type_ignoring_top_level_qualifiers_p + (type, TREE_TYPE (TREE_TYPE (jclass)))) + error ("Java object %qD not allocated with %", decl); + init = NULL_TREE; + } if (init) { DECL_NONTRIVIALLY_INITIALIZED_P (decl) = 1; @@ -5419,6 +5433,9 @@ cp_finish_decl (tree decl, tree init, bo else if (TREE_CODE (type) == ARRAY_TYPE) layout_type (type); } + else if (TREE_CODE (decl) == FIELD_DECL + && TYPE_FOR_JAVA (type) && IS_AGGR_TYPE (type)) + error ("non-static data member %qD has Java class type", decl); /* Add this declaration to the statement-tree. This needs to happen after the call to check_initializer so that the DECL_EXPR for a @@ -8993,6 +9010,16 @@ grokparms (cp_parameter_declarator *firs TREE_TYPE (decl) = error_mark_node; } + if (type != error_mark_node + && TYPE_FOR_JAVA (type) + && IS_AGGR_TYPE (type)) + { + error ("parameter %qD has Java class type", decl); + type = error_mark_node; + TREE_TYPE (decl) = error_mark_node; + init = NULL_TREE; + } + if (type != error_mark_node) { /* Top-level qualifiers on the parameters are @@ -10465,11 +10492,15 @@ check_function_type (tree decl, tree cur if (dependent_type_p (return_type)) return; - if (!COMPLETE_OR_VOID_TYPE_P (return_type)) + if (!COMPLETE_OR_VOID_TYPE_P (return_type) + || (TYPE_FOR_JAVA (return_type) && IS_AGGR_TYPE (return_type))) { tree args = TYPE_ARG_TYPES (fntype); - - error ("return type %q#T is incomplete", return_type); + + if (!COMPLETE_OR_VOID_TYPE_P (return_type)) + error ("return type %q#T is incomplete", return_type); + else + error ("return type has Java class type %q#T", return_type); /* Make it return void instead. */ if (TREE_CODE (fntype) == METHOD_TYPE) --- gcc/cp/init.c.jj 2007-09-20 21:26:48.000000000 +0200 +++ gcc/cp/init.c 2007-11-22 10:49:47.000000000 +0100 @@ -1786,6 +1786,11 @@ build_new_1 (tree placement, tree type, (alloc_fn, build_tree_list (NULL_TREE, class_addr))); } + else if (TYPE_FOR_JAVA (elt_type)) + { + error ("Java class %q#T object allocated using placement new", elt_type); + return error_mark_node; + } else { tree fnname; --- gcc/testsuite/g++.dg/ext/java-2.C.jj 2007-11-22 10:55:10.000000000 +0100 +++ gcc/testsuite/g++.dg/ext/java-2.C 2007-11-22 10:54:59.000000000 +0100 @@ -0,0 +1,79 @@ +// PR c++/30293 +// PR c++/30294 +// { dg-do compile } +// { dg-options "" } + +extern "Java" { +typedef __java_byte jbyte; +namespace java { +namespace lang { + class Object {}; + class Class {}; +} +} +typedef struct java::lang::Object* jobject; +typedef java::lang::Class *jclass; +} +extern "C" jobject _Jv_AllocObject (jclass); + +extern "Java" { + struct A { static java::lang::Class class$; }; +} + +struct B { + A a; // { dg-error "has Java class type" } +}; + +void* operator new (__SIZE_TYPE__, void*) throw(); +char buf[1024]; + +A a; // { dg-error "not allocated with" } +A b = A (); // { dg-error "not allocated with" } +A *c = new ((void *) buf) A (); // { dg-error "using placement new" } +A *d = new A (); +jbyte e = 6; + +const A fn1 () // { dg-error "return type has Java class type" } +{ + A a; // { dg-error "not allocated with" } + return a; +} + +A fn2 () // { dg-error "return type has Java class type" } +{ + A a; // { dg-error "not allocated with" } + return a; +} + +A *fn3 () +{ + return new A (); +} + +A &fn4 () +{ + return *c; +} + +jbyte fn5 () +{ + return 7; +} + +void fn6 (A x) // { dg-error "has Java class type" } +{ +} + +void fn7 (const A x) // { dg-error "has Java class type" } +{ +} + +void fn8 (A *x) +{ + (void) x; +} + +void fn9 (jbyte x) +{ + (void) x; +}