From b0639405ac44cbe88673e17fab7b6baf5505ce9c Mon Sep 17 00:00:00 2001 From: Jonas Maebe Date: Thu, 16 Oct 2014 17:49:02 +0000 Subject: [PATCH] * compare the actual target nodes when checking whether the result of an inline function is getting assigned to one of its parameters, so that typecasts etc. are dealt with correctly (mantis #26536) git-svn-id: trunk@28834 - --- .gitattributes | 1 + compiler/ncal.pas | 2 +- tests/webtbs/tw26536.pp | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 tests/webtbs/tw26536.pp diff --git a/.gitattributes b/.gitattributes index def95a29de..1c7e0777c3 100644 --- a/.gitattributes +++ b/.gitattributes @@ -14087,6 +14087,7 @@ tests/webtbs/tw2647.pp svneol=native#text/plain tests/webtbs/tw26482.pp svneol=native#text/pascal tests/webtbs/tw2649.pp svneol=native#text/plain tests/webtbs/tw2651.pp svneol=native#text/plain +tests/webtbs/tw26536.pp svneol=native#text/plain tests/webtbs/tw2656.pp svneol=native#text/plain tests/webtbs/tw2659.pp svneol=native#text/plain tests/webtbs/tw26599.pp svneol=native#text/pascal diff --git a/compiler/ncal.pas b/compiler/ncal.pas index 90250933fc..1c1fa24943 100644 --- a/compiler/ncal.pas +++ b/compiler/ncal.pas @@ -3977,7 +3977,7 @@ implementation (assigned(aktassignmentnode) and (aktassignmentnode.right=self) and (nf_assign_done_in_right in aktassignmentnode.flags) and - aktassignmentnode.left.isequal(para.left)))) or + actualtargetnode(@aktassignmentnode.left)^.isequal(actualtargetnode(@para.left)^)))) or { the compiler expects that it can take the address of parameters passed by reference in the case of const so we can't replace the node simply by a constant node When playing with this code, ensure that diff --git a/tests/webtbs/tw26536.pp b/tests/webtbs/tw26536.pp new file mode 100644 index 0000000000..293cb6d6ef --- /dev/null +++ b/tests/webtbs/tw26536.pp @@ -0,0 +1,40 @@ +{$MODE OBJFPC} +program test; + +type + TBaseClass = class + function PrintSelf(): TBaseClass; inline; // has to be inline for the bug to manifest + end; + + TSubClass = class(TBaseClass) + end; + +function TBaseClass.PrintSelf(): TBaseClass; inline; +begin + Writeln(PtrUInt(Self)); + Result := nil; + Writeln(PtrUInt(Self)); // prints 0! + if not assigned(self) then + halt(1); +end; + +procedure NoOp(var Dummy: TBaseClass); +begin +end; + + +var + Instance, Variable: TBaseClass; + res: longint; +begin + Instance := TSubClass.Create(); + Variable := nil; + + NoOp(Variable); // this call is important for the bug to manifest + Variable := Instance; + // object being invoked has to be cast to a different type for the bug to manifest + // return value has to be assigned to the variable being used as "self" + Variable := TSubClass(Variable).PrintSelf(); + + Instance.Free(); +end.