Unrelated errors introduce additional runtime diagnostics by skipping CFG construction
#58.276 aberto em 10 de out. de 2022
Métricas do repositório
- Stars
- (26.378 stars)
- Métricas de merge de PR
- (Mesclagem média 1d 2h) (1.000 fundiu PRs em 30d)
Description
Consider: https://gcc.godbolt.org/z/dq6q8xxhY
#include <string.h>
struct Foo {
virtual ~Foo();
int x;
};
#error
constexpr bool alwaysFalse = false;
void maywarn(Foo *p) {
if constexpr (alwaysFalse) {
memset(p, 0, sizeof(*p));
}
if (alwaysFalse) {
memset(p, 0, sizeof(*p)); // warns
}
}
This produces this -Wdynamic-class-memaccess warning:
<source>:15:16: warning: destination for this 'memset' call is a pointer to dynamic class 'Foo'; vtable pointer will be overwritten [-Wdynamic-class-memaccess]
memset(p, 0, sizeof(*p));
~~~~~~ ^
<source>:15:16: note: explicitly cast the pointer to silence this warning
memset(p, 0, sizeof(*p));
^
(void*)
This goes away if you remove the #error.
This causes issues because this latent warning can be present in header files in a warning-clean codebase, and it only appears when developers later introduce an error. The extra warning can obscure the actual problem because, with -Werror, developers end up seeing two errors.
These two conditionals prevent Clang from doing CFG-based warnings in the presence of errors:
- https://github.com/llvm/llvm-project/blob/main/clang/lib/Sema/Sema.cpp#L2224
- https://github.com/llvm/llvm-project/blob/main/clang/lib/Sema/AnalysisBasedWarnings.cpp#L2227
To fix the bug, we need to modify those conditionals to either:
- Always construct a CFG for analysis even in the presence of errors
- Don't issue any diagnostics about possibly unreachable code in the presence of other errors
I've prototyped both changes, and they break a lot of Clang tests, and I'm filing this issue to track followup.