@@ -98,6 +98,13 @@ private API::Node parseOptionsModule() {
98
98
result = API:: getTopLevelMember ( "XML" ) .getMember ( "Options" )
99
99
}
100
100
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
+
101
108
private DataFlow:: LocalSourceNode trackFeature ( Feature f , boolean enable , TypeTracker t ) {
102
109
t .start ( ) and
103
110
(
@@ -112,38 +119,14 @@ private DataFlow::LocalSourceNode trackFeature(Feature f, boolean enable, TypeTr
112
119
enable = true and
113
120
result = parseOptionsModule ( ) .getMember ( f .getConstantName ( ) ) .getAUse ( )
114
121
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.
134
126
exists ( CfgNodes:: ExprNodes:: OperationCfgNode operation |
127
+ bitWiseAndOr ( operation ) and
135
128
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 ( )
147
130
)
148
131
or
149
132
// The complement operator toggles a feature from enabled to disabled and vice-versa
0 commit comments