@@ -842,6 +842,40 @@ module Internal {
842842 e3 = any ( NullCoalescingExpr nce | e1 = nce .getLeftOperand ( ) and e2 = nce .getRightOperand ( ) )
843843 }
844844
845+ predicate nullValueImplied ( Expr e ) {
846+ nullValue ( e )
847+ or
848+ exists ( Expr e1 | nullValueImplied ( e1 ) and nullValueImpliedUnary ( e1 , e ) )
849+ or
850+ exists ( Expr e1 , Expr e2 |
851+ nullValueImplied ( e1 ) and nullValueImplied ( e2 ) and nullValueImpliedBinary ( e1 , e2 , e )
852+ )
853+ or
854+ e =
855+ any ( Ssa:: Definition def |
856+ forex ( Ssa:: Definition u | u = def .getAnUltimateDefinition ( ) | nullDef ( u ) )
857+ ) .getARead ( )
858+ }
859+
860+ private predicate nullDef ( Ssa:: ExplicitDefinition def ) {
861+ nullValueImplied ( def .getADefinition ( ) .getSource ( ) )
862+ }
863+
864+ predicate nonNullValueImplied ( Expr e ) {
865+ nonNullValue ( e )
866+ or
867+ exists ( Expr e1 | nonNullValueImplied ( e1 ) and nonNullValueImpliedUnary ( e1 , e ) )
868+ or
869+ e =
870+ any ( Ssa:: Definition def |
871+ forex ( Ssa:: Definition u | u = def .getAnUltimateDefinition ( ) | nonNullDef ( u ) )
872+ ) .getARead ( )
873+ }
874+
875+ private predicate nonNullDef ( Ssa:: ExplicitDefinition def ) {
876+ nonNullValueImplied ( def .getADefinition ( ) .getSource ( ) )
877+ }
878+
845879 /** A callable that always returns a non-`null` value. */
846880 private class NonNullCallable extends Callable {
847881 NonNullCallable ( ) { this = any ( SystemObjectClass c ) .getGetTypeMethod ( ) }
@@ -936,154 +970,21 @@ module Internal {
936970 e = any ( BinaryArithmeticOperation bao | result = bao .getAnOperand ( ) )
937971 }
938972
939- // The predicates in this module should be evaluated in the same stage as the CFG
940- // construction stage. This is to avoid recomputation of pre-basic-blocks and
941- // pre-SSA predicates
942- private module PreCfg {
943- private import semmle.code.csharp.controlflow.internal.PreBasicBlocks as PreBasicBlocks
944- private import semmle.code.csharp.controlflow.internal.PreSsa
945-
946- private predicate nullDef ( PreSsa:: Definition def ) {
947- nullValueImplied ( def .getDefinition ( ) .getSource ( ) )
948- }
949-
950- private predicate nonNullDef ( PreSsa:: Definition def ) {
951- nonNullValueImplied ( def .getDefinition ( ) .getSource ( ) )
952- }
953-
954- private predicate emptyDef ( PreSsa:: Definition def ) {
955- emptyValue ( def .getDefinition ( ) .getSource ( ) )
956- }
957-
958- private predicate nonEmptyDef ( PreSsa:: Definition def ) {
959- nonEmptyValue ( def .getDefinition ( ) .getSource ( ) )
960- }
961-
962- deprecated predicate isGuard ( Expr e , GuardValue val ) {
963- (
964- e .getType ( ) instanceof BoolType and
965- not e instanceof BoolLiteral and
966- not e instanceof SwitchCaseExpr and
967- not e instanceof PatternExpr and
968- exists ( val .asBooleanValue ( ) )
969- or
970- e instanceof DereferenceableExpr and
971- val .isNullness ( _)
972- ) and
973- not e = any ( ExprStmt es ) .getExpr ( ) and
974- not e = any ( LocalVariableDeclStmt s ) .getAVariableDeclExpr ( )
975- }
976-
977- cached
978- private module CachedWithCfg {
979- private import semmle.code.csharp.Caching
980-
981- private predicate firstReadSameVarUniquePredecessor (
982- PreSsa:: Definition def , AssignableRead read
983- ) {
984- read = def .getAFirstRead ( ) and
985- (
986- not PreSsa:: adjacentReadPairSameVar ( _, read )
987- or
988- read = unique( AssignableRead read0 | PreSsa:: adjacentReadPairSameVar ( read0 , read ) )
989- )
990- }
991-
992- cached
993- predicate nullValueImplied ( Expr e ) {
994- nullValue ( e )
995- or
996- exists ( Expr e1 | nullValueImplied ( e1 ) and nullValueImpliedUnary ( e1 , e ) )
997- or
998- exists ( Expr e1 , Expr e2 |
999- nullValueImplied ( e1 ) and nullValueImplied ( e2 ) and nullValueImpliedBinary ( e1 , e2 , e )
1000- )
1001- or
1002- e =
1003- any ( PreSsa:: Definition def |
1004- forex ( PreSsa:: Definition u | u = def .getAnUltimateDefinition ( ) | nullDef ( u ) )
1005- ) .getARead ( )
1006- }
1007-
1008- cached
1009- predicate nonNullValueImplied ( Expr e ) {
1010- nonNullValue ( e )
1011- or
1012- exists ( Expr e1 | nonNullValueImplied ( e1 ) and nonNullValueImpliedUnary ( e1 , e ) )
1013- or
1014- e =
1015- any ( PreSsa:: Definition def |
1016- forex ( PreSsa:: Definition u | u = def .getAnUltimateDefinition ( ) | nonNullDef ( u ) )
1017- ) .getARead ( )
1018- }
1019-
1020- private predicate adjacentReadPairSameVarUniquePredecessor (
1021- AssignableRead read1 , AssignableRead read2
1022- ) {
1023- PreSsa:: adjacentReadPairSameVar ( read1 , read2 ) and
1024- (
1025- read1 = read2 and
1026- read1 = unique( AssignableRead other | PreSsa:: adjacentReadPairSameVar ( other , read2 ) )
1027- or
1028- read1 =
1029- unique( AssignableRead other |
1030- PreSsa:: adjacentReadPairSameVar ( other , read2 ) and other != read2
1031- )
1032- )
1033- }
1034-
1035- cached
1036- predicate emptyValue ( Expr e ) {
1037- e .( ArrayCreation ) .getALengthArgument ( ) .getValue ( ) .toInt ( ) = 0
1038- or
1039- e .( ArrayInitializer ) .hasNoElements ( )
1040- or
1041- exists ( Expr mid | emptyValue ( mid ) |
1042- mid = e .( AssignExpr ) .getRValue ( )
1043- or
1044- mid = e .( Cast ) .getExpr ( )
1045- )
1046- or
1047- exists ( PreSsa:: Definition def | emptyDef ( def ) | firstReadSameVarUniquePredecessor ( def , e ) )
1048- or
1049- exists ( MethodCall mc |
1050- mc .getTarget ( ) .getAnUltimateImplementee ( ) .getUnboundDeclaration ( ) =
1051- any ( SystemCollectionsGenericICollectionInterface c ) .getClearMethod ( ) and
1052- adjacentReadPairSameVarUniquePredecessor ( mc .getQualifier ( ) , e )
1053- )
1054- }
1055-
1056- cached
1057- predicate nonEmptyValue ( Expr e ) {
1058- forex ( Expr length | length = e .( ArrayCreation ) .getALengthArgument ( ) |
1059- length .getValue ( ) .toInt ( ) != 0
1060- )
1061- or
1062- e .( ArrayInitializer ) .getNumberOfElements ( ) > 0
1063- or
1064- exists ( Expr mid | nonEmptyValue ( mid ) |
1065- mid = e .( AssignExpr ) .getRValue ( )
1066- or
1067- mid = e .( Cast ) .getExpr ( )
1068- )
1069- or
1070- exists ( PreSsa:: Definition def | nonEmptyDef ( def ) |
1071- firstReadSameVarUniquePredecessor ( def , e )
1072- )
1073- or
1074- exists ( MethodCall mc |
1075- mc .getTarget ( ) .getAnUltimateImplementee ( ) .getUnboundDeclaration ( ) =
1076- any ( SystemCollectionsGenericICollectionInterface c ) .getAddMethod ( ) and
1077- adjacentReadPairSameVarUniquePredecessor ( mc .getQualifier ( ) , e )
1078- )
1079- }
1080- }
1081-
1082- import CachedWithCfg
973+ deprecated predicate isGuard ( Expr e , GuardValue val ) {
974+ (
975+ e .getType ( ) instanceof BoolType and
976+ not e instanceof BoolLiteral and
977+ not e instanceof SwitchCaseExpr and
978+ not e instanceof PatternExpr and
979+ exists ( val .asBooleanValue ( ) )
980+ or
981+ e instanceof DereferenceableExpr and
982+ val .isNullness ( _)
983+ ) and
984+ not e = any ( ExprStmt es ) .getExpr ( ) and
985+ not e = any ( LocalVariableDeclStmt s ) .getAVariableDeclExpr ( )
1083986 }
1084987
1085- import PreCfg
1086-
1087988 private predicate interestingDescendantCandidate ( Expr e ) {
1088989 guardControls ( e , _, _)
1089990 or
0 commit comments