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 ( SizeofOperator so |
19- so .( SizeofTypeOperator ) .getTypeOperand ( ) .getUnspecifiedType ( ) = s or
20- so .( SizeofExprOperator ) .getExprOperand ( ) .getType ( ) .getUnspecifiedType ( ) = s |
21- // Check all ancestor nodes except the immediate parent for
22- // allocations.
23- isStdLibAllocationExpr ( so .getParent ( ) .( Expr ) .getParent + ( ) )
24- )
25- }
26-
273/**
284 * Holds if `v` is a member variable of `c` that looks like it might be variable sized in practice. For
295 * example:
@@ -34,15 +10,38 @@ private predicate isDynamicallyAllocatedWithDifferentSize(Class s) {
3410 * };
3511 * ```
3612 * This requires that `v` is an array of size 0 or 1, and `v` is the last member of `c`. In addition,
37- * 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+ * ```
3822 */
3923predicate memberMayBeVarSize ( Class c , MemberVariable v ) {
4024 exists ( int i |
25+ // `v` is the last field in `c`
4126 i = max ( int j | c .getCanonicalMember ( j ) instanceof Field | j ) and
4227 v = c .getCanonicalMember ( i ) and
28+
29+ // v is an array of size at most 1
4330 v .getType ( ) .getUnspecifiedType ( ) .( ArrayType ) .getSize ( ) <= 1
44- ) and
45- isDynamicallyAllocatedWithDifferentSize ( c )
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+ // Check all ancestor nodes except the immediate parent for
37+ // allocations.
38+ isStdLibAllocationExpr ( so .getParent ( ) .( Expr ) .getParent + ( ) )
39+ ) or exists ( AddressOfExpr aoe |
40+ // `&(c.v)` is taken
41+ aoe .getAddressable ( ) = v and
42+ isStdLibAllocationExpr ( aoe .getParent ( ) .( Expr ) .getParent + ( ) )
43+ )
44+ )
4645}
4746
4847/**
0 commit comments