[clang] [analyzer] Trust base to derived casts for dynamic types (PR #69057)
Balazs Benics via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 6 10:22:43 PST 2024
steakhal wrote:
> > However, what should we do if multiple (N) classes implement Base? Trying each N, and basically splitting the state to (N+1) ways is not going to scale. Unless N is of course really small, like 2 or 3 at most.
>
> That's kind of what I imagined - try them all. The Analyzer has a built-in timeout mechanism that will come into play.
>
> If you wanted to be fancy, there could be an obscure config option, with a default of N=3. If config value is not set, and N>3 it asserts, alerting the user to the situation. If config value is set, it limits to analyzing the first N.
I re-read the thread, and I think the most promising approach would be to to split the path N ways to see the outcome.
An alternative workaround would be to somehow annotate the code to force it to split into N ways and then inject a static cast to each way doing the relevant base->derived cast that this PR already instrument and do the desired behavior.
Something like this:
```c++
template <class U, class T> void clang_analyzer_try_cast(const T *base) {
extern bool analyzer_internal_coin();
if (analyzer_internal_coin())
(void)static_cast<const U*>(base);
}
template <class... Ts, class T>
void clang_analyzer_split_n_ways(const T *base) {
static_assert(sizeof...(Ts) > 0);
(clang_analyzer_try_cast<Ts>(base), ...);
}
struct Base {};
struct A : Base {};
struct B : Base {};
struct C : Base {};
void test(const Base *p) {
clang_analyzer_split_n_ways<A, B, C>(p); // <--- This is how the no-op static casts would split into A, B, C.
// We should have like 3 paths here, plus the conservatively eval called path.
}
https://github.com/llvm/llvm-project/pull/69057
More information about the cfe-commits
mailing list