Browse Source

* don't create an instance of abstract classes inside their virtual
constructors (simply do nothing), because creating an abstract class
is not possible in the JVM (and while the JVM only triggers an
exception when you actually execute code that tries to create an
abstract class, the Android platform checks this using the bytecode
verifier at class verification time and therefore stumbled over the
old code)

git-svn-id: branches/jvmbackend@20547 -

Jonas Maebe 13 years ago
parent
commit
94bffa65e9
1 changed files with 16 additions and 4 deletions
  1. 16 4
      compiler/jvm/pjvm.pas

+ 16 - 4
compiler/jvm/pjvm.pas

@@ -659,7 +659,7 @@ implementation
         symtablestack.push(pd.owner);
         { get a copy of the constructor }
         wrapperpd:=tprocdef(pd.getcopyas(procdef,pc_bareproc));
-        { this one is is a class method rather than a constructor }
+        { this one is a class method rather than a constructor }
         include(wrapperpd.procoptions,po_classmethod);
         wrapperpd.proctypeoption:=potype_function;
         wrapperpd.returndef:=tobjectdef(pd.owner.defowner);
@@ -677,9 +677,21 @@ implementation
           copy the vmt parameter from the constructor, that's different) }
         insert_self_and_vmt_para(wrapperpd);
         wrapperpd.calcparas;
-        { implementation: call through to the constructor }
-        wrapperpd.synthetickind:=tsk_callthrough;
-        wrapperpd.skpara:=pd;
+        { implementation: call through to the constructor, except in case of
+          an abstract class: then do nothing, because constructing an abstract
+          class is not possible; we still need the method definition because
+          it's used elsewhere by the compiler (it can be "overridden" by
+          child classes) }
+        if (pd.struct.typ=objectdef) and
+           (tobjectdef(pd.struct).abstractcnt=0) then
+          begin
+            wrapperpd.synthetickind:=tsk_callthrough;
+            wrapperpd.skpara:=pd;
+          end
+        else
+          begin
+            wrapperpd.synthetickind:=tsk_empty;
+          end;
         symtablestack.pop(pd.owner);
         { and now wrap this generated virtual static method itself as well }
         jvm_wrap_virtual_class_method(wrapperpd);