@@ -93,7 +93,7 @@ class Objects(using Context @constructorOnly):
93
93
* | OfClass(class, vs[outer], ctor, args, env) // instance of a class
94
94
* | OfArray(object[owner], regions)
95
95
* | Fun(..., env) // value elements that can be contained in ValueSet
96
- * | BaseValue // Int, String, etc.
96
+ * | SafeValue // values on which method calls and fields won't cause warnings. Int, String, etc.
97
97
* vs ::= ValueSet(ve) // set of abstract values
98
98
* Bottom ::= ValueSet(Empty)
99
99
* val ::= ve | UnknownValue | vs | Package // all possible abstract values in domain
@@ -229,8 +229,9 @@ class Objects(using Context @constructorOnly):
229
229
230
230
/** Represents common base values like Int, String, etc.
231
231
*/
232
- case object BaseValue extends ValueElement :
233
- def show (using Context ): String = " BaseValue"
232
+ case object SafeValue extends ValueElement :
233
+ val safeTypes = defn.ScalaNumericValueTypeList ++ List (defn.UnitType , defn.BooleanType , defn.StringType )
234
+ def show (using Context ): String = " SafeValue"
234
235
235
236
/**
236
237
* Represents a set of values
@@ -661,7 +662,7 @@ class Objects(using Context @constructorOnly):
661
662
a match
662
663
case UnknownValue => UnknownValue
663
664
case Package (_) => a
664
- case BaseValue => BaseValue
665
+ case SafeValue => SafeValue
665
666
case ref : Ref => if ref.klass.isSubClass(klass) then ref else Bottom
666
667
case ValueSet (values) => values.map(v => v.filterClass(klass)).join
667
668
case arr : OfArray => if defn.ArrayClass .isSubClass(klass) then arr else Bottom
@@ -703,8 +704,8 @@ class Objects(using Context @constructorOnly):
703
704
report.warning(" [Internal error] Unexpected call on package = " + value.show + " , meth = " + meth.show + Trace .show, Trace .position)
704
705
Bottom
705
706
706
- case BaseValue =>
707
- if reportUnknown then UnknownValue else BaseValue
707
+ case SafeValue =>
708
+ SafeValue // Check return type, if not safe, try to analyze body, 1.until(2).map(i => UninitializedObject)
708
709
709
710
case Bottom =>
710
711
Bottom
@@ -731,7 +732,7 @@ class Objects(using Context @constructorOnly):
731
732
Bottom
732
733
else
733
734
// Array.length is OK
734
- BaseValue
735
+ SafeValue
735
736
736
737
case ref : Ref =>
737
738
val isLocal = ! meth.owner.isClass
@@ -752,10 +753,10 @@ class Objects(using Context @constructorOnly):
752
753
arr
753
754
else if target.equals(defn.Predef_classOf ) then
754
755
// Predef.classOf is a stub method in tasty and is replaced in backend
755
- BaseValue
756
+ SafeValue
756
757
else if target.equals(defn.ClassTagModule_apply ) then
757
758
// ClassTag and other reflection related values are considered safe
758
- BaseValue
759
+ SafeValue
759
760
else if target.hasSource then
760
761
val cls = target.owner.enclosingClass.asClass
761
762
val ddef = target.defTree.asInstanceOf [DefDef ]
@@ -869,8 +870,8 @@ class Objects(using Context @constructorOnly):
869
870
else
870
871
UnknownValue
871
872
872
- case BaseValue =>
873
- if reportUnknown then UnknownValue else BaseValue
873
+ case SafeValue =>
874
+ SafeValue
874
875
875
876
case Package (packageSym) =>
876
877
if field.isStaticObject then
@@ -954,7 +955,7 @@ class Objects(using Context @constructorOnly):
954
955
case arr : OfArray =>
955
956
report.warning(" [Internal error] unexpected tree in assignment, array = " + arr.show + " field = " + field + Trace .show, Trace .position)
956
957
957
- case BaseValue | UnknownValue =>
958
+ case SafeValue | UnknownValue =>
958
959
report.warning(" Assigning to base or unknown value is forbidden. " + Trace .show, Trace .position)
959
960
960
961
case ValueSet (values) =>
@@ -986,7 +987,7 @@ class Objects(using Context @constructorOnly):
986
987
*/
987
988
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) {
988
989
outer.filterClass(klass.owner) match
989
- case _ : Fun | _ : OfArray | BaseValue =>
990
+ case _ : Fun | _ : OfArray | SafeValue =>
990
991
report.warning(" [Internal error] unexpected outer in instantiating a class, outer = " + outer.show + " , class = " + klass.show + " , " + Trace .show, Trace .position)
991
992
Bottom
992
993
@@ -1081,7 +1082,7 @@ class Objects(using Context @constructorOnly):
1081
1082
case UnknownValue =>
1082
1083
report.warning(" Calling on unknown value. " + Trace .show, Trace .position)
1083
1084
Bottom
1084
- case _ : ValueSet | _ : Ref | _ : OfArray | _ : Package | BaseValue =>
1085
+ case _ : ValueSet | _ : Ref | _ : OfArray | _ : Package | SafeValue =>
1085
1086
report.warning(" [Internal error] Unexpected by-name value " + value.show + " . " + Trace .show, Trace .position)
1086
1087
Bottom
1087
1088
else
@@ -1269,7 +1270,7 @@ class Objects(using Context @constructorOnly):
1269
1270
evalType(expr.tpe, thisV, klass)
1270
1271
1271
1272
case Literal (_) =>
1272
- BaseValue
1273
+ SafeValue
1273
1274
1274
1275
case Typed (expr, tpt) =>
1275
1276
if tpt.tpe.hasAnnotation(defn.UncheckedAnnot ) then
@@ -1555,7 +1556,7 @@ class Objects(using Context @constructorOnly):
1555
1556
1556
1557
// call .apply
1557
1558
val applyDenot = getMemberMethod(scrutineeType, nme.apply, applyType(elemType))
1558
- val applyRes = call(scrutinee, applyDenot.symbol, ArgInfo (BaseValue , summon[Trace ], EmptyTree ) :: Nil , scrutineeType, superType = NoType , needResolve = true )
1559
+ val applyRes = call(scrutinee, applyDenot.symbol, ArgInfo (SafeValue , summon[Trace ], EmptyTree ) :: Nil , scrutineeType, superType = NoType , needResolve = true )
1559
1560
1560
1561
if isWildcardStarArgList(pats) then
1561
1562
if pats.size == 1 then
@@ -1566,7 +1567,7 @@ class Objects(using Context @constructorOnly):
1566
1567
else
1567
1568
// call .drop
1568
1569
val dropDenot = getMemberMethod(scrutineeType, nme.drop, dropType(elemType))
1569
- val dropRes = call(scrutinee, dropDenot.symbol, ArgInfo (BaseValue , summon[Trace ], EmptyTree ) :: Nil , scrutineeType, superType = NoType , needResolve = true )
1570
+ val dropRes = call(scrutinee, dropDenot.symbol, ArgInfo (SafeValue , summon[Trace ], EmptyTree ) :: Nil , scrutineeType, superType = NoType , needResolve = true )
1570
1571
for pat <- pats.init do evalPattern(applyRes, pat)
1571
1572
evalPattern(dropRes, pats.last)
1572
1573
end if
@@ -1608,7 +1609,7 @@ class Objects(using Context @constructorOnly):
1608
1609
def evalType (tp : Type , thisV : ThisValue , klass : ClassSymbol , elideObjectAccess : Boolean = false ): Contextual [Value ] = log(" evaluating " + tp.show, printer, (_ : Value ).show) {
1609
1610
tp match
1610
1611
case _ : ConstantType =>
1611
- BaseValue
1612
+ SafeValue
1612
1613
1613
1614
case tmref : TermRef if tmref.prefix == NoPrefix =>
1614
1615
val sym = tmref.symbol
@@ -1858,7 +1859,7 @@ class Objects(using Context @constructorOnly):
1858
1859
resolveThis(target, ref.outerValue(klass), outerCls)
1859
1860
case ValueSet (values) =>
1860
1861
values.map(ref => resolveThis(target, ref, klass)).join
1861
- case _ : Fun | _ : OfArray | _ : Package | BaseValue =>
1862
+ case _ : Fun | _ : OfArray | _ : Package | SafeValue =>
1862
1863
report.warning(" [Internal error] unexpected thisV = " + thisV + " , target = " + target.show + " , klass = " + klass.show + Trace .show, Trace .position)
1863
1864
Bottom
1864
1865
}
0 commit comments