diff --git a/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp index 7cc146ed29d0d..cd24b1e816e01 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp @@ -183,8 +183,6 @@ bool CallAndMessageChecker::uninitRefOrPointer( CheckerContext &C, SVal V, SourceRange ArgRange, const Expr *ArgEx, const BugType &BT, const ParmVarDecl *ParamDecl, int ArgumentNumber) const { - // The pointee being uninitialized is a sign of code smell, not a bug, no need - // to sink here. if (!ChecksEnabled[CK_ArgPointeeInitializedness]) return false; @@ -212,8 +210,14 @@ bool CallAndMessageChecker::uninitRefOrPointer( if (const MemRegion *SValMemRegion = V.getAsRegion()) { const ProgramStateRef State = C.getState(); - const SVal PSV = State->getSVal(SValMemRegion, C.getASTContext().CharTy); - if (PSV.isUndef()) { + QualType T = ParamDecl->getType()->getPointeeType(); + if (T->isVoidType()) + T = C.getASTContext().CharTy; + const SVal PSV = State->getSVal(SValMemRegion, T); + bool IsUndef = PSV.isUndef(); + if (auto LCV = PSV.getAs()) + IsUndef = LCV->getStore() == nullptr; + if (IsUndef) { if (ExplodedNode *N = C.generateErrorNode()) { auto R = std::make_unique(BT, Os.str(), N); R->addRange(ArgRange); diff --git a/clang/test/Analysis/PR40625.cpp b/clang/test/Analysis/PR40625.cpp index 5ebe2122945e6..ab3faa328298a 100644 --- a/clang/test/Analysis/PR40625.cpp +++ b/clang/test/Analysis/PR40625.cpp @@ -5,11 +5,11 @@ void f(const int *end); void g(const int (&arrr)[10]) { - f(arrr); // expected-warning{{1st function call argument is a pointer to uninitialized value}} + f(arrr); } void h() { int arr[10]; - g(arr); + g(arr); // expected-warning{{1st function call argument is an uninitialized value}} } diff --git a/clang/test/Analysis/call-and-message.c b/clang/test/Analysis/call-and-message.c index ade51145e2a93..fdac77176569b 100644 --- a/clang/test/Analysis/call-and-message.c +++ b/clang/test/Analysis/call-and-message.c @@ -24,6 +24,18 @@ void pointee_uninit(void) { doStuff_pointerToConstInt(p); // expected-warning{{1st function call argument is a pointer to uninitialized value [core.CallAndMessage]}} } +typedef struct S { + int a; + short b; +} S; + +void doStuff_pointerToConstStruct(const S *s){}; +void pointee_uninit_struct(void) { + S s; + S *p = &s; + doStuff_pointerToConstStruct(p); // expected-warning{{1st function call argument is a pointer to uninitialized value [core.CallAndMessage]}} +} + // TODO: If this hash ever changes, turn // core.CallAndMessage:ArgPointeeInitializedness from a checker option into a // checker, as described in the CallAndMessage comments!