11import semmle.code.cpp.Type
22
3+ /** For upgraded databases without mangled name info. */
34pragma [ noinline]
45private string getTopLevelClassName ( @usertype c ) {
6+ not mangled_name ( _, _) and
57 isClass ( c ) and
68 usertypes ( c , result , _) and
79 not namespacembrs ( _, c ) and // not in a namespace
810 not member ( _, _, c ) and // not in some structure
911 not class_instantiation ( c , _) // not a template instantiation
1012}
1113
12- /** Holds if `d` is a unique complete class named `name`. */
14+ /**
15+ * For upgraded databases without mangled name info.
16+ * Holds if `d` is a unique complete class named `name`.
17+ */
1318pragma [ noinline]
1419private predicate existsCompleteWithName ( string name , @usertype d ) {
20+ not mangled_name ( _, _) and
1521 is_complete ( d ) and
1622 name = getTopLevelClassName ( d ) and
1723 onlyOneCompleteClassExistsWithName ( name )
1824}
1925
26+ /** For upgraded databases without mangled name info. */
2027pragma [ noinline]
2128private predicate onlyOneCompleteClassExistsWithName ( string name ) {
29+ not mangled_name ( _, _) and
2230 strictcount ( @usertype c | is_complete ( c ) and getTopLevelClassName ( c ) = name ) = 1
2331}
2432
25- /** Holds if `c` is an incomplete class named `name`. */
33+ /**
34+ * For upgraded databases without mangled name info.
35+ * Holds if `c` is an incomplete class named `name`.
36+ */
2637pragma [ noinline]
2738private predicate existsIncompleteWithName ( string name , @usertype c ) {
39+ not mangled_name ( _, _) and
2840 not is_complete ( c ) and
2941 name = getTopLevelClassName ( c )
3042}
3143
3244/**
45+ * For upgraded databases without mangled name info.
3346 * Holds if `c` is an incomplete class, and there exists a unique complete class `d`
3447 * with the same name.
3548 */
36- private predicate hasCompleteTwin ( @usertype c , @usertype d ) {
49+ private predicate oldHasCompleteTwin ( @usertype c , @usertype d ) {
50+ not mangled_name ( _, _) and
3751 exists ( string name |
3852 existsIncompleteWithName ( name , c ) and
3953 existsCompleteWithName ( name , d )
4054 )
4155}
4256
57+ pragma [ noinline]
58+ private @mangledname getTopLevelClassMangledName ( @usertype c ) {
59+ isClass ( c ) and
60+ mangled_name ( c , result ) and
61+ not namespacembrs ( _, c ) and // not in a namespace
62+ not member ( _, _, c ) and // not in some structure
63+ not class_instantiation ( c , _) // not a template instantiation
64+ }
65+
66+ /** Holds if `d` is a unique complete class named `name`. */
67+ pragma [ noinline]
68+ private predicate existsCompleteWithMangledName ( @mangledname name , @usertype d ) {
69+ is_complete ( d ) and
70+ name = getTopLevelClassMangledName ( d ) and
71+ onlyOneCompleteClassExistsWithMangledName ( name )
72+ }
73+
74+ pragma [ noinline]
75+ private predicate onlyOneCompleteClassExistsWithMangledName ( @mangledname name ) {
76+ strictcount ( @usertype c | is_complete ( c ) and getTopLevelClassMangledName ( c ) = name ) = 1
77+ }
78+
79+ /** Holds if `c` is an incomplete class named `name`. */
80+ pragma [ noinline]
81+ private predicate existsIncompleteWithMangledName ( @mangledname name , @usertype c ) {
82+ not is_complete ( c ) and
83+ name = getTopLevelClassMangledName ( c )
84+ }
85+
86+ /**
87+ * Holds if `c` is an incomplete class, and there exists a unique complete class `d`
88+ * with the same name.
89+ */
90+ private predicate hasCompleteTwin ( @usertype c , @usertype d ) {
91+ exists ( @mangledname name |
92+ existsIncompleteWithMangledName ( name , c ) and
93+ existsCompleteWithMangledName ( name , d )
94+ )
95+ }
96+
4397import Cached
4498cached private module Cached {
4599 /**
@@ -49,7 +103,11 @@ cached private module Cached {
49103 cached @usertype resolveClass ( @usertype c ) {
50104 hasCompleteTwin ( c , result )
51105 or
52- ( not hasCompleteTwin ( c , _) and result = c )
106+ oldHasCompleteTwin ( c , result )
107+ or
108+ ( not hasCompleteTwin ( c , _) and
109+ not oldHasCompleteTwin ( c , _) and
110+ result = c )
53111 }
54112
55113 /**
0 commit comments