diff --git a/clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp index 2ce95a9d47685..fbefd5f9ffdc9 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp @@ -178,7 +178,7 @@ const MemRegion *ValistChecker::getVAListAsRegion(SVal SV, const Expr *E, if (isa(DeclReg->getDecl())) Reg = C.getState()->getSVal(SV.castAs()).getAsRegion(); } - IsSymbolic = Reg && Reg->getAs(); + IsSymbolic = Reg && Reg->getBaseRegion()->getAs(); // Some VarRegion based VA lists reach here as ElementRegions. const auto *EReg = dyn_cast_or_null(Reg); return (EReg && VaListModelledAsArray) ? EReg->getSuperRegion() : Reg; diff --git a/clang/test/Analysis/valist-uninitialized-no-undef.c b/clang/test/Analysis/valist-uninitialized-no-undef.c index 528ac86c14213..6d6542a6acf99 100644 --- a/clang/test/Analysis/valist-uninitialized-no-undef.c +++ b/clang/test/Analysis/valist-uninitialized-no-undef.c @@ -16,11 +16,20 @@ void call_inlined_uses_arg(int fst, ...) { void f6(va_list *fst, ...) { va_start(*fst, fst); - // FIXME: There should be no warning for this. - (void)va_arg(*fst, int); // expected-warning{{va_arg() is called on an uninitialized va_list}} - // expected-note@-1{{va_arg() is called on an uninitialized va_list}} + (void)va_arg(*fst, int); va_end(*fst); -} +} + +int va_list_get_int(va_list *va) { + return va_arg(*va, int); // no-warning +} + +struct MyVaList { + va_list l; +}; +int va_list_get_int2(struct MyVaList *va) { + return va_arg(va->l, int); // no-warning +} void call_vprintf_bad(int isstring, ...) { va_list va;