@@ -926,18 +926,46 @@ private module Cached {
926926 TReturnCtxNoFlowThrough ( ) or
927927 TReturnCtxMaybeFlowThrough ( ReturnKindExt kind )
928928
929+ cached
930+ newtype TTypedContentApprox =
931+ MkTypedContentApprox ( ContentApprox c , DataFlowType t ) {
932+ exists ( Content cont |
933+ c = getContentApprox ( cont ) and
934+ store ( _, cont , _, _, t )
935+ )
936+ }
937+
929938 cached
930939 newtype TTypedContent = MkTypedContent ( Content c , DataFlowType t ) { store ( _, c , _, _, t ) }
931940
941+ cached
942+ TypedContent getATypedContent ( TypedContentApprox c ) {
943+ exists ( ContentApprox cls , DataFlowType t , Content cont |
944+ c = MkTypedContentApprox ( cls , pragma [ only_bind_into ] ( t ) ) and
945+ result = MkTypedContent ( cont , pragma [ only_bind_into ] ( t ) ) and
946+ cls = getContentApprox ( cont )
947+ )
948+ }
949+
932950 cached
933951 newtype TAccessPathFront =
934952 TFrontNil ( DataFlowType t ) or
935953 TFrontHead ( TypedContent tc )
936954
955+ cached
956+ newtype TApproxAccessPathFront =
957+ TApproxFrontNil ( DataFlowType t ) or
958+ TApproxFrontHead ( TypedContentApprox tc )
959+
937960 cached
938961 newtype TAccessPathFrontOption =
939962 TAccessPathFrontNone ( ) or
940963 TAccessPathFrontSome ( AccessPathFront apf )
964+
965+ cached
966+ newtype TApproxAccessPathFrontOption =
967+ TApproxAccessPathFrontNone ( ) or
968+ TApproxAccessPathFrontSome ( ApproxAccessPathFront apf )
941969}
942970
943971/**
@@ -1353,6 +1381,75 @@ class ReturnCtx extends TReturnCtx {
13531381 }
13541382}
13551383
1384+ /** An approximated `Content` tagged with the type of a containing object. */
1385+ class TypedContentApprox extends MkTypedContentApprox {
1386+ private ContentApprox c ;
1387+ private DataFlowType t ;
1388+
1389+ TypedContentApprox ( ) { this = MkTypedContentApprox ( c , t ) }
1390+
1391+ /** Gets a typed content approximated by this value. */
1392+ TypedContent getATypedContent ( ) { result = getATypedContent ( this ) }
1393+
1394+ /** Gets the container type. */
1395+ DataFlowType getContainerType ( ) { result = t }
1396+
1397+ /** Gets a textual representation of this approximated content. */
1398+ string toString ( ) { result = c .toString ( ) }
1399+ }
1400+
1401+ /**
1402+ * The front of an approximated access path. This is either a head or a nil.
1403+ */
1404+ abstract class ApproxAccessPathFront extends TApproxAccessPathFront {
1405+ abstract string toString ( ) ;
1406+
1407+ abstract DataFlowType getType ( ) ;
1408+
1409+ abstract boolean toBoolNonEmpty ( ) ;
1410+
1411+ pragma [ nomagic]
1412+ TypedContent getAHead ( ) {
1413+ exists ( TypedContentApprox cont |
1414+ this = TApproxFrontHead ( cont ) and
1415+ result = cont .getATypedContent ( )
1416+ )
1417+ }
1418+ }
1419+
1420+ class ApproxAccessPathFrontNil extends ApproxAccessPathFront , TApproxFrontNil {
1421+ private DataFlowType t ;
1422+
1423+ ApproxAccessPathFrontNil ( ) { this = TApproxFrontNil ( t ) }
1424+
1425+ override string toString ( ) { result = ppReprType ( t ) }
1426+
1427+ override DataFlowType getType ( ) { result = t }
1428+
1429+ override boolean toBoolNonEmpty ( ) { result = false }
1430+ }
1431+
1432+ class ApproxAccessPathFrontHead extends ApproxAccessPathFront , TApproxFrontHead {
1433+ private TypedContentApprox tc ;
1434+
1435+ ApproxAccessPathFrontHead ( ) { this = TApproxFrontHead ( tc ) }
1436+
1437+ override string toString ( ) { result = tc .toString ( ) }
1438+
1439+ override DataFlowType getType ( ) { result = tc .getContainerType ( ) }
1440+
1441+ override boolean toBoolNonEmpty ( ) { result = true }
1442+ }
1443+
1444+ /** An optional approximated access path front. */
1445+ class ApproxAccessPathFrontOption extends TApproxAccessPathFrontOption {
1446+ string toString ( ) {
1447+ this = TApproxAccessPathFrontNone ( ) and result = "<none>"
1448+ or
1449+ this = TApproxAccessPathFrontSome ( any ( ApproxAccessPathFront apf | result = apf .toString ( ) ) )
1450+ }
1451+ }
1452+
13561453/** A `Content` tagged with the type of a containing object. */
13571454class TypedContent extends MkTypedContent {
13581455 private Content c ;
@@ -1385,7 +1482,7 @@ abstract class AccessPathFront extends TAccessPathFront {
13851482
13861483 abstract DataFlowType getType ( ) ;
13871484
1388- abstract boolean toBoolNonEmpty ( ) ;
1485+ abstract ApproxAccessPathFront toApprox ( ) ;
13891486
13901487 TypedContent getHead ( ) { this = TFrontHead ( result ) }
13911488}
@@ -1399,7 +1496,7 @@ class AccessPathFrontNil extends AccessPathFront, TFrontNil {
13991496
14001497 override DataFlowType getType ( ) { result = t }
14011498
1402- override boolean toBoolNonEmpty ( ) { result = false }
1499+ override ApproxAccessPathFront toApprox ( ) { result = TApproxFrontNil ( t ) }
14031500}
14041501
14051502class AccessPathFrontHead extends AccessPathFront , TFrontHead {
@@ -1411,7 +1508,7 @@ class AccessPathFrontHead extends AccessPathFront, TFrontHead {
14111508
14121509 override DataFlowType getType ( ) { result = tc .getContainerType ( ) }
14131510
1414- override boolean toBoolNonEmpty ( ) { result = true }
1511+ override ApproxAccessPathFront toApprox ( ) { result . getAHead ( ) = tc }
14151512}
14161513
14171514/** An optional access path front. */
0 commit comments