@@ -15,91 +15,8 @@ import codingstandards.c.cert
15
15
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
16
16
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
17
17
import semmle.code.cpp.controlflow.Guards
18
+ import codingstandards.cpp.UndefinedBehavior
18
19
19
- /*
20
- * Precision predicate based on a sample implementation from
21
- * https://wiki.sei.cmu.edu/confluence/display/c/INT35-C.+Use+correct+integer+precisions
22
- */
23
-
24
- /**
25
- * A function whose name is suggestive that it counts the number of bits set.
26
- */
27
- class PopCount extends Function {
28
- PopCount ( ) { this .getName ( ) .toLowerCase ( ) .matches ( "%popc%nt%" ) }
29
- }
30
-
31
- /**
32
- * A macro which is suggestive that it is used to determine the precision of an integer.
33
- */
34
- class PrecisionMacro extends Macro {
35
- PrecisionMacro ( ) { this .getName ( ) .toLowerCase ( ) .matches ( "precision" ) }
36
- }
37
-
38
- class LiteralZero extends Literal {
39
- LiteralZero ( ) { this .getValue ( ) = "0" }
40
- }
41
-
42
- class BitShiftExpr extends BinaryBitwiseOperation {
43
- BitShiftExpr ( ) {
44
- this instanceof LShiftExpr or
45
- this instanceof RShiftExpr
46
- }
47
- }
48
-
49
- int getPrecision ( IntegralType type ) {
50
- type .isExplicitlyUnsigned ( ) and result = type .getSize ( ) * 8
51
- or
52
- type .isExplicitlySigned ( ) and result = type .getSize ( ) * 8 - 1
53
- }
54
-
55
- predicate isForbiddenShiftExpr ( BitShiftExpr shift , string message ) {
56
- (
57
- (
58
- getPrecision ( shift .getLeftOperand ( ) .getExplicitlyConverted ( ) .getUnderlyingType ( ) ) <=
59
- upperBound ( shift .getRightOperand ( ) ) and
60
- message =
61
- "The operand " + shift .getLeftOperand ( ) + " is shifted by an expression " +
62
- shift .getRightOperand ( ) + " whose upper bound (" + upperBound ( shift .getRightOperand ( ) ) +
63
- ") is greater than or equal to the precision."
64
- or
65
- lowerBound ( shift .getRightOperand ( ) ) < 0 and
66
- message =
67
- "The operand " + shift .getLeftOperand ( ) + " is shifted by an expression " +
68
- shift .getRightOperand ( ) + " which may be negative."
69
- ) and
70
- /*
71
- * Shift statement is not at a basic block where
72
- * `shift_rhs < PRECISION(...)` is ensured
73
- */
74
-
75
- not exists ( GuardCondition gc , BasicBlock block , Expr precisionCall , Expr lTLhs |
76
- block = shift .getBasicBlock ( ) and
77
- (
78
- precisionCall .( FunctionCall ) .getTarget ( ) instanceof PopCount
79
- or
80
- precisionCall = any ( PrecisionMacro pm ) .getAnInvocation ( ) .getExpr ( )
81
- )
82
- |
83
- globalValueNumber ( lTLhs ) = globalValueNumber ( shift .getRightOperand ( ) ) and
84
- gc .ensuresLt ( lTLhs , precisionCall , 0 , block , true )
85
- ) and
86
- /*
87
- * Shift statement is not at a basic block where
88
- * `shift_rhs < 0` is ensured
89
- */
90
-
91
- not exists ( GuardCondition gc , BasicBlock block , Expr literalZero , Expr lTLhs |
92
- block = shift .getBasicBlock ( ) and
93
- literalZero instanceof LiteralZero
94
- |
95
- globalValueNumber ( lTLhs ) = globalValueNumber ( shift .getRightOperand ( ) ) and
96
- gc .ensuresLt ( lTLhs , literalZero , 0 , block , true )
97
- )
98
- )
99
- }
100
-
101
- from BinaryBitwiseOperation badShift , string message
102
- where
103
- not isExcluded ( badShift , Types1Package:: exprShiftedbyNegativeOrGreaterPrecisionOperandQuery ( ) ) and
104
- isForbiddenShiftExpr ( badShift , message )
105
- select badShift , message
20
+ from ShiftByNegativeOrGreaterPrecisionOperand badShift
21
+ where not isExcluded ( badShift , Types1Package:: exprShiftedbyNegativeOrGreaterPrecisionOperandQuery ( ) )
22
+ select badShift , badShift .getReason ( )
0 commit comments