re PR c++/30293 (ICE with extern "Java" in store_init_value)
authorJakub Jelinek <jakub@redhat.com>
Fri, 23 Nov 2007 20:49:02 +0000 (21:49 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 23 Nov 2007 20:49:02 +0000 (21:49 +0100)
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.

From-SVN: r130382

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/init.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/java-2.C [new file with mode: 0644]

index 0aff9b197cc1db19361d59ad98f3c0ed98377458..90382709914f037bb7e72f735932d13e1dbf5004 100644 (file)
@@ -1,3 +1,16 @@
+2007-11-23  Jakub Jelinek  <jakub@redhat.com>
+
+       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.
+
 2007-11-23  Mark Mitchell  <mark@codesourcery.com>
            Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
        
index 758d95b05bbf1b9caca5fe19e6913a732bfaceb3..f020c270f89d34f34eb0ba6e7a1d299084745b6e 100644 (file)
@@ -5468,6 +5468,20 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
             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 %<new%>", decl);
+             init = NULL_TREE;
+           }
          if (init)
            {
              DECL_NONTRIVIALLY_INITIALIZED_P (decl) = 1;
@@ -5538,6 +5552,9 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
       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
@@ -9328,6 +9345,16 @@ grokparms (cp_parameter_declarator *first_parm, tree *parms)
          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
@@ -10914,11 +10941,15 @@ check_function_type (tree decl, tree current_function_parms)
 
   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)
index c5c17b1a9e15a8928a9651b490be19fcb630a2b2..202f3b68ebbdf14e65c7783c5af96072debe69b2 100644 (file)
@@ -1786,6 +1786,11 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
                    (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;
index 5e5578d8867df06f99701d1a4724d031dc167f4c..6bd778a3bacccc09713e3befb616262e418b43a0 100644 (file)
@@ -1,3 +1,9 @@
+2007-11-23  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/30293
+       PR c++/30294
+       * g++.dg/ext/java-2.C: New test.
+
 2007-11-23  Mark Mitchell  <mark@codesourcery.com>
            Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
        
diff --git a/gcc/testsuite/g++.dg/ext/java-2.C b/gcc/testsuite/g++.dg/ext/java-2.C
new file mode 100644 (file)
index 0000000..4015f00
--- /dev/null
@@ -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;
+}