@@ -565,7 +565,7 @@ object Objects:
565
565
566
566
// --------------------------- domain operations -----------------------------
567
567
568
- type ArgInfo = TraceValue [ Value ]
568
+ case class ArgInfo ( value : Value , trace : Trace , tree : Tree )
569
569
570
570
extension (a : Value )
571
571
def join (b : Value ): Value =
@@ -875,7 +875,7 @@ object Objects:
875
875
* @param ctor The symbol of the target constructor.
876
876
* @param args The arguments passsed to the constructor.
877
877
*/
878
- def instantiate (outer : Value , klass : ClassSymbol , ctor : Symbol , args : List [ArgInfo ]): Contextual [Value ] = log(" instantiating " + klass.show + " , outer = " + outer + " , args = " + args.map(_.value.show), printer, (_ : Value ).show) {
878
+ def instantiate (outer : Value , klass : ClassSymbol , ctor : Symbol , args : List [ArgInfo ], inKlass : ClassSymbol ): Contextual [Value ] = log(" instantiating " + klass.show + " , outer = " + outer + " , args = " + args.map(_.value.show), printer, (_ : Value ).show) {
879
879
outer match
880
880
881
881
case _ : Fun | _ : OfArray =>
@@ -884,9 +884,14 @@ object Objects:
884
884
885
885
case outer : (Ref | Cold .type | Bottom .type ) =>
886
886
if klass == defn.ArrayClass then
887
- val arr = OfArray (State .currentObject, summon[Regions .Data ])
888
- Heap .writeJoin(arr.addr, Bottom )
889
- arr
887
+ args.head.tree.tpe match
888
+ case ConstantType (Constants .Constant (0 )) =>
889
+ // new Array(0)
890
+ Bottom
891
+ case _ =>
892
+ val arr = OfArray (State .currentObject, summon[Regions .Data ])
893
+ Heap .writeJoin(arr.addr, Bottom )
894
+ arr
890
895
else
891
896
// Widen the outer to finitize the domain. Arguments already widened in `evalArgs`.
892
897
val (outerWidened, envWidened) =
@@ -909,7 +914,7 @@ object Objects:
909
914
instance
910
915
911
916
case ValueSet (values) =>
912
- values.map(ref => instantiate(ref, klass, ctor, args)).join
917
+ values.map(ref => instantiate(ref, klass, ctor, args, inKlass )).join
913
918
}
914
919
915
920
/** Handle local variable definition, `val x = e` or `var x = e`.
@@ -1083,7 +1088,7 @@ object Objects:
1083
1088
val cls = tref.classSymbol.asClass
1084
1089
withTrace(trace2) {
1085
1090
val outer = outerValue(tref, thisV, klass)
1086
- instantiate(outer, cls, ctor, args)
1091
+ instantiate(outer, cls, ctor, args, klass )
1087
1092
}
1088
1093
1089
1094
case Apply (ref, arg :: Nil ) if ref.symbol == defn.InitRegionMethod =>
@@ -1328,7 +1333,7 @@ object Objects:
1328
1333
case _ => List ()
1329
1334
1330
1335
val implicitArgsAfterScrutinee = evalArgs(implicits.map(Arg .apply), thisV, klass)
1331
- val args = implicitArgsBeforeScrutinee(fun) ++ (TraceValue (scrutinee, summon[Trace ]) :: implicitArgsAfterScrutinee)
1336
+ val args = implicitArgsBeforeScrutinee(fun) ++ (ArgInfo (scrutinee, summon[Trace ], EmptyTree ) :: implicitArgsAfterScrutinee)
1332
1337
val unapplyRes = call(receiver, funRef.symbol, args, funRef.prefix, superType = NoType , needResolve = true )
1333
1338
1334
1339
if fun.symbol.name == nme.unapplySeq then
@@ -1425,15 +1430,15 @@ object Objects:
1425
1430
// call .lengthCompare or .length
1426
1431
val lengthCompareDenot = getMemberMethod(scrutineeType, nme.lengthCompare, lengthCompareType)
1427
1432
if lengthCompareDenot.exists then
1428
- call(scrutinee, lengthCompareDenot.symbol, TraceValue (Bottom , summon[Trace ]) :: Nil , scrutineeType, superType = NoType , needResolve = true )
1433
+ call(scrutinee, lengthCompareDenot.symbol, ArgInfo (Bottom , summon[Trace ], EmptyTree ) :: Nil , scrutineeType, superType = NoType , needResolve = true )
1429
1434
else
1430
1435
val lengthDenot = getMemberMethod(scrutineeType, nme.length, lengthType)
1431
1436
call(scrutinee, lengthDenot.symbol, Nil , scrutineeType, superType = NoType , needResolve = true )
1432
1437
end if
1433
1438
1434
1439
// call .apply
1435
1440
val applyDenot = getMemberMethod(scrutineeType, nme.apply, applyType(elemType))
1436
- val applyRes = call(scrutinee, applyDenot.symbol, TraceValue (Bottom , summon[Trace ]) :: Nil , scrutineeType, superType = NoType , needResolve = true )
1441
+ val applyRes = call(scrutinee, applyDenot.symbol, ArgInfo (Bottom , summon[Trace ], EmptyTree ) :: Nil , scrutineeType, superType = NoType , needResolve = true )
1437
1442
1438
1443
if isWildcardStarArgList(pats) then
1439
1444
if pats.size == 1 then
@@ -1444,7 +1449,7 @@ object Objects:
1444
1449
else
1445
1450
// call .drop
1446
1451
val dropDenot = getMemberMethod(scrutineeType, nme.drop, applyType(elemType))
1447
- val dropRes = call(scrutinee, dropDenot.symbol, TraceValue (Bottom , summon[Trace ]) :: Nil , scrutineeType, superType = NoType , needResolve = true )
1452
+ val dropRes = call(scrutinee, dropDenot.symbol, ArgInfo (Bottom , summon[Trace ], EmptyTree ) :: Nil , scrutineeType, superType = NoType , needResolve = true )
1448
1453
for pat <- pats.init do evalPattern(applyRes, pat)
1449
1454
evalPattern(dropRes, pats.last)
1450
1455
end if
@@ -1546,7 +1551,7 @@ object Objects:
1546
1551
case _ =>
1547
1552
res.widen(1 )
1548
1553
1549
- argInfos += TraceValue (widened, trace.add(arg.tree))
1554
+ argInfos += ArgInfo (widened, trace.add(arg.tree), arg.tree )
1550
1555
}
1551
1556
argInfos.toList
1552
1557
@@ -1644,7 +1649,7 @@ object Objects:
1644
1649
// The parameter check of traits comes late in the mixin phase.
1645
1650
// To avoid crash we supply hot values for erroneous parent calls.
1646
1651
// See tests/neg/i16438.scala.
1647
- val args : List [ArgInfo ] = ctor.info.paramInfoss.flatten.map(_ => new ArgInfo (Bottom , Trace .empty))
1652
+ val args : List [ArgInfo ] = ctor.info.paramInfoss.flatten.map(_ => new ArgInfo (Bottom , Trace .empty, EmptyTree ))
1648
1653
extendTrace(superParent) {
1649
1654
superCall(tref, ctor, args, tasks)
1650
1655
}
0 commit comments