4
4
5
5
import java
6
6
private import semmle.code.java.frameworks.android.Compose
7
+ private import semmle.code.java.Constants
7
8
8
9
/** A common super-class that represents all kinds of expressions. */
9
10
class Expr extends ExprParent , @expr {
@@ -130,6 +131,7 @@ private predicate primitiveOrString(Type t) {
130
131
* See JLS v8, section 15.28 (Constant Expressions).
131
132
*/
132
133
class CompileTimeConstantExpr extends Expr {
134
+ pragma [ assume_small_delta]
133
135
CompileTimeConstantExpr ( ) {
134
136
primitiveOrString ( this .getType ( ) ) and
135
137
(
@@ -179,6 +181,7 @@ class CompileTimeConstantExpr extends Expr {
179
181
/**
180
182
* Gets the string value of this expression, where possible.
181
183
*/
184
+ pragma [ assume_small_delta]
182
185
pragma [ nomagic]
183
186
string getStringValue ( ) {
184
187
result = this .( StringLiteral ) .getValue ( )
@@ -204,75 +207,13 @@ class CompileTimeConstantExpr extends Expr {
204
207
/**
205
208
* Gets the boolean value of this expression, where possible.
206
209
*/
210
+ pragma [ assume_small_delta]
211
+ pragma [ nomagic]
207
212
boolean getBooleanValue ( ) {
208
213
// Literal value.
209
214
result = this .( BooleanLiteral ) .getBooleanValue ( )
210
215
or
211
- // No casts relevant to booleans.
212
- // `!` is the only unary operator that evaluates to a boolean.
213
- result = this .( LogNotExpr ) .getExpr ( ) .( CompileTimeConstantExpr ) .getBooleanValue ( ) .booleanNot ( )
214
- or
215
- // Handle binary expressions that have integer operands and a boolean result.
216
- exists ( BinaryExpr b , int left , int right |
217
- b = this and
218
- left = b .getLeftOperand ( ) .( CompileTimeConstantExpr ) .getIntValue ( ) and
219
- right = b .getRightOperand ( ) .( CompileTimeConstantExpr ) .getIntValue ( )
220
- |
221
- (
222
- b instanceof LTExpr and
223
- if left < right then result = true else result = false
224
- )
225
- or
226
- (
227
- b instanceof LEExpr and
228
- if left <= right then result = true else result = false
229
- )
230
- or
231
- (
232
- b instanceof GTExpr and
233
- if left > right then result = true else result = false
234
- )
235
- or
236
- (
237
- b instanceof GEExpr and
238
- if left >= right then result = true else result = false
239
- )
240
- or
241
- (
242
- b instanceof ValueOrReferenceEqualsExpr and
243
- if left = right then result = true else result = false
244
- )
245
- or
246
- (
247
- b instanceof ValueOrReferenceNotEqualsExpr and
248
- if left != right then result = true else result = false
249
- )
250
- )
251
- or
252
- // Handle binary expressions that have boolean operands and a boolean result.
253
- exists ( BinaryExpr b , boolean left , boolean right |
254
- b = this and
255
- left = b .getLeftOperand ( ) .( CompileTimeConstantExpr ) .getBooleanValue ( ) and
256
- right = b .getRightOperand ( ) .( CompileTimeConstantExpr ) .getBooleanValue ( )
257
- |
258
- (
259
- b instanceof ValueOrReferenceEqualsExpr and
260
- if left = right then result = true else result = false
261
- )
262
- or
263
- (
264
- b instanceof ValueOrReferenceNotEqualsExpr and
265
- if left != right then result = true else result = false
266
- )
267
- or
268
- ( b instanceof AndBitwiseExpr or b instanceof AndLogicalExpr ) and
269
- result = left .booleanAnd ( right )
270
- or
271
- ( b instanceof OrBitwiseExpr or b instanceof OrLogicalExpr ) and
272
- result = left .booleanOr ( right )
273
- or
274
- b instanceof XorBitwiseExpr and result = left .booleanXor ( right )
275
- )
216
+ result = CalcCompileTimeConstants:: calculateBooleanValue ( this )
276
217
or
277
218
// Handle binary expressions that have `String` operands and a boolean result.
278
219
exists ( BinaryExpr b , string left , string right |
@@ -300,18 +241,6 @@ class CompileTimeConstantExpr extends Expr {
300
241
)
301
242
or
302
243
// Note: no `getFloatValue()`, so we cannot support binary expressions with float or double operands.
303
- // Ternary expressions, where the `true` and `false` expressions are boolean compile-time constants.
304
- exists ( ConditionalExpr ce , boolean condition |
305
- ce = this and
306
- condition = ce .getCondition ( ) .( CompileTimeConstantExpr ) .getBooleanValue ( ) and
307
- result = ce .getBranchExpr ( condition ) .( CompileTimeConstantExpr ) .getBooleanValue ( )
308
- )
309
- or
310
- // Simple or qualified names where the variable is final and the initializer is a constant.
311
- exists ( Variable v | this = v .getAnAccess ( ) |
312
- result = v .getInitializer ( ) .( CompileTimeConstantExpr ) .getBooleanValue ( )
313
- )
314
- or
315
244
result = this .( LiveLiteral ) .getValue ( ) .getBooleanValue ( )
316
245
}
317
246
@@ -329,75 +258,20 @@ class CompileTimeConstantExpr extends Expr {
329
258
result = this .( IntegerLiteral ) .getIntValue ( )
330
259
or
331
260
result = this .( CharacterLiteral ) .getCodePointValue ( )
332
- or
333
- exists ( CastingExpr cast , int val |
334
- cast = this and val = cast .getExpr ( ) .( CompileTimeConstantExpr ) .getIntValue ( )
335
- |
336
- if cast .getType ( ) .hasName ( "byte" )
337
- then result = ( val + 128 ) .bitAnd ( 255 ) - 128
338
- else
339
- if cast .getType ( ) .hasName ( "short" )
340
- then result = ( val + 32768 ) .bitAnd ( 65535 ) - 32768
341
- else
342
- if cast .getType ( ) .hasName ( "char" )
343
- then result = val .bitAnd ( 65535 )
344
- else result = val
345
- )
346
- or
347
- result = this .( PlusExpr ) .getExpr ( ) .( CompileTimeConstantExpr ) .getIntValue ( )
348
- or
349
- result = - this .( MinusExpr ) .getExpr ( ) .( CompileTimeConstantExpr ) .getIntValue ( )
350
- or
351
- result = this .( BitNotExpr ) .getExpr ( ) .( CompileTimeConstantExpr ) .getIntValue ( ) .bitNot ( )
352
- or
353
- // No `int` value for `LogNotExpr`.
354
- exists ( BinaryExpr b , int v1 , int v2 |
355
- b = this and
356
- v1 = b .getLeftOperand ( ) .( CompileTimeConstantExpr ) .getIntValue ( ) and
357
- v2 = b .getRightOperand ( ) .( CompileTimeConstantExpr ) .getIntValue ( )
358
- |
359
- b instanceof MulExpr and result = v1 * v2
360
- or
361
- b instanceof DivExpr and result = v1 / v2
362
- or
363
- b instanceof RemExpr and result = v1 % v2
364
- or
365
- b instanceof AddExpr and result = v1 + v2
366
- or
367
- b instanceof SubExpr and result = v1 - v2
368
- or
369
- b instanceof LeftShiftExpr and result = v1 .bitShiftLeft ( v2 )
370
- or
371
- b instanceof RightShiftExpr and result = v1 .bitShiftRightSigned ( v2 )
372
- or
373
- b instanceof UnsignedRightShiftExpr and result = v1 .bitShiftRight ( v2 )
374
- or
375
- b instanceof AndBitwiseExpr and result = v1 .bitAnd ( v2 )
376
- or
377
- b instanceof OrBitwiseExpr and result = v1 .bitOr ( v2 )
378
- or
379
- b instanceof XorBitwiseExpr and result = v1 .bitXor ( v2 )
380
- // No `int` value for `AndLogicalExpr` or `OrLogicalExpr`.
381
- // No `int` value for `LTExpr`, `GTExpr`, `LEExpr`, `GEExpr`, `ValueOrReferenceEqualsExpr` or `ValueOrReferenceNotEqualsExpr`.
382
- )
383
- or
384
- // Ternary conditional, with compile-time constant condition.
385
- exists ( ConditionalExpr ce , boolean condition |
386
- ce = this and
387
- condition = ce .getCondition ( ) .( CompileTimeConstantExpr ) .getBooleanValue ( ) and
388
- result = ce .getBranchExpr ( condition ) .( CompileTimeConstantExpr ) .getIntValue ( )
389
- )
390
- or
391
- // If a `Variable` is a `CompileTimeConstantExpr`, its value is its initializer.
392
- exists ( Variable v | this = v .getAnAccess ( ) |
393
- result = v .getInitializer ( ) .( CompileTimeConstantExpr ) .getIntValue ( )
394
- )
395
261
)
396
262
or
263
+ result = CalcCompileTimeConstants:: calculateIntValue ( this )
264
+ or
397
265
result = this .( LiveLiteral ) .getValue ( ) .getIntValue ( )
398
266
}
399
267
}
400
268
269
+ private boolean getBoolValue ( Expr e ) { result = e .( CompileTimeConstantExpr ) .getBooleanValue ( ) }
270
+
271
+ private int getIntValue ( Expr e ) { result = e .( CompileTimeConstantExpr ) .getIntValue ( ) }
272
+
273
+ private module CalcCompileTimeConstants = CalculateConstants< getBoolValue / 1 , getIntValue / 1 > ;
274
+
401
275
/** An expression parent is an element that may have an expression as its child. */
402
276
class ExprParent extends @exprparent, Top { }
403
277
0 commit comments