@@ -31,32 +31,23 @@ private class SwiftDataFlowPlugin extends DataFlowPlugin {
3131 )
3232 or
3333 exists ( UnaryExpr expr |
34- expr .getOperator ( ) .( PostfixOperator ) .getValue ( ) = "!" and
35- node1 .isResultValue ( expr .getOperand ( ) ) and
36- ( step .readName ( "some.0" ) or step .taint ( ) ) and
37- node2 .isResultValue ( expr )
34+ expr .getOperator ( ) .( PostfixOperator ) .getValue ( ) = "!"
3835 or
39- expr .getOperator ( ) .( PrefixOperator ) .getValue ( ) = [ "try" , "try!" , "await" ] and
36+ expr .getOperator ( ) .( PrefixOperator ) .getValue ( ) = [ "try" , "try!" , "try?" , "await" ]
37+ |
4038 node1 .isResultValue ( expr .getOperand ( ) ) and
4139 step .value ( ) and
4240 node2 .isResultValue ( expr )
43- or
44- expr .getOperator ( ) .( PrefixOperator ) .getValue ( ) = "try?" and
45- // TODO: preserve the value of some.0 if it is already stored in that
46- node1 .isResultValue ( expr .getOperand ( ) ) and
47- step .storeName ( "some.0" ) and
48- node2 .isResultValue ( expr )
4941 )
5042 or
5143 exists ( TypeCastExpr expr |
52- // The `as?` type cast boxes the incoming value in Optional depending on whether the type cast succeeded
53- expr .getOperator ( ) .getValue ( ) = "as?" and
54- node1 .isResultValue ( expr .getExpr ( ) ) and
55- step .storeName ( "some.0" ) and
56- node2 .isResultValue ( expr )
57- or
58- // Safe upcast conversion ("as") and downcast-or-throw ("as!") propagate the value directly
59- expr .getOperator ( ) .getValue ( ) = [ "as" , "as!" ] and
44+ // Type-cast operators:
45+ // - "as": Safe upcast conversion
46+ // - "as?": Wrap in Optional<T> if cast succeeds
47+ // - "as!": Throw if cast fails
48+ //
49+ // Since we bypass Optional<T> content, we model all of these as value steps.
50+ expr .getOperator ( ) .getValue ( ) = [ "as" , "as?" , "as!" ] and
6051 node1 .isResultValue ( expr .getExpr ( ) ) and
6152 step .value ( ) and
6253 node2 .isResultValue ( expr )
0 commit comments