[clang] a80c393 - [analyzer] Consolidate the va_list checkers (#156682)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 8 04:16:28 PDT 2025
Author: DonĂ¡t Nagy
Date: 2025-09-08T13:16:24+02:00
New Revision: a80c393a9c498279a1ec9fd630535b9ff139b49f
URL: https://github.com/llvm/llvm-project/commit/a80c393a9c498279a1ec9fd630535b9ff139b49f
DIFF: https://github.com/llvm/llvm-project/commit/a80c393a9c498279a1ec9fd630535b9ff139b49f.diff
LOG: [analyzer] Consolidate the va_list checkers (#156682)
Previously the analyzer had an undocumented top-level checker group
called `valist` which offered several checkers to detect use of
uninitialized `va_list` objects and leaks of `va_list`s.
As the responsibilities of these checkers were messily intertwined and
`va_list` is a rarely used language feature, this commit simplifies the
situation by consolidating these checkers into a single checker which
will be called `security.VAList`.
Note that I'm choosing the capitalization `VAList` to be consistent with
the example of the AST node type `VAArgExpr`. I updated many variable
names to ensure that `ValistChecker.cpp` uses this spelling everywhere
(in CamelCased names). I'm planning to rename `ValistChecker.cpp` to
`VAListChecker.cpp` in a follow-up commit.
This commit also adds documentation for this checker in checkers.rst.
Among the test files I preserved the existing separation but I
eliminated some duplicated cases now that there is no way to separately
enable the old sub-checkers.
For the background of this change see also the discourse thread
https://discourse.llvm.org/t/clean-up-valist-checkers/85277/3
Added:
Modified:
clang/docs/analyzer/checkers.rst
clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp
clang/test/Analysis/valist-as-lazycompound.c
clang/test/Analysis/valist-uninitialized-no-undef.c
clang/test/Analysis/valist-uninitialized.c
clang/test/Analysis/valist-unterminated.c
Removed:
################################################################################
diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst
index 9350def672a6d..76bd80b82a4d6 100644
--- a/clang/docs/analyzer/checkers.rst
+++ b/clang/docs/analyzer/checkers.rst
@@ -1859,6 +1859,32 @@ this) and always check the return value of these calls.
This check corresponds to SEI CERT Rule `POS36-C <https://wiki.sei.cmu.edu/confluence/display/c/POS36-C.+Observe+correct+revocation+order+while+relinquishing+privileges>`_.
+.. _security-VAList:
+
+security.VAList (C, C++)
+""""""""""""""""""""""""
+Reports use of uninitialized (or already released) ``va_list`` objects and
+situations where a ``va_start`` call is not followed by ``va_end``.
+
+Report out of bounds access to memory that is before the start or after the end
+of the accessed region (array, heap-allocated region, string literal etc.).
+This usually means incorrect indexing, but the checker also detects access via
+the operators ``*`` and ``->``.
+
+.. code-block:: c
+
+ int test_use_after_release(int x, ...) {
+ va_list va;
+ va_start(va, x);
+ va_end(va);
+ return va_arg(va, int); // warn: va is uninitialized
+ }
+
+ void test_leak(int x, ...) {
+ va_list va;
+ va_start(va, x);
+ } // warn: va is leaked
+
.. _unix-checkers:
unix
diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
index c6c856bf7a773..a1f5bdfb9edf1 100644
--- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
+++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
@@ -64,8 +64,6 @@ def Cplusplus : Package<"cplusplus">;
def CplusplusAlpha : Package<"cplusplus">, ParentPackage<Alpha>;
def CplusplusOptIn : Package<"cplusplus">, ParentPackage<OptIn>;
-def Valist : Package<"valist">;
-
def DeadCode : Package<"deadcode">;
def DeadCodeAlpha : Package<"deadcode">, ParentPackage<Alpha>;
@@ -779,35 +777,6 @@ def SmartPtrChecker: Checker<"SmartPtr">,
} // end: "alpha.cplusplus"
-
-//===----------------------------------------------------------------------===//
-// Valist checkers.
-//===----------------------------------------------------------------------===//
-
-let ParentPackage = Valist in {
-
-def ValistBase : Checker<"ValistBase">,
- HelpText<"Gathers information about va_lists.">,
- Documentation<NotDocumented>,
- Hidden;
-
-def UninitializedChecker : Checker<"Uninitialized">,
- HelpText<"Check for usages of uninitialized (or already released) va_lists.">,
- Dependencies<[ValistBase]>,
- Documentation<NotDocumented>;
-
-def UnterminatedChecker : Checker<"Unterminated">,
- HelpText<"Check for va_lists which are not released by a va_end call.">,
- Dependencies<[ValistBase]>,
- Documentation<NotDocumented>;
-
-def CopyToSelfChecker : Checker<"CopyToSelf">,
- HelpText<"Check for va_lists which are copied onto itself.">,
- Dependencies<[ValistBase]>,
- Documentation<NotDocumented>;
-
-} // end : "valist"
-
//===----------------------------------------------------------------------===//
// Deadcode checkers.
//===----------------------------------------------------------------------===//
@@ -982,6 +951,10 @@ let ParentPackage = Security in {
"'setuid(getuid())' (CERT: POS36-C)">,
Documentation<HasDocumentation>;
+ def VAListChecker : Checker<"VAList">,
+ HelpText<"Warn on misuse of va_list objects">,
+ Documentation<HasDocumentation>;
+
} // end "security"
let ParentPackage = ENV in {
diff --git a/clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp
index bd2f88c7b1bcc..2355abdaa060c 100644
--- a/clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp
@@ -27,28 +27,21 @@ REGISTER_SET_WITH_PROGRAMSTATE(InitializedVALists, const MemRegion *)
namespace {
typedef SmallVector<const MemRegion *, 2> RegionVector;
-class ValistChecker : public Checker<check::PreCall, check::PreStmt<VAArgExpr>,
+class VAListChecker : public Checker<check::PreCall, check::PreStmt<VAArgExpr>,
check::DeadSymbols> {
- mutable std::unique_ptr<BugType> BT_leakedvalist, BT_uninitaccess;
+ const BugType LeakBug{this, "Leaked va_list", categories::MemoryError,
+ /*SuppressOnSink=*/true};
+ const BugType UninitAccessBug{this, "Uninitialized va_list",
+ categories::MemoryError};
struct VAListAccepter {
CallDescription Func;
- int VAListPos;
+ int ParamIndex;
};
static const SmallVector<VAListAccepter, 15> VAListAccepters;
static const CallDescription VaStart, VaEnd, VaCopy;
public:
- enum CheckKind {
- CK_Uninitialized,
- CK_Unterminated,
- CK_CopyToSelf,
- CK_NumCheckKinds
- };
-
- bool ChecksEnabled[CK_NumCheckKinds] = {false};
- CheckerNameRef CheckNames[CK_NumCheckKinds];
-
void checkPreStmt(const VAArgExpr *VAA, CheckerContext &C) const;
void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const;
@@ -61,17 +54,16 @@ class ValistChecker : public Checker<check::PreCall, check::PreStmt<VAArgExpr>,
void reportUninitializedAccess(const MemRegion *VAList, StringRef Msg,
CheckerContext &C) const;
- void reportLeakedVALists(const RegionVector &LeakedVALists, StringRef Msg1,
- StringRef Msg2, CheckerContext &C, ExplodedNode *N,
- bool ReportUninit = false) const;
+ void reportLeaked(const RegionVector &Leaked, StringRef Msg1, StringRef Msg2,
+ CheckerContext &C, ExplodedNode *N) const;
void checkVAListStartCall(const CallEvent &Call, CheckerContext &C,
bool IsCopy) const;
void checkVAListEndCall(const CallEvent &Call, CheckerContext &C) const;
- class ValistBugVisitor : public BugReporterVisitor {
+ class VAListBugVisitor : public BugReporterVisitor {
public:
- ValistBugVisitor(const MemRegion *Reg, bool IsLeak = false)
+ VAListBugVisitor(const MemRegion *Reg, bool IsLeak = false)
: Reg(Reg), IsLeak(IsLeak) {}
void Profile(llvm::FoldingSetNodeID &ID) const override {
static int X = 0;
@@ -99,8 +91,8 @@ class ValistChecker : public Checker<check::PreCall, check::PreStmt<VAArgExpr>,
};
};
-const SmallVector<ValistChecker::VAListAccepter, 15>
- ValistChecker::VAListAccepters = {{{CDM::CLibrary, {"vfprintf"}, 3}, 2},
+const SmallVector<VAListChecker::VAListAccepter, 15>
+ VAListChecker::VAListAccepters = {{{CDM::CLibrary, {"vfprintf"}, 3}, 2},
{{CDM::CLibrary, {"vfscanf"}, 3}, 2},
{{CDM::CLibrary, {"vprintf"}, 2}, 1},
{{CDM::CLibrary, {"vscanf"}, 2}, 1},
@@ -116,14 +108,14 @@ const SmallVector<ValistChecker::VAListAccepter, 15>
// vsnprintf, vsprintf has no wide version
{{CDM::CLibrary, {"vswscanf"}, 3}, 2}};
-const CallDescription ValistChecker::VaStart(CDM::CLibrary,
+const CallDescription VAListChecker::VaStart(CDM::CLibrary,
{"__builtin_va_start"}, /*Args=*/2,
/*Params=*/1),
- ValistChecker::VaCopy(CDM::CLibrary, {"__builtin_va_copy"}, 2),
- ValistChecker::VaEnd(CDM::CLibrary, {"__builtin_va_end"}, 1);
+ VAListChecker::VaCopy(CDM::CLibrary, {"__builtin_va_copy"}, 2),
+ VAListChecker::VaEnd(CDM::CLibrary, {"__builtin_va_end"}, 1);
} // end anonymous namespace
-void ValistChecker::checkPreCall(const CallEvent &Call,
+void VAListChecker::checkPreCall(const CallEvent &Call,
CheckerContext &C) const {
if (VaStart.matches(Call))
checkVAListStartCall(Call, C, false);
@@ -137,8 +129,8 @@ void ValistChecker::checkPreCall(const CallEvent &Call,
continue;
bool Symbolic;
const MemRegion *VAList =
- getVAListAsRegion(Call.getArgSVal(FuncInfo.VAListPos),
- Call.getArgExpr(FuncInfo.VAListPos), Symbolic, C);
+ getVAListAsRegion(Call.getArgSVal(FuncInfo.ParamIndex),
+ Call.getArgExpr(FuncInfo.ParamIndex), Symbolic, C);
if (!VAList)
return;
@@ -159,17 +151,17 @@ void ValistChecker::checkPreCall(const CallEvent &Call,
}
}
-const MemRegion *ValistChecker::getVAListAsRegion(SVal SV, const Expr *E,
+const MemRegion *VAListChecker::getVAListAsRegion(SVal SV, const Expr *E,
bool &IsSymbolic,
CheckerContext &C) const {
const MemRegion *Reg = SV.getAsRegion();
if (!Reg)
return nullptr;
// TODO: In the future this should be abstracted away by the analyzer.
- bool VaListModelledAsArray = false;
+ bool VAListModelledAsArray = false;
if (const auto *Cast = dyn_cast<CastExpr>(E)) {
QualType Ty = Cast->getType();
- VaListModelledAsArray =
+ VAListModelledAsArray =
Ty->isPointerType() && Ty->getPointeeType()->isRecordType();
}
if (const auto *DeclReg = Reg->getAs<DeclRegion>()) {
@@ -179,17 +171,16 @@ const MemRegion *ValistChecker::getVAListAsRegion(SVal SV, const Expr *E,
IsSymbolic = Reg && Reg->getBaseRegion()->getAs<SymbolicRegion>();
// Some VarRegion based VA lists reach here as ElementRegions.
const auto *EReg = dyn_cast_or_null<ElementRegion>(Reg);
- return (EReg && VaListModelledAsArray) ? EReg->getSuperRegion() : Reg;
+ return (EReg && VAListModelledAsArray) ? EReg->getSuperRegion() : Reg;
}
-void ValistChecker::checkPreStmt(const VAArgExpr *VAA,
+void VAListChecker::checkPreStmt(const VAArgExpr *VAA,
CheckerContext &C) const {
ProgramStateRef State = C.getState();
- const Expr *VASubExpr = VAA->getSubExpr();
- SVal VAListSVal = C.getSVal(VASubExpr);
+ const Expr *ArgExpr = VAA->getSubExpr();
+ SVal VAListSVal = C.getSVal(ArgExpr);
bool Symbolic;
- const MemRegion *VAList =
- getVAListAsRegion(VAListSVal, VASubExpr, Symbolic, C);
+ const MemRegion *VAList = getVAListAsRegion(VAListSVal, ArgExpr, Symbolic, C);
if (!VAList)
return;
if (Symbolic)
@@ -199,20 +190,19 @@ void ValistChecker::checkPreStmt(const VAArgExpr *VAA,
VAList, "va_arg() is called on an uninitialized va_list", C);
}
-void ValistChecker::checkDeadSymbols(SymbolReaper &SR,
+void VAListChecker::checkDeadSymbols(SymbolReaper &SR,
CheckerContext &C) const {
ProgramStateRef State = C.getState();
- InitializedVAListsTy TrackedVALists = State->get<InitializedVALists>();
- RegionVector LeakedVALists;
- for (auto Reg : TrackedVALists) {
+ InitializedVAListsTy Tracked = State->get<InitializedVALists>();
+ RegionVector Leaked;
+ for (const MemRegion *Reg : Tracked) {
if (SR.isLiveRegion(Reg))
continue;
- LeakedVALists.push_back(Reg);
+ Leaked.push_back(Reg);
State = State->remove<InitializedVALists>(Reg);
}
if (ExplodedNode *N = C.addTransition(State))
- reportLeakedVALists(LeakedVALists, "Initialized va_list", " is leaked", C,
- N);
+ reportLeaked(Leaked, "Initialized va_list", " is leaked", C, N);
}
// This function traverses the exploded graph backwards and finds the node where
@@ -220,7 +210,7 @@ void ValistChecker::checkDeadSymbols(SymbolReaper &SR,
// It is not likely that there are several
diff erent va_lists that belongs to
//
diff erent stack frames, so that case is not yet handled.
const ExplodedNode *
-ValistChecker::getStartCallSite(const ExplodedNode *N,
+VAListChecker::getStartCallSite(const ExplodedNode *N,
const MemRegion *Reg) const {
const LocationContext *LeakContext = N->getLocationContext();
const ExplodedNode *StartCallNode = N;
@@ -244,42 +234,21 @@ ValistChecker::getStartCallSite(const ExplodedNode *N,
return StartCallNode;
}
-void ValistChecker::reportUninitializedAccess(const MemRegion *VAList,
+void VAListChecker::reportUninitializedAccess(const MemRegion *VAList,
StringRef Msg,
CheckerContext &C) const {
- if (!ChecksEnabled[CK_Uninitialized])
- return;
if (ExplodedNode *N = C.generateErrorNode()) {
- if (!BT_uninitaccess)
- BT_uninitaccess.reset(new BugType(CheckNames[CK_Uninitialized],
- "Uninitialized va_list",
- categories::MemoryError));
- auto R = std::make_unique<PathSensitiveBugReport>(*BT_uninitaccess, Msg, N);
+ auto R = std::make_unique<PathSensitiveBugReport>(UninitAccessBug, Msg, N);
R->markInteresting(VAList);
- R->addVisitor(std::make_unique<ValistBugVisitor>(VAList));
+ R->addVisitor(std::make_unique<VAListBugVisitor>(VAList));
C.emitReport(std::move(R));
}
}
-void ValistChecker::reportLeakedVALists(const RegionVector &LeakedVALists,
- StringRef Msg1, StringRef Msg2,
- CheckerContext &C, ExplodedNode *N,
- bool ReportUninit) const {
- if (!(ChecksEnabled[CK_Unterminated] ||
- (ChecksEnabled[CK_Uninitialized] && ReportUninit)))
- return;
- for (auto Reg : LeakedVALists) {
- if (!BT_leakedvalist) {
- // FIXME: maybe creating a new check name for this type of bug is a better
- // solution.
- BT_leakedvalist.reset(new BugType(
- static_cast<StringRef>(CheckNames[CK_Unterminated]).empty()
- ? CheckNames[CK_Uninitialized]
- : CheckNames[CK_Unterminated],
- "Leaked va_list", categories::MemoryError,
- /*SuppressOnSink=*/true));
- }
-
+void VAListChecker::reportLeaked(const RegionVector &Leaked, StringRef Msg1,
+ StringRef Msg2, CheckerContext &C,
+ ExplodedNode *N) const {
+ for (const MemRegion *Reg : Leaked) {
const ExplodedNode *StartNode = getStartCallSite(N, Reg);
PathDiagnosticLocation LocUsedForUniqueing;
@@ -296,15 +265,15 @@ void ValistChecker::reportLeakedVALists(const RegionVector &LeakedVALists,
OS << Msg2;
auto R = std::make_unique<PathSensitiveBugReport>(
- *BT_leakedvalist, OS.str(), N, LocUsedForUniqueing,
+ LeakBug, OS.str(), N, LocUsedForUniqueing,
StartNode->getLocationContext()->getDecl());
R->markInteresting(Reg);
- R->addVisitor(std::make_unique<ValistBugVisitor>(Reg, true));
+ R->addVisitor(std::make_unique<VAListBugVisitor>(Reg, true));
C.emitReport(std::move(R));
}
}
-void ValistChecker::checkVAListStartCall(const CallEvent &Call,
+void VAListChecker::checkVAListStartCall(const CallEvent &Call,
CheckerContext &C, bool IsCopy) const {
bool Symbolic;
const MemRegion *VAList =
@@ -318,20 +287,19 @@ void ValistChecker::checkVAListStartCall(const CallEvent &Call,
const MemRegion *Arg2 =
getVAListAsRegion(Call.getArgSVal(1), Call.getArgExpr(1), Symbolic, C);
if (Arg2) {
- if (ChecksEnabled[CK_CopyToSelf] && VAList == Arg2) {
- RegionVector LeakedVALists{VAList};
+ if (VAList == Arg2) {
+ RegionVector Leaked{VAList};
if (ExplodedNode *N = C.addTransition(State))
- reportLeakedVALists(LeakedVALists, "va_list",
- " is copied onto itself", C, N, true);
+ reportLeaked(Leaked, "va_list", " is copied onto itself", C, N);
return;
- } else if (!State->contains<InitializedVALists>(Arg2) && !Symbolic) {
+ }
+ if (!State->contains<InitializedVALists>(Arg2) && !Symbolic) {
if (State->contains<InitializedVALists>(VAList)) {
State = State->remove<InitializedVALists>(VAList);
- RegionVector LeakedVALists{VAList};
+ RegionVector Leaked{VAList};
if (ExplodedNode *N = C.addTransition(State))
- reportLeakedVALists(LeakedVALists, "Initialized va_list",
- " is overwritten by an uninitialized one", C, N,
- true);
+ reportLeaked(Leaked, "Initialized va_list",
+ " is overwritten by an uninitialized one", C, N);
} else {
reportUninitializedAccess(Arg2, "Uninitialized va_list is copied", C);
}
@@ -340,10 +308,10 @@ void ValistChecker::checkVAListStartCall(const CallEvent &Call,
}
}
if (State->contains<InitializedVALists>(VAList)) {
- RegionVector LeakedVALists{VAList};
+ RegionVector Leaked{VAList};
if (ExplodedNode *N = C.addTransition(State))
- reportLeakedVALists(LeakedVALists, "Initialized va_list",
- " is initialized again", C, N);
+ reportLeaked(Leaked, "Initialized va_list", " is initialized again", C,
+ N);
return;
}
@@ -351,7 +319,7 @@ void ValistChecker::checkVAListStartCall(const CallEvent &Call,
C.addTransition(State);
}
-void ValistChecker::checkVAListEndCall(const CallEvent &Call,
+void VAListChecker::checkVAListEndCall(const CallEvent &Call,
CheckerContext &C) const {
bool Symbolic;
const MemRegion *VAList =
@@ -374,7 +342,7 @@ void ValistChecker::checkVAListEndCall(const CallEvent &Call,
C.addTransition(State);
}
-PathDiagnosticPieceRef ValistChecker::ValistBugVisitor::VisitNode(
+PathDiagnosticPieceRef VAListChecker::VAListBugVisitor::VisitNode(
const ExplodedNode *N, BugReporterContext &BRC, PathSensitiveBugReport &) {
ProgramStateRef State = N->getState();
ProgramStateRef StatePrev = N->getFirstPred()->getState();
@@ -399,26 +367,8 @@ PathDiagnosticPieceRef ValistChecker::ValistBugVisitor::VisitNode(
return std::make_shared<PathDiagnosticEventPiece>(Pos, Msg, true);
}
-void ento::registerValistBase(CheckerManager &mgr) {
- mgr.registerChecker<ValistChecker>();
-}
-
-bool ento::shouldRegisterValistBase(const CheckerManager &mgr) {
- return true;
+void ento::registerVAListChecker(CheckerManager &Mgr) {
+ Mgr.registerChecker<VAListChecker>();
}
-#define REGISTER_CHECKER(name) \
- void ento::register##name##Checker(CheckerManager &mgr) { \
- ValistChecker *checker = mgr.getChecker<ValistChecker>(); \
- checker->ChecksEnabled[ValistChecker::CK_##name] = true; \
- checker->CheckNames[ValistChecker::CK_##name] = \
- mgr.getCurrentCheckerName(); \
- } \
- \
- bool ento::shouldRegister##name##Checker(const CheckerManager &mgr) { \
- return true; \
- }
-
-REGISTER_CHECKER(Uninitialized)
-REGISTER_CHECKER(Unterminated)
-REGISTER_CHECKER(CopyToSelf)
+bool ento::shouldRegisterVAListChecker(const CheckerManager &) { return true; }
diff --git a/clang/test/Analysis/valist-as-lazycompound.c b/clang/test/Analysis/valist-as-lazycompound.c
index 3218e03a9c657..35a137321a67f 100644
--- a/clang/test/Analysis/valist-as-lazycompound.c
+++ b/clang/test/Analysis/valist-as-lazycompound.c
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -triple gcc-linaro-arm-linux-gnueabihf -analyzer-checker=core,valist.Uninitialized,valist.CopyToSelf -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -triple gcc-linaro-arm-linux-gnueabihf -analyzer-checker=core,security.VAList -analyzer-output=text -verify %s
// expected-no-diagnostics
typedef unsigned int size_t;
diff --git a/clang/test/Analysis/valist-uninitialized-no-undef.c b/clang/test/Analysis/valist-uninitialized-no-undef.c
index 48631429be646..b8add29fc4803 100644
--- a/clang/test/Analysis/valist-uninitialized-no-undef.c
+++ b/clang/test/Analysis/valist-uninitialized-no-undef.c
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu -analyzer-checker=core,valist.Uninitialized,valist.CopyToSelf -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu -analyzer-checker=core,security.VAList -analyzer-output=text -verify %s
#include "Inputs/system-header-simulator-for-valist.h"
@@ -14,12 +14,6 @@ void call_inlined_uses_arg(int fst, ...) {
inlined_uses_arg(va); // expected-note{{Calling 'inlined_uses_arg'}}
}
-void f6(va_list *fst, ...) {
- va_start(*fst, fst);
- (void)va_arg(*fst, int);
- va_end(*fst);
-}
-
int va_list_get_int(va_list *va) {
return va_arg(*va, int); // no-warning
}
diff --git a/clang/test/Analysis/valist-uninitialized.c b/clang/test/Analysis/valist-uninitialized.c
index 003592997eab8..689fc95c5a771 100644
--- a/clang/test/Analysis/valist-uninitialized.c
+++ b/clang/test/Analysis/valist-uninitialized.c
@@ -1,15 +1,15 @@
// RUN: %clang_analyze_cc1 -triple hexagon-unknown-linux -verify %s \
-// RUN: -analyzer-checker=core,valist.Uninitialized,valist.CopyToSelf \
+// RUN: -analyzer-checker=core,security.VAList \
// RUN: -analyzer-disable-checker=core.CallAndMessage \
// RUN: -analyzer-output=text
//
// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu -verify %s \
-// RUN: -analyzer-checker=core,valist.Uninitialized,valist.CopyToSelf \
+// RUN: -analyzer-checker=core,security.VAList \
// RUN: -analyzer-disable-checker=core.CallAndMessage \
// RUN: -analyzer-output=text
//
// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu %s \
-// RUN: -analyzer-checker=core,valist.Uninitialized
+// RUN: -analyzer-checker=core,security.VAList
#include "Inputs/system-header-simulator-for-valist.h"
@@ -47,12 +47,6 @@ void f4(int cond, ...) {
// expected-note at -1{{va_end() is called on an uninitialized va_list}}
}
-void f5(va_list fst, ...) {
- va_start(fst, fst);
- (void)va_arg(fst, int);
- va_end(fst);
-} // no-warning
-
void f7(int *fst, ...) {
va_list x;
va_list *y = &x;
@@ -70,14 +64,6 @@ void f8(int *fst, ...) {
// expected-note at -1{{va_arg() is called on an uninitialized va_list}}
}
-// This only contains problems which are handled by varargs.Unterminated.
-void reinit(int *fst, ...) {
- va_list va;
- va_start(va, fst);
- va_start(va, fst);
- (void)va_arg(va, int);
-} // no-warning
-
void reinitOk(int *fst, ...) {
va_list va;
va_start(va, fst);
@@ -100,27 +86,6 @@ void reinit3(int *fst, ...) {
// expected-note at -1{{va_arg() is called on an uninitialized va_list}}
}
-void copyself(int fst, ...) {
- va_list va;
- va_start(va, fst); // expected-note{{Initialized va_list}}
- va_copy(va, va); // expected-warning{{va_list 'va' is copied onto itself}}
- // expected-note at -1{{va_list 'va' is copied onto itself}}
- va_end(va);
-}
-
-void copyselfUninit(int fst, ...) {
- va_list va;
- va_copy(va, va); // expected-warning{{va_list 'va' is copied onto itself}}
- // expected-note at -1{{va_list 'va' is copied onto itself}}
-}
-
-void copyOverwrite(int fst, ...) {
- va_list va, va2;
- va_start(va, fst); // expected-note{{Initialized va_list}}
- va_copy(va, va2); // expected-warning{{Initialized va_list 'va' is overwritten by an uninitialized one}}
- // expected-note at -1{{Initialized va_list 'va' is overwritten by an uninitialized one}}
-}
-
void copyUnint(int fst, ...) {
va_list va, va2;
va_copy(va, va2); // expected-warning{{Uninitialized va_list is copied}}
diff --git a/clang/test/Analysis/valist-unterminated.c b/clang/test/Analysis/valist-unterminated.c
index 22d8fc710544e..cc892684b15fc 100644
--- a/clang/test/Analysis/valist-unterminated.c
+++ b/clang/test/Analysis/valist-unterminated.c
@@ -1,5 +1,5 @@
-// RUN: %clang_analyze_cc1 -triple hexagon-unknown-linux -analyzer-checker=core,valist.Unterminated,valist.CopyToSelf -analyzer-output=text -verify %s
-// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu -analyzer-checker=core,valist.Unterminated,valist.CopyToSelf -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -triple hexagon-unknown-linux -analyzer-checker=core,security.VAList -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu -analyzer-checker=core,security.VAList -analyzer-output=text -verify %s
#include "Inputs/system-header-simulator-for-valist.h"
@@ -97,12 +97,6 @@ void copyOverwrite(int fst, ...) {
// expected-note at -1{{Initialized va_list 'va' is overwritten by an uninitialized one}}
}
-//This only generates a warning for the valist.Uninitialized checker
-void copyUnint(int fst, ...) {
- va_list va, va2;
- va_copy(va, va2);
-} // no-warning
-
void recopy(int fst, ...) {
va_list va, va2;
va_start(va, fst);
More information about the cfe-commits
mailing list