Proper fix for unwanted substitutions in function calls

SymbolReplacedOrDeleted had an "emergency fix" that disabled several kinds of substitutions, because they generated code that didn't compile. The cause was actually elsewhere.

The actual problem was the marking of function parameters as being written to by function calls. This is true in a sense, but there's a big scope change that totally destroys the possibility of substituting identifiers, for example.

We were not removing the function parameters, anyway, therefore that code has just been disabled.

Note that removal of function parameters may be impossible if one parameter has side effects. Consider this:

f(string x, integer y, string z)
{
    llOwnerSay(x + z);
}
integer n = 2;
default{state_entry(){
  f("a" + (string)n, n=llSetRegionPos(<100,100,100>), "c" + (string)n);
}}

Even worse if the expression for the x argument has side effects too and x and y need to be performed in the right order.

Fortunately, such case is highly unlikely. But if we ever implement removal of function parameters, that's an additional difficulty to take care of.
This commit is contained in:
Sei Lisa 2019-01-03 02:31:08 +01:00
parent 454d44e85f
commit 1946acf3a4

View file

@ -163,13 +163,16 @@ class deadcode(object):
# Each element is a "write" on the callee's parameter. # Each element is a "write" on the callee's parameter.
# E.g. f(integer a, integer b) { f(2,3); } means 2, 3 are # E.g. f(integer a, integer b) { f(2,3); } means 2, 3 are
# writes to a and b. # writes to a and b.
# This has been eliminated, as it causes more trouble than
# it fixes.
self.MarkReferences(child[idx]) self.MarkReferences(child[idx])
if fdef is not None: if fdef is not None:
psym = self.symtab[fdef.pscope][fdef.pnames[idx]] psym = self.symtab[fdef.pscope][fdef.pnames[idx]]
if 'W' in psym: #if 'W' in psym:
psym['W'] = False # psym['W'] = False
else: #else:
psym['W'] = child[idx] # psym['W'] = child[idx]
psym['W'] = False
if 'Loc' in sym: if 'Loc' in sym:
if not hasattr(self.tree[sym['Loc']], 'X'): if not hasattr(self.tree[sym['Loc']], 'X'):
@ -355,9 +358,7 @@ class deadcode(object):
# Replacing j with i+1 in llOwnerSay will produce wrong code because # Replacing j with i+1 in llOwnerSay will produce wrong code because
# the name i is redefined after j is assigned. shrinknames prevents # the name i is redefined after j is assigned. shrinknames prevents
# that. # that.
# FIXME: EMERGENCY FIX: shrinknames is not enough guarantee. See nposerlv.lsl. if not self.shrinknames or not node.SEF:
#if not self.shrinknames or not node.SEF:
if True or not node.SEF:
return False return False
if nt not in ('VECTOR', 'ROTATION'): if nt not in ('VECTOR', 'ROTATION'):