@@ -10,6 +10,44 @@ private string getConstExprValue(Variable v) {
10
10
v .isConstexpr ( )
11
11
}
12
12
13
+ /**
14
+ * Gets the number of uses of variable `v` in an opaque assignment, where an opaqua assignment for example a cast from one type to the other and `v` is assumed to be a member of the resulting type.
15
+ * e.g.,
16
+ * struct foo {
17
+ * int bar;
18
+ * }
19
+ *
20
+ * struct foo * v = (struct foo*)buffer;
21
+ */
22
+ Expr getIndirectSubObjectAssignedValue ( MemberVariable subobject ) {
23
+ // struct foo * ptr = (struct foo*)buffer;
24
+ exists ( Struct someStruct , Variable instanceOfSomeStruct | someStruct .getAMember ( ) = subobject |
25
+ instanceOfSomeStruct .getType ( ) .( PointerType ) .getBaseType ( ) = someStruct and
26
+ exists ( Cast assignedValue |
27
+ // Exclude cases like struct foo * v = nullptr;
28
+ not assignedValue .isImplicit ( ) and
29
+ // `v` is a subobject of another type that reinterprets another object. We count that as a use of `v`.
30
+ assignedValue .getExpr ( ) = instanceOfSomeStruct .getAnAssignedValue ( ) and
31
+ result = assignedValue
32
+ )
33
+ or
34
+ // struct foo; read(..., (char *)&foo);
35
+ instanceOfSomeStruct .getType ( ) = someStruct and
36
+ exists ( Call externalInitializerCall , Cast castToCharPointer , int n |
37
+ externalInitializerCall .getArgument ( n ) .( AddressOfExpr ) .getOperand ( ) =
38
+ instanceOfSomeStruct .getAnAccess ( ) and
39
+ externalInitializerCall .getArgument ( n ) = castToCharPointer .getExpr ( ) and
40
+ castToCharPointer .getType ( ) .( PointerType ) .getBaseType ( ) .getUnspecifiedType ( ) instanceof
41
+ CharType and
42
+ result = externalInitializerCall
43
+ )
44
+ or
45
+ // the object this subject is part of is initialized and we assumes this initializes the subobject.
46
+ instanceOfSomeStruct .getType ( ) = someStruct and
47
+ result = instanceOfSomeStruct .getInitializer ( ) .getExpr ( )
48
+ )
49
+ }
50
+
13
51
/** Gets a "use" count according to rule M0-1-4. */
14
52
int getUseCount ( Variable v ) {
15
53
// We enforce that it's a POD type variable, so if it has an initializer it is explicit
@@ -23,7 +61,7 @@ int getUseCount(Variable v) {
23
61
// of the variable
24
62
count ( ClassTemplateInstantiation cti |
25
63
cti .getTemplateArgument ( _) .( Expr ) .getValue ( ) = getConstExprValue ( v )
26
- )
64
+ ) + count ( getIndirectSubObjectAssignedValue ( v ) )
27
65
}
28
66
29
67
Expr getAUserInitializedValue ( Variable v ) {
0 commit comments