Skip to content

Commit 3c0c803

Browse files
committed
fix routine analysis when compact() is there
avoids nullifying all the types
1 parent 342ea2d commit 3c0c803

File tree

3 files changed

+46
-25
lines changed

3 files changed

+46
-25
lines changed

src/Peachpie.CodeAnalysis/FlowAnalysis/ExpressionAnalysis.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1891,12 +1891,17 @@ TypeRefMask BindValidRoutineCall(BoundRoutineCall call, MethodSymbol method, Imm
18911891
var rflags = method.InvocationFlags(out var localaccess);
18921892
Routine.Flags |= rflags;
18931893

1894-
if ((rflags & RoutineFlags.UsesLocals) != 0
1895-
//&& (x is BoundGlobalFunctionCall gf && gf.Name.NameValue.Name.Value == "extract") // "compact" does not change locals // CONSIDER // TODO
1896-
)
1894+
if ((rflags & RoutineFlags.UsesLocals) != 0)
18971895
{
1898-
// function may change/add local variables
1899-
State.SetAllUnknown(true);
1896+
if (call is BoundGlobalFunctionCall && method.Name == "compact")
1897+
{
1898+
// "compact" does not change locals // NOTE: it's ugly cause we don't have flags for that yet
1899+
}
1900+
else
1901+
{
1902+
// function may change/add local variables
1903+
State.SetAllUnknown(true);
1904+
}
19001905
}
19011906

19021907
if (localaccess != null)

src/Peachpie.CodeAnalysis/FlowAnalysis/FlowContext.cs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -132,17 +132,17 @@ public VariableHandle GetVarIndex(VariableName name)
132132
return new VariableHandle() { Slot = index, Name = name };
133133
}
134134

135-
/// <summary>
136-
/// Enumerates all known variables as pairs of their index and name.
137-
/// </summary>
138-
public IEnumerable<VariableHandle> EnumerateVariables()
139-
{
140-
return _varsIndex.Select(pair => new VariableHandle()
141-
{
142-
Slot = pair.Value,
143-
Name = pair.Key,
144-
});
145-
}
135+
///// <summary>
136+
///// Enumerates all known variables as pairs of their index and name.
137+
///// </summary>
138+
//public IEnumerable<VariableHandle> EnumerateVariables()
139+
//{
140+
// return _varsIndex.Select(pair => new VariableHandle()
141+
// {
142+
// Slot = pair.Value,
143+
// Name = pair.Key,
144+
// });
145+
//}
146146

147147
public void SetReference(int varindex)
148148
{

src/Peachpie.CodeAnalysis/FlowAnalysis/FlowState.cs

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using Devsense.PHP.Syntax;
2+
using Devsense.PHP.Syntax.Ast;
23
using Microsoft.CodeAnalysis;
34
using Pchp.CodeAnalysis.Semantics;
45
using Pchp.CodeAnalysis.Symbols;
@@ -213,18 +214,27 @@ public bool Equals(IFlowState<FlowState> other)
213214
public void SetLocalType(VariableHandle handle, TypeRefMask tmask)
214215
{
215216
handle.ThrowIfInvalid();
217+
SetLocalType(handle.Slot, tmask);
218+
}
216219

217-
if (handle >= _varsType.Length)
220+
/// <summary>
221+
/// Sets variable type in this state.
222+
/// </summary>
223+
/// <param name="varindex">Variable slot.</param>
224+
/// <param name="tmask">Variable type. If <c>uninitialized</c>, the variable is set as not initialized in this state.</param>
225+
public void SetLocalType(int varindex, TypeRefMask tmask)
226+
{
227+
if (varindex >= _varsType.Length)
218228
{
219-
Array.Resize(ref _varsType, handle + 1);
229+
Array.Resize(ref _varsType, varindex + 1);
220230
}
221231

222-
_varsType[handle] = tmask;
232+
_varsType[varindex] = tmask;
223233

224-
this.FlowContext.AddVarType(handle, tmask); // TODO: collect merged type information at the end of analysis
234+
this.FlowContext.AddVarType(varindex, tmask); // TODO: collect merged type information at the end of analysis
225235

226236
// update the _initializedMask
227-
SetVarInitialized(handle);
237+
SetVarInitialized(varindex);
228238
}
229239

230240
/// <summary>
@@ -282,9 +292,14 @@ public void SetAllUnknown(bool maybeRef)
282292
? TypeRefMask.AnyType.WithRefFlag
283293
: TypeRefMask.AnyType;
284294

285-
foreach (var v in FlowContext.EnumerateVariables())
295+
//foreach (var v in FlowContext.EnumerateVariables())
296+
//{
297+
// SetLocalType(v, tmask);
298+
//}
299+
300+
for (int i = 0; i < FlowContext.VarsType.Length; i++)
286301
{
287-
SetLocalType(v, tmask);
302+
SetLocalType(i, tmask);
288303
}
289304

290305
// all initialized
@@ -306,9 +321,10 @@ public void FlowThroughReturn(TypeRefMask type)
306321
FlowContext.ReturnType |= type;
307322
}
308323

309-
public void SetVarInitialized(VariableHandle handle)
324+
public void SetVarInitialized(VariableHandle handle) => SetVarInitialized(handle.Slot);
325+
326+
public void SetVarInitialized(int varindex)
310327
{
311-
int varindex = handle.Slot;
312328
if (varindex >= 0 && varindex < FlowContext.BitsCount)
313329
{
314330
_initializedMask |= 1ul << varindex;

0 commit comments

Comments
 (0)