[fpc-devel] Explicitly named return values and implicit aliases Result

Blaise at blaise.ru Blaise at blaise.ru
Tue Dec 15 20:00:20 CET 2020


Consider this test case:
-------8<-------
{$mode ObjFPC}

// EXPECTED: 'Error: Identifier not found "result"'
// ACTUAL BUG #1: gets compiled
operator - (const L, R: Char) returned: Char;
begin
	result := 'Z'
end;

// EXPECTED: gets compiled
// ACTUAL BUG #2: 'Error: Duplicate identifier "result"'
operator / (const L, R: Char) result: Char;
begin
	result := 'Z'
end;

begin
end.
-------8<-------

The patch http://hg.blaise.ru/public/fpc/rev/ce20f68924a0 (attached) alters insert_funcret_local:
1) Extracts duplicate code into alias_funcret;
2) Avoids the second call to the pd.resultname getter;
3) Avoids copying strings pd.resultname^/pd.procsym.name to the local buffer hs;
4) Fixes the first bug: the alias Result should not be implicitly declared when another identifier is declared as the return value;
5) Fixes the second bug: even with {$modeswitch result+}, it should be possible to explicitly name a return value Result.
NB: The patch preserves the current suspicious behaviour of not slapping vo_is_result onto explicit names. More on that later.

If needed, I can file a bug report to document the user-visible change in behaviour.

-- 
βþ
-------------- next part --------------
# HG changeset patch
# User Blaise.ru
# Date 1608056493 -10800
! insert_funcret_local: do not create the alias Result if an explicit name is declared

diff -r 6a8b4a8fc96e -r ce20f68924a0 pparautl.pas
--- a/pparautl.pas	Tue Dec 15 20:45:13 2020 +0300
+++ b/pparautl.pas	Tue Dec 15 21:21:33 2020 +0300
@@ -295,12 +295,22 @@
 
 
     procedure insert_funcret_local(pd:tprocdef);
+
+      function alias_funcret(const pd: tprocdef; const name: TSymStr): tabsolutevarsym;
+        var
+          sl: tpropaccesslist;
+        begin
+          sl:=tpropaccesslist.create;
+          sl.addsym(sl_load,pd.funcretsym);
+          result:=cabsolutevarsym.create_ref(name,pd.returndef,sl);
+          include(result.varoptions,vo_is_funcret);
+          tlocalsymtable(pd.localst).insert(result);
+        end;
+
       var
         storepos : tfileposinfo;
         vs       : tlocalvarsym;
-        aliasvs  : tabsolutevarsym;
-        sl       : tpropaccesslist;
-        hs       : string;
+        pname    : PShortString;
       begin
         storepos:=current_tokenpos;
         current_tokenpos:=pd.fileinfo;
@@ -323,33 +333,14 @@
               pd.funcretsym:=vs;
             end;
 
-           { insert the name of the procedure as alias for the function result,
-             we can't use realname because that will not work for compilerprocs
-             as the name is lowercase and unreachable from the code }
-           if (pd.proctypeoption<>potype_operator) or assigned(pd.resultname) then
-             begin
-               if assigned(pd.resultname) then
-                 hs:=pd.resultname^
-               else
-                 hs:=pd.procsym.name;
-               sl:=tpropaccesslist.create;
-               sl.addsym(sl_load,pd.funcretsym);
-               aliasvs:=cabsolutevarsym.create_ref(hs,pd.returndef,sl);
-               include(aliasvs.varoptions,vo_is_funcret);
-               tlocalsymtable(pd.localst).insert(aliasvs);
-             end;
-
-           { insert result also if support is on }
-           if (m_result in current_settings.modeswitches) then
-            begin
-              sl:=tpropaccesslist.create;
-              sl.addsym(sl_load,pd.funcretsym);
-              aliasvs:=cabsolutevarsym.create_ref('RESULT',pd.returndef,sl);
-              include(aliasvs.varoptions,vo_is_funcret);
-              include(aliasvs.varoptions,vo_is_result);
-              tlocalsymtable(pd.localst).insert(aliasvs);
-            end;
-
+           // Create funcret aliases
+           if pd.proctypeoption<>potype_operator then
+             alias_funcret(pd,pd.procsym.name); // .RealName does not work for compilerprocs
+           pname:=pd.resultname;
+           if assigned(pname) then
+             alias_funcret(pd,pname^) // explicitly named
+           else if m_result in current_settings.modeswitches then
+             include(alias_funcret(pd,'RESULT').varoptions,vo_is_result) // implicit Result
          end;
 
         if pd.generate_safecall_wrapper then


More information about the fpc-devel mailing list