Commit ee2ef75
committed
Fix RULE-0-2-4/A0-1-3 false positives for private functions
Two categories of false positive are addressed:
1. **Private pure virtual functions used via the NVI idiom** —
`DynamicCallGraph::getTarget()` resolves a virtual call to the
implementations that may actually *run*. A pure virtual function
(`= 0`) has no body, so it is never a viable dispatch target and is
therefore never returned by `getTarget()` — not even when it is
unambiguously named by a call, as in the non-virtual interface (NVI)
idiom where a public member calls a private pure virtual. It was
consequently reported as unused even though a sibling member calls
it. `functionIsCalled` now also counts the *statically named* callee
(`FunctionCall.getTarget()`), which recovers exactly that case.
This is deliberately narrower than excluding `PureVirtualFunction`
from `LocalFunction` outright: a private pure virtual that is
genuinely never called and never overridden is still reported.
2. **Private members of never-instantiated class templates** — when a
class template is never instantiated with a concrete type anywhere
in the analyzed compilation units, Clang never elaborates a body for
its member functions, so `Call`/`FunctionCall` targets within that
pattern's own text cannot be resolved by
`DynamicCallGraph::getTarget()` or `VirtualDispatch`, even for calls
between sibling members of the very same class (e.g. a public entry
point calling a private helper). This is common for generic
"plumbing" library code (CRTP-style wrappers and the like) that is
only ever instantiated by downstream consumers outside the analyzed
codebase. The new `hasNoVisibleInstantiation(fn)` predicate
conservatively treats such private members as "used" (out of scope
for this analysis) rather than reporting them as dead code — but
only when *no* sibling member of the same class has any
instantiation either, so genuinely dead private helpers in class
templates that *are* instantiated elsewhere are still correctly
reported.
The sibling-instantiation check is factored into a `pragma[noinline]`
predicate over the declaring `Class` rather than over the member
`Function`. Inlined into the caller, the join orderer loses the fact
that the class is functionally determined and materialises the full
(member, sibling) cross product per class before projecting it away.
On a large real-world database this cut the peak intermediate relation
for that predicate from 4,831,818 tuples to 7,700 with identical
results.
Fixes #11681 parent 62bf905 commit ee2ef75
4 files changed
Lines changed: 175 additions & 3 deletions
File tree
- change_notes
- cpp/common
- src/codingstandards/cpp/rules/unusedlocalfunction
- test/rules/unusedlocalfunction
Lines changed: 16 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
Lines changed: 78 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
23 | 43 | | |
24 | 44 | | |
25 | 45 | | |
26 | 46 | | |
27 | 47 | | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
28 | 101 | | |
29 | 102 | | |
30 | 103 | | |
| |||
74 | 147 | | |
75 | 148 | | |
76 | 149 | | |
77 | | - | |
| 150 | + | |
78 | 151 | | |
79 | 152 | | |
80 | 153 | | |
| |||
88 | 161 | | |
89 | 162 | | |
90 | 163 | | |
91 | | - | |
| 164 | + | |
92 | 165 | | |
93 | 166 | | |
94 | 167 | | |
| |||
100 | 173 | | |
101 | 174 | | |
102 | 175 | | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
103 | 179 | | |
104 | 180 | | |
105 | 181 | | |
| |||
Lines changed: 2 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
| 9 | + | |
| 10 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
157 | 157 | | |
158 | 158 | | |
159 | 159 | | |
160 | | - | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
0 commit comments