From 17ef986b17f9c207f358a1a2ea2301ddc248e96b Mon Sep 17 00:00:00 2001 From: paul Date: Sun, 18 Aug 2013 17:29:23 +0000 Subject: [PATCH] compiler: don't treat methods without self node (static class methods, class contructors, destructors, operators) as method pointers, fix comparison of procdef and procvardef to allow assignment of a static class method to a regular procedural variable (issue #24486) git-svn-id: trunk@25284 - --- .gitattributes | 1 + compiler/defcmp.pas | 10 ++++++---- compiler/symdef.pas | 4 ++-- tests/webtbs/tw24486.pp | 25 +++++++++++++++++++++++++ 4 files changed, 34 insertions(+), 6 deletions(-) create mode 100644 tests/webtbs/tw24486.pp diff --git a/.gitattributes b/.gitattributes index 49c693f30c..f4834773fa 100644 --- a/.gitattributes +++ b/.gitattributes @@ -13466,6 +13466,7 @@ tests/webtbs/tw2432.pp svneol=native#text/plain tests/webtbs/tw2435.pp svneol=native#text/plain tests/webtbs/tw2438.pp svneol=native#text/plain tests/webtbs/tw2442.pp svneol=native#text/plain +tests/webtbs/tw24486.pp svneol=native#text/pascal tests/webtbs/tw2452.pp svneol=native#text/plain tests/webtbs/tw24536.pp svneol=native#text/plain tests/webtbs/tw2454.pp svneol=native#text/plain diff --git a/compiler/defcmp.pas b/compiler/defcmp.pas index 6f618cebce..4c4e7b7c8b 100644 --- a/compiler/defcmp.pas +++ b/compiler/defcmp.pas @@ -2113,8 +2113,8 @@ implementation function proc_to_procvar_equal(def1:tabstractprocdef;def2:tprocvardef;checkincompatibleuniv: boolean):tequaltype; var - eq : tequaltype; - po_comp : tprocoptions; + eq: tequaltype; + po_comp: tprocoptions; pa_comp: tcompare_paras_options; begin proc_to_procvar_equal:=te_incompatible; @@ -2148,8 +2148,10 @@ implementation if checkincompatibleuniv then include(pa_comp,cpo_warn_incompatible_univ); { check return value and options, methodpointer is already checked } - po_comp:=[po_staticmethod,po_interrupt, - po_iocheck,po_varargs]; + po_comp:=[po_interrupt,po_iocheck,po_varargs]; + { check static only if we compare method pointers } + if def1.is_methodpointer then + include(po_comp,po_staticmethod); if (m_delphi in current_settings.modeswitches) then exclude(po_comp,po_varargs); if (def1.proccalloption=def2.proccalloption) and diff --git a/compiler/symdef.pas b/compiler/symdef.pas index bfbf8f5fa2..8c95ec6cba 100644 --- a/compiler/symdef.pas +++ b/compiler/symdef.pas @@ -4769,14 +4769,14 @@ implementation begin { don't check assigned(_class), that's also the case for nested procedures inside methods } - result:=owner.symtabletype=ObjectSymtable; + result:=(owner.symtabletype=ObjectSymtable)and not no_self_node; end; function tprocdef.is_addressonly:boolean; begin result:=assigned(owner) and - (owner.symtabletype<>ObjectSymtable) and + not is_methodpointer and (not(m_nested_procvars in current_settings.modeswitches) or not is_nested_pd(self)); end; diff --git a/tests/webtbs/tw24486.pp b/tests/webtbs/tw24486.pp new file mode 100644 index 0000000000..ce1c6bd1fb --- /dev/null +++ b/tests/webtbs/tw24486.pp @@ -0,0 +1,25 @@ +{%NORUN} +program tw24486; + +{$mode delphi} + +type + tproc1 = procedure(a: integer); + +var + proc1: tproc1; + +type + tclass1 = class + class procedure p1(a: integer); static; + end; + +{ tclass1 } + +class procedure tclass1.p1(a: integer); +begin +end; + +begin + proc1 := tclass1.p1; +end.