diff --git a/clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp --- a/clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp @@ -178,7 +178,7 @@ 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 --- a/clang/test/Analysis/valist-uninitialized-no-undef.c +++ b/clang/test/Analysis/valist-uninitialized-no-undef.c @@ -16,11 +16,20 @@ 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;