From 66ec137f098ece282c762ee3a74eed9ea161e252 Mon Sep 17 00:00:00 2001 From: sergei Date: Mon, 2 Jan 2012 09:43:43 +0000 Subject: [PATCH] * Partially reverted r19668. It turns out that the implicit finally block in constructors, besides its intended purpose, provides correct position of the exit label (more precisely, it relocates exit label to the start of 'finally' part without subsequent restoring it to original value). Optimizing it away causes exit statements in constructors to jump over AfterConstruction call. + Test to prevent it from happening again. git-svn-id: trunk@19948 - --- .gitattributes | 1 + compiler/psub.pas | 9 ++------- tests/test/cg/tctr1.pp | 28 ++++++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 7 deletions(-) create mode 100644 tests/test/cg/tctr1.pp diff --git a/.gitattributes b/.gitattributes index f98b098423..2191dbb969 100644 --- a/.gitattributes +++ b/.gitattributes @@ -9541,6 +9541,7 @@ tests/test/cg/tcnvstr2.pp svneol=native#text/plain tests/test/cg/tcnvstr3.pp svneol=native#text/plain tests/test/cg/tcppcl1.pp svneol=native#text/plain tests/test/cg/tcppcl2.pp svneol=native#text/plain +tests/test/cg/tctr1.pp svneol=native#text/plain tests/test/cg/tderef.pp svneol=native#text/plain tests/test/cg/tdivz1.pp svneol=native#text/plain tests/test/cg/tdivz2.pp svneol=native#text/plain diff --git a/compiler/psub.pas b/compiler/psub.pas index 7e88872a91..ff24e105d9 100644 --- a/compiler/psub.pas +++ b/compiler/psub.pas @@ -284,6 +284,7 @@ implementation begin if is_class(current_structdef) then begin + include(current_procinfo.flags,pi_needs_implicit_finally); srsym:=search_struct_member(current_structdef,'NEWINSTANCE'); if assigned(srsym) and (srsym.typ=procsym) then @@ -698,13 +699,7 @@ implementation end else begin - { Constructors need the destroy-on-exception code even if they don't - use managed variables/temps. } - if (cs_implicit_exceptions in current_settings.moduleswitches) and - (is_class(procdef.struct) and (procdef.proctypeoption=potype_constructor)) then - maybe_add_constructor_wrapper(code,true) - else - maybe_add_constructor_wrapper(code,false); + maybe_add_constructor_wrapper(code,false); addstatement(newstatement,loadpara_asmnode); addstatement(newstatement,stackcheck_asmnode); addstatement(newstatement,entry_asmnode); diff --git a/tests/test/cg/tctr1.pp b/tests/test/cg/tctr1.pp new file mode 100644 index 0000000000..e0322161a2 --- /dev/null +++ b/tests/test/cg/tctr1.pp @@ -0,0 +1,28 @@ +{$mode objfpc}{$h+} + +type + tobj=class(TObject) + ffield:boolean; + constructor Create; + procedure AfterConstruction;override; + end; + +{ Exit statement in constructor must not jump over AfterConstruction! } +constructor tobj.Create; +begin + exit; +end; + +procedure tobj.AfterConstruction; +begin + ffield:=true; +end; + + +var + o: tobj; +begin + o:=tobj.create; + if not o.ffield then + Halt(1); +end.