@@ -10,6 +10,44 @@ private string getConstExprValue(Variable v) {
1010 v .isConstexpr ( )
1111}
1212
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+
1351/** Gets a "use" count according to rule M0-1-4. */
1452int getUseCount ( Variable v ) {
1553 // 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) {
2361 // of the variable
2462 count ( ClassTemplateInstantiation cti |
2563 cti .getTemplateArgument ( _) .( Expr ) .getValue ( ) = getConstExprValue ( v )
26- )
64+ ) + count ( getIndirectSubObjectAssignedValue ( v ) )
2765}
2866
2967Expr getAUserInitializedValue ( Variable v ) {
0 commit comments