Bug #10027
Incorrect handling of an unused shared variable in the conversion process.
100%
History
#2 Updated by Paula Păstrăguș about 1 year ago
Here's the testcase:
def shared var var1 as date no-undo. def shared var var2 like var1 no-undo.
The var1 variable should be converted as SharedVariableManager.lookupVariableUnreferenced, not as SharedVariableManager.lookupVariable.
#4 Updated by Paula Păstrăguș about 1 year ago
- File ast.png added
Constantin, I looked into the conversion process, and the AST looks like this:

In the VAR_DATE node, we can see that a refid annotation is being added by post_parse_fixups.xml. Based on my analysis, this annotation likely should not be added in this context.
Here’s the relevant rule definition:
<rule>
!(type == prog.wid_dialog or type == prog.wid_frame or type == prog.wid_window) and
(evalLib("variables") or evalLib("widget_references")) and
type != prog.sys_handle and
isNote("tempidx") and
(!isNote('tempidx-file') or
ancestor(prog.method_def, -1) or
ancestor(prog.constructor, -1) or
evalLib("widget_references")) and
dictionaryContains("var_defs", #(java.lang.String) execLib("compute_key"))
The problem is that later in variable_definitions_unrefd.rules, there's a rule that checks for the presence of the refid annotation. If it's found, the node’s ID is removed from the unrefd hash set, which results in the generation of a SharedVariable.lookupVariable(...) instead of the expected lookupVariableUnreferenced(...).
<!-- any reference to a variable in the set means that it should be
removed since it must be a "live" var -->
<!-- aside from a like clause for a shared var that is not defined yet -->
<rule>isNote("refid")
<action>unrefd.remove(getNoteLong("refid"))</action>
</rule>
#5 Updated by Paula Păstrăguș about 1 year ago
Regarding the rule I mentioned earlier, I would suggest adding a new condition like the following at a first glance:
!(this.parent.parent.type == prog.DEFINE_VARIABLE and this.parent.parent.descendant(1, prog.KW_SHARED) and this.parent.parent.descendant(1, prog.KW_LIKE))
#6 Updated by Constantin Asofiei about 1 year ago
We need to exclude the 'meta' usage when checking the 'refid' - so in variable_definitions_unrefd.rules, do not use a refid if the parent is a KW_LIKE.
The same can be said about def temp-table tt1 field f1 like var1. - this is a 'meta' reference of the variable. Can you think of other syntax where a var can be used as a 'meta' reference?
#7 Updated by Constantin Asofiei about 1 year ago
Paula Păstrăguș wrote:
Regarding the rule I mentioned earlier, I would suggest adding a new condition like the following at a first glance:
[...]
KW_LIKE is processed later on in the conversion pipe-line - so the refid annotation there is required, to resolve the reference from which the definition is read.
#8 Updated by Paula Păstrăguș about 1 year ago
Alright, I tried my quick workaround and the conversion completed successfully... However, I see your point. So just to confirm, you're suggesting that the better solution would be to update variable_definitions_unrefd.rules so that it doesn't remove the ID from the unrefd set?
#9 Updated by Constantin Asofiei about 1 year ago
Paula Păstrăguș wrote:
So just to confirm, you're suggesting that the better solution would be to update
variable_definitions_unrefd.rulesso that it doesn't remove the ID from theunrefdset?
Yes, for KW_LIKE parent and anything else you can find. 'unreferenced' in 4GL I think means 'is not read/written', not that is not used as a 'like'.
#10 Updated by Paula Păstrăguș about 1 year ago
Okay, I’ll also look for other test cases that involve those kind of variables.
#11 Updated by Holly Brown about 1 year ago
Please can you add CA-24875 to the case_num?
thank you
#12 Updated by Radu Apetrii about 1 year ago
- case_num set to CA-24875
#13 Updated by Paula Păstrăguș about 1 year ago
I looked for other scenarios, but it seems that LIKE remains the only problematic case in this context.
Here's a patch:
=== modified file 'rules/annotations/variable_definitions_unrefd.rules' --- old/rules/annotations/variable_definitions_unrefd.rules 2023-05-10 07:41:38 +0000 +++ new/rules/annotations/variable_definitions_unrefd.rules 2025-05-21 12:19:13 +0000 @@ -135,7 +135,7 @@ <!-- any reference to a variable in the set means that it should be removed since it must be a "live" var --> - <rule>isNote("refid") + <rule>isNote("refid") and parent.type != prog.KW_LIKE <action>unrefd.remove(getNoteLong("refid"))</action> </rule>
I performed an incremental conversion of a customer application, and everything went smoothly. Of course, to properly validate the fix, a full conversion should eventually be done. However, until then, Constantin, does the fix meet your expectations?
#14 Updated by Constantin Asofiei about 1 year ago
Paula Păstrăguș wrote:
However, until then, Constantin, does the fix meet your expectations?
Yes, thank you.
#15 Updated by Paula Păstrăguș about 1 year ago
- Status changed from New to Internal Test
- Assignee set to Paula Păstrăguș
- % Done changed from 0 to 100
Conversion testing passed: unused variables were successfully dropped, and unused shared variables were emitted using lookupVariableUnreferenced.
Runtime testing also passed for both ChUI and a large GUI application.
#16 Updated by Paula Păstrăguș about 1 year ago
Committed to 10027a/15933.
Constantin, please double-check the revision.
If everything looks good, Radu, we’d like to add this to the merging queue.
#17 Updated by Constantin Asofiei about 1 year ago
Paula Păstrăguș wrote:
Committed to 10027a/15933.
Constantin, please double-check the revision.
The branch is OK.
If everything looks good, Radu, we’d like to add this to the merging queue.
Radu: lets plan to merge this on Monday.
Do we need this in #8966 branch?
#18 Updated by Radu Apetrii about 1 year ago
Constantin Asofiei wrote:
Do we need this in #8966 branch?
We'll see in #9945 if these changes should be ported to 9866a.
#19 Updated by Constantin Asofiei about 1 year ago
- Status changed from Internal Test to Merge Pending
Please merge 10027a after 9583b.
#20 Updated by Paula Păstrăguș about 1 year ago
- Assignee deleted (
Paula Păstrăguș) - Status changed from Merge Pending to Test
10027a was merged to trunk as rev 15935 and archived.
#21 Updated by Paula Păstrăguș about 1 year ago
- Assignee set to Paula Păstrăguș