Bläddra i källkod

* 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 år sedan
förälder
incheckning
94bffa65e9
1 ändrade filer med 16 tillägg och 4 borttagningar
  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);