11import cpp
22
3- /**
4- * Holds if `sizeof(s)` occurs as part of the parameter of a dynamic
5- * memory allocation (`malloc`, `realloc`, etc.), except if `sizeof(s)`
6- * only ever occurs as the immediate parameter to allocations.
7- *
8- * For example, holds for `s` if it occurs as
9- * ```
10- * malloc(sizeof(s) + 100 * sizeof(char))
11- * ```
12- * but not if it only ever occurs as
13- * ```
14- * malloc(sizeof(s))
15- * ```
16- */
17- private predicate isDynamicallyAllocatedWithDifferentSize ( Class s ) {
18- exists ( SizeofTypeOperator sof |
19- sof .getTypeOperand ( ) .getUnspecifiedType ( ) = s |
20- // Check all ancestor nodes except the immediate parent for
21- // allocations.
22- isStdLibAllocationExpr ( sof .getParent ( ) .( Expr ) .getParent + ( ) )
23- )
24- }
25-
263/**
274 * Holds if `v` is a member variable of `c` that looks like it might be variable sized in practice. For
285 * example:
@@ -33,15 +10,40 @@ private predicate isDynamicallyAllocatedWithDifferentSize(Class s) {
3310 * };
3411 * ```
3512 * This requires that `v` is an array of size 0 or 1, and `v` is the last member of `c`. In addition,
36- * there must be at least one instance where a `c` pointer is allocated with additional space.
13+ * there must be at least one instance where a `c` pointer is allocated with additional space. For
14+ * example, holds for `c` if it occurs as
15+ * ```
16+ * malloc(sizeof(c) + 100 * sizeof(char))
17+ * ```
18+ * but not if it only ever occurs as
19+ * ```
20+ * malloc(sizeof(c))
21+ * ```
3722 */
3823predicate memberMayBeVarSize ( Class c , MemberVariable v ) {
3924 exists ( int i |
25+ // `v` is the last field in `c`
4026 i = max ( int j | c .getCanonicalMember ( j ) instanceof Field | j ) and
4127 v = c .getCanonicalMember ( i ) and
42- v .getType ( ) .getUnspecifiedType ( ) .( ArrayType ) .getSize ( ) <= 1
43- ) and
44- isDynamicallyAllocatedWithDifferentSize ( c )
28+
29+ // v is an array of size at most 1
30+ v .getType ( ) .getUnspecifiedType ( ) .( ArrayType ) .getArraySize ( ) <= 1
31+ ) and (
32+ exists ( SizeofOperator so |
33+ // `sizeof(c)` is taken
34+ so .( SizeofTypeOperator ) .getTypeOperand ( ) .getUnspecifiedType ( ) = c or
35+ so .( SizeofExprOperator ) .getExprOperand ( ) .getType ( ) .getUnspecifiedType ( ) = c |
36+
37+ // arithmetic is performed on the result
38+ so .getParent * ( ) instanceof AddExpr
39+ ) or exists ( AddressOfExpr aoe |
40+ // `&(c.v)` is taken
41+ aoe .getAddressable ( ) = v
42+ ) or exists ( BuiltInOperationOffsetOf oo |
43+ // `offsetof(c, v)` using a builtin
44+ oo .getAChild ( ) .( VariableAccess ) .getTarget ( ) = v
45+ )
46+ )
4547}
4648
4749/**
0 commit comments