@@ -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
@@ -668,7 +669,7 @@ class Objects(using Context @constructorOnly):
668
669
a match
669
670
case UnknownValue => UnknownValue
670
671
case Package (_) => a
671
- case BaseValue => BaseValue
672
+ case SafeValue => SafeValue
672
673
case ref : Ref => if ref.klass.isSubClass(klass) then ref else Bottom
673
674
case ValueSet (values) => values.map(v => v.filterClass(klass)).join
674
675
case arr : OfArray => if defn.ArrayClass .isSubClass(klass) then arr else Bottom
@@ -710,8 +711,8 @@ class Objects(using Context @constructorOnly):
710
711
report.warning(" [Internal error] Unexpected call on package = " + value.show + " , meth = " + meth.show + Trace .show, Trace .position)
711
712
Bottom
712
713
713
- case BaseValue =>
714
- if reportUnknown then UnknownValue else BaseValue
714
+ case SafeValue =>
715
+ SafeValue // Check return type, if not safe, try to analyze body, 1.until(2).map(i => UninitializedObject)
715
716
716
717
case Bottom =>
717
718
Bottom
@@ -738,7 +739,7 @@ class Objects(using Context @constructorOnly):
738
739
Bottom
739
740
else
740
741
// Array.length is OK
741
- BaseValue
742
+ SafeValue
742
743
743
744
case ref : Ref =>
744
745
val isLocal = ! meth.owner.isClass
@@ -759,10 +760,10 @@ class Objects(using Context @constructorOnly):
759
760
arr
760
761
else if target.equals(defn.Predef_classOf ) then
761
762
// Predef.classOf is a stub method in tasty and is replaced in backend
762
- BaseValue
763
+ SafeValue
763
764
else if target.equals(defn.ClassTagModule_apply ) then
764
765
// ClassTag and other reflection related values are considered safe
765
- BaseValue
766
+ SafeValue
766
767
else if target.hasSource then
767
768
val cls = target.owner.enclosingClass.asClass
768
769
val ddef = target.defTree.asInstanceOf [DefDef ]
@@ -876,8 +877,8 @@ class Objects(using Context @constructorOnly):
876
877
else
877
878
UnknownValue
878
879
879
- case BaseValue =>
880
- if reportUnknown then UnknownValue else BaseValue
880
+ case SafeValue =>
881
+ SafeValue
881
882
882
883
case Package (packageSym) =>
883
884
if field.isStaticObject then
@@ -961,7 +962,7 @@ class Objects(using Context @constructorOnly):
961
962
case arr : OfArray =>
962
963
report.warning(" [Internal error] unexpected tree in assignment, array = " + arr.show + " field = " + field + Trace .show, Trace .position)
963
964
964
- case BaseValue | UnknownValue =>
965
+ case SafeValue | UnknownValue =>
965
966
report.warning(" Assigning to base or unknown value is forbidden. " + Trace .show, Trace .position)
966
967
967
968
case ValueSet (values) =>
@@ -993,7 +994,7 @@ class Objects(using Context @constructorOnly):
993
994
*/
994
995
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) {
995
996
outer.filterClass(klass.owner) match
996
- case _ : Fun | _ : OfArray | BaseValue =>
997
+ case _ : Fun | _ : OfArray | SafeValue =>
997
998
report.warning(" [Internal error] unexpected outer in instantiating a class, outer = " + outer.show + " , class = " + klass.show + " , " + Trace .show, Trace .position)
998
999
Bottom
999
1000
@@ -1088,7 +1089,7 @@ class Objects(using Context @constructorOnly):
1088
1089
case UnknownValue =>
1089
1090
report.warning(" Calling on unknown value. " + Trace .show, Trace .position)
1090
1091
Bottom
1091
- case _ : ValueSet | _ : Ref | _ : OfArray | _ : Package | BaseValue =>
1092
+ case _ : ValueSet | _ : Ref | _ : OfArray | _ : Package | SafeValue =>
1092
1093
report.warning(" [Internal error] Unexpected by-name value " + value.show + " . " + Trace .show, Trace .position)
1093
1094
Bottom
1094
1095
else
@@ -1276,7 +1277,7 @@ class Objects(using Context @constructorOnly):
1276
1277
evalType(expr.tpe, thisV, klass)
1277
1278
1278
1279
case Literal (_) =>
1279
- BaseValue
1280
+ SafeValue
1280
1281
1281
1282
case Typed (expr, tpt) =>
1282
1283
if tpt.tpe.hasAnnotation(defn.UncheckedAnnot ) then
@@ -1562,7 +1563,7 @@ class Objects(using Context @constructorOnly):
1562
1563
1563
1564
// call .apply
1564
1565
val applyDenot = getMemberMethod(scrutineeType, nme.apply, applyType(elemType))
1565
- val applyRes = call(scrutinee, applyDenot.symbol, ArgInfo (BaseValue , summon[Trace ], EmptyTree ) :: Nil , scrutineeType, superType = NoType , needResolve = true )
1566
+ val applyRes = call(scrutinee, applyDenot.symbol, ArgInfo (SafeValue , summon[Trace ], EmptyTree ) :: Nil , scrutineeType, superType = NoType , needResolve = true )
1566
1567
1567
1568
if isWildcardStarArgList(pats) then
1568
1569
if pats.size == 1 then
@@ -1573,7 +1574,7 @@ class Objects(using Context @constructorOnly):
1573
1574
else
1574
1575
// call .drop
1575
1576
val dropDenot = getMemberMethod(scrutineeType, nme.drop, dropType(elemType))
1576
- val dropRes = call(scrutinee, dropDenot.symbol, ArgInfo (BaseValue , summon[Trace ], EmptyTree ) :: Nil , scrutineeType, superType = NoType , needResolve = true )
1577
+ val dropRes = call(scrutinee, dropDenot.symbol, ArgInfo (SafeValue , summon[Trace ], EmptyTree ) :: Nil , scrutineeType, superType = NoType , needResolve = true )
1577
1578
for pat <- pats.init do evalPattern(applyRes, pat)
1578
1579
evalPattern(dropRes, pats.last)
1579
1580
end if
@@ -1615,7 +1616,7 @@ class Objects(using Context @constructorOnly):
1615
1616
def evalType (tp : Type , thisV : ThisValue , klass : ClassSymbol , elideObjectAccess : Boolean = false ): Contextual [Value ] = log(" evaluating " + tp.show, printer, (_ : Value ).show) {
1616
1617
tp match
1617
1618
case _ : ConstantType =>
1618
- BaseValue
1619
+ SafeValue
1619
1620
1620
1621
case tmref : TermRef if tmref.prefix == NoPrefix =>
1621
1622
val sym = tmref.symbol
@@ -1865,7 +1866,7 @@ class Objects(using Context @constructorOnly):
1865
1866
resolveThis(target, ref.outerValue(klass), outerCls)
1866
1867
case ValueSet (values) =>
1867
1868
values.map(ref => resolveThis(target, ref, klass)).join
1868
- case _ : Fun | _ : OfArray | _ : Package | BaseValue =>
1869
+ case _ : Fun | _ : OfArray | _ : Package | SafeValue =>
1869
1870
report.warning(" [Internal error] unexpected thisV = " + thisV + " , target = " + target.show + " , klass = " + klass.show + Trace .show, Trace .position)
1870
1871
Bottom
1871
1872
}
0 commit comments