@@ -98,6 +98,13 @@ private API::Node parseOptionsModule() {
9898 result = API:: getTopLevelMember ( "XML" ) .getMember ( "Options" )
9999}
100100
101+ private predicate bitWiseAndOr ( CfgNodes:: ExprNodes:: OperationCfgNode operation ) {
102+ operation .getExpr ( ) instanceof BitwiseAndExpr or
103+ operation .getExpr ( ) instanceof AssignBitwiseAndExpr or
104+ operation .getExpr ( ) instanceof BitwiseOrExpr or
105+ operation .getExpr ( ) instanceof AssignBitwiseOrExpr
106+ }
107+
101108private DataFlow:: LocalSourceNode trackFeature ( Feature f , boolean enable , TypeTracker t ) {
102109 t .start ( ) and
103110 (
@@ -112,38 +119,14 @@ private DataFlow::LocalSourceNode trackFeature(Feature f, boolean enable, TypeTr
112119 enable = true and
113120 result = parseOptionsModule ( ) .getMember ( f .getConstantName ( ) ) .getAUse ( )
114121 or
115- // If a feature is enabled in any of the operands of the `|` and `|=` operators
116- // then the feature is also enabled in the result of the operators.
117- exists ( CfgNodes:: ExprNodes:: OperationCfgNode operation |
118- operation = result .asExpr ( ) .( CfgNodes:: ExprNodes:: OperationCfgNode ) and
119- (
120- operation .getExpr ( ) instanceof BitwiseOrExpr or
121- operation .getExpr ( ) instanceof AssignBitwiseOrExpr
122- )
123- |
124- enable = true and
125- operation .getAnOperand ( ) = trackFeature ( f , true ) .asExpr ( )
126- or
127- enable = false and
128- operation .getAnOperand ( ) = trackFeature ( f , false ) .asExpr ( ) and
129- forall ( DataFlow:: Node n | n .asExpr ( ) = operation .getAnOperand ( ) | n != trackFeature ( f , true ) )
130- )
131- or
132- // If a feature is disabled in any of the operands of the `&` and `&=` operators
133- // then the feature is also disabled in the result of the operators.
122+ // Treat `&`, `&=`, `|` and `|=` operators as if they preserve the on/off states
123+ // of their operands. This is an overapproximation but likely to work well in practice
124+ // because it makes little sense to explicitly set a feature to both `on` and `off` in the
125+ // same code.
134126 exists ( CfgNodes:: ExprNodes:: OperationCfgNode operation |
127+ bitWiseAndOr ( operation ) and
135128 operation = result .asExpr ( ) .( CfgNodes:: ExprNodes:: OperationCfgNode ) and
136- (
137- operation .getExpr ( ) instanceof BitwiseAndExpr or
138- operation .getExpr ( ) instanceof AssignBitwiseAndExpr
139- )
140- |
141- enable = false and
142- operation .getAnOperand ( ) = trackFeature ( f , false ) .asExpr ( )
143- or
144- enable = true and
145- operation .getAnOperand ( ) = trackFeature ( f , true ) .asExpr ( ) and
146- forall ( DataFlow:: Node n | n .asExpr ( ) = operation .getAnOperand ( ) | n != trackFeature ( f , false ) )
129+ operation .getAnOperand ( ) = trackFeature ( f , enable ) .asExpr ( )
147130 )
148131 or
149132 // The complement operator toggles a feature from enabled to disabled and vice-versa
0 commit comments