Description
The following snippet causes the Static Analyzer to fail an assertion in debug mode, or crash in release mode.
struct S {
static int a;
~S(){};
};
int S::a = 0;
void foo() {
S::a = 0;
int x = 3;
memset(&x, 1, sizeof(x));
S *arr = new S[x];
delete[] arr;
clang_analyzer_explain(S::a);
}
memset
sets the value of S::a
to derived_$12{conj_$8{int, LC1, no stmt, #1},a}
, and later when clang_analyzer_explain()
tries to explain the value, it encounters a nullptr
which it dereferences.
conj_$8{int, LC1, no stmt, #1}
doesn't contain any statement, so when SValExplainer::VisitSymbolConjured()
calls SValExplainer::printStmt(const Stmt *S)
it passes a nullptr
to it as an argument. The called function assumes it always receives a valid pointer, and it simply calls S->printPretty()
without any validation, and this is when the crash happens.
For more information please see godbolt.