[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