View Issue Details

IDProjectCategoryView StatusLast Update
0027049FPCCompilerpublic2020-04-23 05:46
ReporterColin Haywood Assigned ToFlorian  
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionno change required 
Platformx86OSWindows 
Product Version2.6.4 
Summary0027049: "inline" function specifier causes reference counting errors
DescriptionSee attached program. The use of "inline" in a function that has an otherwise-useless temporary variable seems to cause the compiler to mess up the code for handling the temporary variable.

When run, the output of the program should be

Reference count of a is 2
Reference count of b is 2

since both these variables have two references at the point we do the writeln(): one inside m.FMap, and the other of course the variable (a or b) itself.

But instead it prints

Reference count of a is 3
Reference count of b is 2

The only difference between what happens to "a" and what happens to "b" is the use of inline: a gets passed out to InlineGet, but b gets passed out to Get. Looking at the assembler, the compiler generates a "finalize" call for both but puts the one for "a" BEFORE the call to I_ActualGet rather than after (where it should be).

(Note that although this program is rather useless, this is adapted from a real-world example in which there are two variants of Get(): one which takes an out parameter, and one which does not. The Get without the out parameter calls the Get with the out parameter, passing a useless temporary variable.)
Steps To ReproduceCompile attached program for 32-bit OS.
TagsNo tags attached.
Fixed in Revision
FPCOldBugId
FPCTarget
Attached Files

Activities

Colin Haywood

2014-11-16 22:35

reporter  

Colin Haywood

2014-11-16 22:37

reporter   ~0079179

Hmm, where did the severity option go? It should be "major"

Florian

2014-11-25 20:26

administrator   ~0079387

When inlining, the variables of the inlined subroutine are hold in the stack frame of the caller and finalized when the caller is left. This happens with TMap.InlineGet.dummy, so a gets another reference which is release at "end."

Just compile with -gh and you will see that there is no memory leak.

Issue History

Date Modified Username Field Change
2014-11-16 22:35 Colin Haywood New Issue
2014-11-16 22:35 Colin Haywood File Added: inline_reference_count_bug.lpr
2014-11-16 22:37 Colin Haywood Note Added: 0079179
2014-11-25 20:26 Florian Note Added: 0079387
2014-11-25 20:26 Florian Status new => resolved
2014-11-25 20:26 Florian Resolution open => no change required
2014-11-25 20:26 Florian Assigned To => Florian