r279043 - revert [analyzer] Added valist related checkers.
Gabor Horvath via cfe-commits
cfe-commits at lists.llvm.org
Thu Aug 18 02:13:37 PDT 2016
Author: xazax
Date: Thu Aug 18 04:13:37 2016
New Revision: 279043
URL: http://llvm.org/viewvc/llvm-project?rev=279043&view=rev
Log:
revert [analyzer] Added valist related checkers.
Removed:
cfe/trunk/lib/StaticAnalyzer/Checkers/ValistChecker.cpp
cfe/trunk/test/Analysis/Inputs/system-header-simulator-for-valist.h
cfe/trunk/test/Analysis/valist-uninitialized.c
cfe/trunk/test/Analysis/valist-unterminated.c
Modified:
cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td
cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt
Modified: cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td?rev=279043&r1=279042&r2=279043&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td Thu Aug 18 04:13:37 2016
@@ -43,9 +43,6 @@ def Nullability : Package<"nullability">
def Cplusplus : Package<"cplusplus">;
def CplusplusAlpha : Package<"cplusplus">, InPackage<Alpha>, Hidden;
-def Valist : Package<"valist">;
-def ValistAlpha : Package<"valist">, InPackage<Alpha>, Hidden;
-
def DeadCode : Package<"deadcode">;
def DeadCodeAlpha : Package<"deadcode">, InPackage<Alpha>, Hidden;
@@ -270,27 +267,6 @@ def VirtualCallChecker : Checker<"Virtua
} // end: "alpha.cplusplus"
-
-//===----------------------------------------------------------------------===//
-// Valist checkers.
-//===----------------------------------------------------------------------===//
-
-let ParentPackage = ValistAlpha in {
-
-def UninitializedChecker : Checker<"Uninitialized">,
- HelpText<"Check for usages of uninitialized (or already released) va_lists.">,
- DescFile<"ValistChecker.cpp">;
-
-def UnterminatedChecker : Checker<"Unterminated">,
- HelpText<"Check for va_lists which are not released by a va_end call.">,
- DescFile<"ValistChecker.cpp">;
-
-def CopyToSelfChecker : Checker<"CopyToSelf">,
- HelpText<"Check for va_lists which are copied onto itself.">,
- DescFile<"ValistChecker.cpp">;
-
-} // end : "alpha.valist"
-
//===----------------------------------------------------------------------===//
// Deadcode checkers.
//===----------------------------------------------------------------------===//
Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt?rev=279043&r1=279042&r2=279043&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt Thu Aug 18 04:13:37 2016
@@ -81,7 +81,6 @@ add_clang_library(clangStaticAnalyzerChe
UnreachableCodeChecker.cpp
VforkChecker.cpp
VLASizeChecker.cpp
- ValistChecker.cpp
VirtualCallChecker.cpp
DEPENDS
Removed: cfe/trunk/lib/StaticAnalyzer/Checkers/ValistChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/ValistChecker.cpp?rev=279042&view=auto
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/ValistChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/ValistChecker.cpp (removed)
@@ -1,373 +0,0 @@
-//== ValistChecker.cpp - stdarg.h macro usage checker -----------*- C++ -*--==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This defines checkers which detect usage of uninitialized va_list values
-// and va_start calls with no matching va_end.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ClangSACheckers.h"
-#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
-#include "clang/StaticAnalyzer/Core/Checker.h"
-#include "clang/StaticAnalyzer/Core/CheckerManager.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
-
-using namespace clang;
-using namespace ento;
-
-REGISTER_SET_WITH_PROGRAMSTATE(InitializedVALists, const MemRegion *)
-
-namespace {
-typedef SmallVector<const MemRegion *, 2> RegionVector;
-
-class ValistChecker : public Checker<check::PreCall, check::PreStmt<VAArgExpr>,
- check::DeadSymbols> {
- mutable std::unique_ptr<BugType> BT_leakedvalist, BT_uninitaccess;
-
- struct VAListAccepter {
- CallDescription Func;
- int VAListPos;
- };
- static const SmallVector<VAListAccepter, 15> VAListAccepters;
- static const CallDescription VaStart, VaEnd, VaCopy;
-
-public:
- enum CheckKind {
- CK_Uninitialized,
- CK_Unterminated,
- CK_CopyToSelf,
- CK_NumCheckKinds
- };
-
- DefaultBool ChecksEnabled[CK_NumCheckKinds];
- CheckName 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;
-
-private:
- const MemRegion *getVAListAsRegion(SVal SV, CheckerContext &C) const;
- StringRef getVariableNameFromRegion(const MemRegion *Reg) const;
- const ExplodedNode *getStartCallSite(const ExplodedNode *N,
- const MemRegion *Reg,
- CheckerContext &C) const;
-
- void reportUninitializedAccess(const MemRegion *VAList, StringRef Msg,
- CheckerContext &C) const;
- void reportLeakedVALists(const RegionVector &LeakedVALists, StringRef Msg1,
- StringRef Msg2, CheckerContext &C, ExplodedNode *N,
- bool ForceReport = false) const;
-
- void checkVAListStartCall(const CallEvent &Call, CheckerContext &C,
- bool IsCopy) const;
- void checkVAListEndCall(const CallEvent &Call, CheckerContext &C) const;
-
- class ValistBugVisitor : public BugReporterVisitorImpl<ValistBugVisitor> {
- public:
- ValistBugVisitor(const MemRegion *Reg, bool IsLeak = false)
- : Reg(Reg), IsLeak(IsLeak) {}
- void Profile(llvm::FoldingSetNodeID &ID) const override {
- static int X = 0;
- ID.AddPointer(&X);
- ID.AddPointer(Reg);
- }
- std::unique_ptr<PathDiagnosticPiece>
- getEndPath(BugReporterContext &BRC, const ExplodedNode *EndPathNode,
- BugReport &BR) override {
- if (!IsLeak)
- return nullptr;
-
- PathDiagnosticLocation L = PathDiagnosticLocation::createEndOfPath(
- EndPathNode, BRC.getSourceManager());
- // Do not add the statement itself as a range in case of leak.
- return llvm::make_unique<PathDiagnosticEventPiece>(L, BR.getDescription(),
- false);
- }
- PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
- const ExplodedNode *PrevN,
- BugReporterContext &BRC,
- BugReport &BR) override;
-
- private:
- const MemRegion *Reg;
- bool IsLeak;
- };
-};
-
-const SmallVector<ValistChecker::VAListAccepter, 15>
- ValistChecker::VAListAccepters = {
- {{"vfprintf", 3}, 2},
- {{"vfscanf", 3}, 2},
- {{"vprintf", 2}, 1},
- {{"vscanf", 2}, 1},
- {{"vsnprintf", 4}, 3},
- {{"vsprintf", 3}, 2},
- {{"vsscanf", 3}, 2},
- {{"vfwprintf", 3}, 2},
- {{"vfwscanf", 3}, 2},
- {{"vwprintf", 2}, 1},
- {{"vwscanf", 2}, 1},
- {{"vswprintf", 4}, 3},
- // vswprintf is the wide version of vsnprintf,
- // vsprintf has no wide version
- {{"vswscanf", 3}, 2}};
-const CallDescription ValistChecker::VaStart("__builtin_va_start", 2),
- ValistChecker::VaCopy("__builtin_va_copy", 2),
- ValistChecker::VaEnd("__builtin_va_end", 1);
-} // end anonymous namespace
-
-void ValistChecker::checkPreCall(const CallEvent &Call,
- CheckerContext &C) const {
- if (!Call.isGlobalCFunction())
- return;
- if (Call.isCalled(VaStart))
- checkVAListStartCall(Call, C, false);
- else if (Call.isCalled(VaCopy))
- checkVAListStartCall(Call, C, true);
- else if (Call.isCalled(VaEnd))
- checkVAListEndCall(Call, C);
- else {
- for (auto FuncInfo : VAListAccepters) {
- if (!Call.isCalled(FuncInfo.Func))
- continue;
- const MemRegion *VAList =
- getVAListAsRegion(Call.getArgSVal(FuncInfo.VAListPos), C);
- if (!VAList)
- return;
-
- if (C.getState()->contains<InitializedVALists>(VAList))
- return;
-
- SmallString<80> Errmsg("Function '");
- Errmsg += FuncInfo.Func.getFunctionName();
- Errmsg += "' is called with an uninitialized va_list argument";
- reportUninitializedAccess(VAList, Errmsg.c_str(), C);
- break;
- }
- }
-}
-
-void ValistChecker::checkPreStmt(const VAArgExpr *VAA,
- CheckerContext &C) const {
- ProgramStateRef State = C.getState();
- SVal VAListSVal = State->getSVal(VAA->getSubExpr(), C.getLocationContext());
- const MemRegion *VAList = getVAListAsRegion(VAListSVal, C);
- if (!VAList)
- return;
- if (!State->contains<InitializedVALists>(VAList))
- reportUninitializedAccess(
- VAList, "va_arg() is called on an uninitialized va_list", C);
-}
-
-void ValistChecker::checkDeadSymbols(SymbolReaper &SR,
- CheckerContext &C) const {
- ProgramStateRef State = C.getState();
- InitializedVAListsTy TrackedVALists = State->get<InitializedVALists>();
- RegionVector LeakedVALists;
- for (auto Reg : TrackedVALists) {
- if (SR.isLiveRegion(Reg))
- continue;
- LeakedVALists.push_back(Reg);
- State = State->remove<InitializedVALists>(Reg);
- }
- if (ExplodedNode *N = C.addTransition(State))
- reportLeakedVALists(LeakedVALists, "Initialized va_list", " is leaked", C,
- N);
-}
-
-const MemRegion *ValistChecker::getVAListAsRegion(SVal SV,
- CheckerContext &C) const {
- const MemRegion *Reg = SV.getAsRegion();
- const auto *TReg = dyn_cast_or_null<TypedValueRegion>(Reg);
- // Some VarRegion based VLAs reach here as ElementRegions.
- const auto *EReg = dyn_cast_or_null<ElementRegion>(TReg);
- return EReg ? EReg->getSuperRegion() : TReg;
-}
-
-// This function traverses the exploded graph backwards and finds the node where
-// the va_list is initialized. That node is used for uniquing the bug paths.
-// It is not likely that there are several different va_lists that belongs to
-// different stack frames, so that case is not yet handled.
-const ExplodedNode *ValistChecker::getStartCallSite(const ExplodedNode *N,
- const MemRegion *Reg,
- CheckerContext &C) const {
- const LocationContext *LeakContext = N->getLocationContext();
- const ExplodedNode *StartCallNode = N;
-
- bool FoundInitializedState = false;
-
- while (N) {
- ProgramStateRef State = N->getState();
- if (!State->contains<InitializedVALists>(Reg)) {
- if (FoundInitializedState)
- break;
- } else {
- FoundInitializedState = true;
- }
- const LocationContext *NContext = N->getLocationContext();
- if (NContext == LeakContext || NContext->isParentOf(LeakContext))
- StartCallNode = N;
- N = N->pred_empty() ? nullptr : *(N->pred_begin());
- }
-
- return StartCallNode;
-}
-
-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",
- "Memory Error"));
- auto R = llvm::make_unique<BugReport>(*BT_uninitaccess, Msg, N);
- R->markInteresting(VAList);
- R->addVisitor(llvm::make_unique<ValistBugVisitor>(VAList));
- C.emitReport(std::move(R));
- }
-}
-
-void ValistChecker::reportLeakedVALists(const RegionVector &LeakedVALists,
- StringRef Msg1, StringRef Msg2,
- CheckerContext &C, ExplodedNode *N,
- bool ForceReport) const {
- if (!(ChecksEnabled[CK_Unterminated] ||
- (ChecksEnabled[CK_Uninitialized] && ForceReport)))
- return;
- for (auto Reg : LeakedVALists) {
- if (!BT_leakedvalist) {
- BT_leakedvalist.reset(new BugType(CheckNames[CK_Unterminated],
- "Leaked va_list", "Memory Error"));
- BT_leakedvalist->setSuppressOnSink(true);
- }
-
- const ExplodedNode *StartNode = getStartCallSite(N, Reg, C);
- PathDiagnosticLocation LocUsedForUniqueing;
-
- if (const Stmt *StartCallStmt = PathDiagnosticLocation::getStmt(StartNode))
- LocUsedForUniqueing = PathDiagnosticLocation::createBegin(
- StartCallStmt, C.getSourceManager(), StartNode->getLocationContext());
-
- SmallString<100> Buf;
- llvm::raw_svector_ostream OS(Buf);
- OS << Msg1;
- StringRef VariableName = Reg->getDescriptiveName();
- if (!VariableName.empty())
- OS << " " << VariableName;
- OS << Msg2;
-
- auto R = llvm::make_unique<BugReport>(
- *BT_leakedvalist, OS.str(), N, LocUsedForUniqueing,
- StartNode->getLocationContext()->getDecl());
- R->markInteresting(Reg);
- R->addVisitor(llvm::make_unique<ValistBugVisitor>(Reg, true));
- C.emitReport(std::move(R));
- }
-}
-
-void ValistChecker::checkVAListStartCall(const CallEvent &Call,
- CheckerContext &C, bool IsCopy) const {
- const MemRegion *VAList = getVAListAsRegion(Call.getArgSVal(0), C);
- ProgramStateRef State = C.getState();
- if (!VAList)
- return;
-
- if (IsCopy) {
- const MemRegion *Arg2 = getVAListAsRegion(Call.getArgSVal(1), C);
- if (Arg2) {
- if (ChecksEnabled[CK_CopyToSelf] && VAList == Arg2) {
- RegionVector LeakedVALists{VAList};
- if (ExplodedNode *N = C.addTransition(State))
- reportLeakedVALists(LeakedVALists, "va_list",
- " is copied onto itself", C, N, true);
- return;
- } else if (!State->contains<InitializedVALists>(Arg2)) {
- if (State->contains<InitializedVALists>(VAList)) {
- State = State->remove<InitializedVALists>(VAList);
- RegionVector LeakedVALists{VAList};
- if (ExplodedNode *N = C.addTransition(State))
- reportLeakedVALists(LeakedVALists, "Initialized va_list",
- " is overwritten by an uninitialized one", C, N,
- true);
- } else {
- reportUninitializedAccess(Arg2, "Uninitialized va_list is copied", C);
- }
- return;
- }
- }
- }
- if (State->contains<InitializedVALists>(VAList)) {
- RegionVector LeakedVALists{VAList};
- if (ExplodedNode *N = C.addTransition(State))
- reportLeakedVALists(LeakedVALists, "Initialized va_list",
- " is initialized again", C, N);
- return;
- }
-
- State = State->add<InitializedVALists>(VAList);
- C.addTransition(State);
-}
-
-void ValistChecker::checkVAListEndCall(const CallEvent &Call,
- CheckerContext &C) const {
- const MemRegion *VAList = getVAListAsRegion(Call.getArgSVal(0), C);
- if (!VAList)
- return;
-
- if (!C.getState()->contains<InitializedVALists>(VAList)) {
- reportUninitializedAccess(
- VAList, "va_end() is called on an uninitialized va_list", C);
- return;
- }
- ProgramStateRef State = C.getState();
- State = State->remove<InitializedVALists>(VAList);
- C.addTransition(State);
-}
-
-PathDiagnosticPiece *ValistChecker::ValistBugVisitor::VisitNode(
- const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC,
- BugReport &BR) {
- ProgramStateRef State = N->getState();
- ProgramStateRef StatePrev = PrevN->getState();
-
- const Stmt *S = PathDiagnosticLocation::getStmt(N);
- if (!S)
- return nullptr;
-
- StringRef Msg;
- if (State->contains<InitializedVALists>(Reg) &&
- !StatePrev->contains<InitializedVALists>(Reg))
- Msg = "Initialized va_list";
- else if (!State->contains<InitializedVALists>(Reg) &&
- StatePrev->contains<InitializedVALists>(Reg))
- Msg = "Ended va_list";
-
- if (Msg.empty())
- return nullptr;
-
- PathDiagnosticLocation Pos(S, BRC.getSourceManager(),
- N->getLocationContext());
- return new PathDiagnosticEventPiece(Pos, Msg, true);
-}
-
-#define REGISTER_CHECKER(name) \
- void ento::register##name##Checker(CheckerManager &mgr) { \
- ValistChecker *checker = mgr.registerChecker<ValistChecker>(); \
- checker->ChecksEnabled[ValistChecker::CK_##name] = true; \
- checker->CheckNames[ValistChecker::CK_##name] = mgr.getCurrentCheckName(); \
- }
-
-REGISTER_CHECKER(Uninitialized)
-REGISTER_CHECKER(Unterminated)
-REGISTER_CHECKER(CopyToSelf)
Removed: cfe/trunk/test/Analysis/Inputs/system-header-simulator-for-valist.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/Inputs/system-header-simulator-for-valist.h?rev=279042&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/Inputs/system-header-simulator-for-valist.h (original)
+++ cfe/trunk/test/Analysis/Inputs/system-header-simulator-for-valist.h (removed)
@@ -1,30 +0,0 @@
-// Like the compiler, the static analyzer treats some functions differently if
-// they come from a system header -- for example, it is assumed that system
-// functions do not arbitrarily free() their parameters, and that some bugs
-// found in system headers cannot be fixed by the user and should be
-// suppressed.
-
-#pragma clang system_header
-
-#ifdef __cplusplus
-#define restrict /*restrict*/
-#endif
-
-typedef __builtin_va_list va_list;
-
-#define va_start(ap, param) __builtin_va_start(ap, param)
-#define va_end(ap) __builtin_va_end(ap)
-#define va_arg(ap, type) __builtin_va_arg(ap, type)
-#define va_copy(dst, src) __builtin_va_copy(dst, src)
-
-int vprintf (const char *restrict format, va_list arg);
-
-int vsprintf (char *restrict s, const char *restrict format, va_list arg);
-
-int some_library_function(int n, va_list arg);
-
-// No warning from system header.
-inline void __impl_detail(int fst, ...) {
- va_list va;
- (void)va_arg(va, int);
-}
Removed: cfe/trunk/test/Analysis/valist-uninitialized.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/valist-uninitialized.c?rev=279042&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/valist-uninitialized.c (original)
+++ cfe/trunk/test/Analysis/valist-uninitialized.c (removed)
@@ -1,178 +0,0 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.valist.Uninitialized,alpha.valist.CopyToSelf -analyzer-output=text -analyzer-store=region -verify %s
-
-#include "Inputs/system-header-simulator-for-valist.h"
-
-void f1(int fst, ...) {
- va_list va;
- (void)va_arg(va, int); //expected-warning{{va_arg() is called on an uninitialized va_list}} expected-note{{va_arg() is called on an uninitialized va_list}}
-}
-
-int f2(int fst, ...) {
- va_list va;
- va_start(va, fst); // expected-note{{Initialized va_list}}
- va_end(va); // expected-note{{Ended va_list}}
- return va_arg(va, int); //expected-warning{{va_arg() is called on an uninitialized va_list}} expected-note{{va_arg() is called on an uninitialized va_list}}
-}
-
-void f3(int fst, ...) {
- va_list va, va2;
- va_start(va, fst);
- va_copy(va2, va);
- va_end(va);
- (void)va_arg(va2, int);
- va_end(va2);
-} //no-warning
-
-void f4(int cond, ...) {
- va_list va;
- if (cond) { // expected-note{{Assuming 'cond' is 0}} expected-note{{Taking false branch}}
- va_start(va, cond);
- (void)va_arg(va,int);
- }
- va_end(va); //expected-warning{{va_end() is called on an uninitialized va_list}} expected-note{{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
-
-//FIXME: this should not cause a warning
-void f6(va_list *fst, ...) {
- va_start(*fst, fst);
- (void)va_arg(*fst, int); //expected-warning{{va_arg() is called on an uninitialized va_list}} expected-note{{va_arg() is called on an uninitialized va_list}}
- va_end(*fst);
-}
-
-void f7(int *fst, ...) {
- va_list x;
- va_list *y = &x;
- va_start(*y,fst);
- (void)va_arg(x, int);
- va_end(x);
-} // no-warning
-
-void f8(int *fst, ...) {
- va_list x;
- va_list *y = &x;
- va_start(*y,fst); // expected-note{{Initialized va_list}}
- va_end(x); // expected-note{{Ended va_list}}
- (void)va_arg(*y, int); //expected-warning{{va_arg() is called on an uninitialized va_list}} expected-note{{va_arg() is called on an uninitialized va_list}}
-} // no-warning
-
-// 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);
- (void)va_arg(va, int);
- va_end(va);
- va_start(va, fst);
- (void)va_arg(va, int);
- va_end(va);
-} // no-warning
-
-void reinit3(int *fst, ...) {
- va_list va;
- va_start(va, fst); // expected-note{{Initialized va_list}}
- (void)va_arg(va, int);
- va_end(va); // expected-note{{Ended va_list}}
- va_start(va, fst); // expected-note{{Initialized va_list}}
- (void)va_arg(va, int);
- va_end(va); // expected-note{{Ended va_list}}
- (void)va_arg(va, int); //expected-warning{{va_arg() is called on an uninitialized va_list}} expected-note{{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{{va_list 'va' is copied onto itself}}
- va_end(va);
-} // no-warning
-
-void copyselfUninit(int fst, ...) {
- va_list va;
- va_copy(va, va); // expected-warning{{va_list 'va' is copied onto itself}} expected-note{{va_list 'va' is copied onto itself}}
-} // no-warning
-
-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{{Initialized va_list 'va' is overwritten by an uninitialized one}}
-} // no-warning
-
-void copyUnint(int fst, ...) {
- va_list va, va2;
- va_copy(va, va2); // expected-warning{{Uninitialized va_list is copied}} expected-note{{Uninitialized va_list is copied}}
-}
-
-void g1(int fst, ...) {
- va_list va;
- va_end(va); // expected-warning{{va_end() is called on an uninitialized va_list}} expected-note{{va_end() is called on an uninitialized va_list}}
-}
-
-void g2(int fst, ...) {
- va_list va;
- va_start(va, fst); // expected-note{{Initialized va_list}}
- va_end(va); // expected-note{{Ended va_list}}
- va_end(va); // expected-warning{{va_end() is called on an uninitialized va_list}} expected-note{{va_end() is called on an uninitialized va_list}}
-}
-
-void is_sink(int fst, ...) {
- va_list va;
- va_end(va); // expected-warning{{va_end() is called on an uninitialized va_list}} expected-note{{va_end() is called on an uninitialized va_list}}
- *((volatile int *)0) = 1; //no-warning
-}
-
-// NOTE: this is invalid, as the man page of va_end requires that "Each invocation of va_start()
-// must be matched by a corresponding invocation of va_end() in the same function."
-void ends_arg(va_list arg) {
- va_end(arg);
-} //no-warning
-
-void uses_arg(va_list arg) {
- (void)va_arg(arg, int);
-} //no-warning
-
-// This is the same function as the previous one, but it is called in call_uses_arg2(),
-// and the warning is generated during the analysis of call_uses_arg2().
-void inlined_uses_arg(va_list arg) {
- (void)va_arg(arg, int); //expected-warning{{va_arg() is called on an uninitialized va_list}} expected-note{{va_arg() is called on an uninitialized va_list}}
-}
-
-void call_inlined_uses_arg(int fst, ...) {
- va_list va;
- inlined_uses_arg(va); // expected-note{{Calling 'inlined_uses_arg'}}
-}
-
-void call_vprintf_ok(int isstring, ...) {
- va_list va;
- va_start(va, isstring);
- vprintf(isstring ? "%s" : "%d", va);
- va_end(va);
-} //no-warning
-
-void call_vprintf_bad(int isstring, ...) {
- va_list va;
- vprintf(isstring ? "%s" : "%d", va); //expected-warning{{Function 'vprintf' is called with an uninitialized va_list argument}} expected-note{{Function 'vprintf' is called with an uninitialized va_list argument}} expected-note{{Assuming 'isstring' is 0}} expected-note{{'?' condition is false}}
-}
-
-void call_vsprintf_bad(char *buffer, ...) {
- va_list va;
- va_start(va, buffer); // expected-note{{Initialized va_list}}
- va_end(va); // expected-note{{Ended va_list}}
- vsprintf(buffer, "%s %d %d %lf %03d", va); //expected-warning{{Function 'vsprintf' is called with an uninitialized va_list argument}} expected-note{{Function 'vsprintf' is called with an uninitialized va_list argument}}
-}
-
-void call_some_other_func(int n, ...) {
- va_list va;
- some_library_function(n, va);
-} //no-warning
-
Removed: cfe/trunk/test/Analysis/valist-unterminated.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/valist-unterminated.c?rev=279042&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/valist-unterminated.c (original)
+++ cfe/trunk/test/Analysis/valist-unterminated.c (removed)
@@ -1,133 +0,0 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.valist.Unterminated,alpha.valist.CopyToSelf -analyzer-output=text -analyzer-store=region -verify %s
-
-#include "Inputs/system-header-simulator-for-valist.h"
-
-void f1(int fst, ...) {
- va_list va;
- va_start(va, fst); // expected-note{{Initialized va_list}}
- return; // expected-warning{{Initialized va_list 'va' is leaked}} expected-note{{Initialized va_list 'va' is leaked}}
-}
-
-void f2(int fst, ...) {
- va_list va;
- va_start(va, fst); // expected-note{{Initialized va_list}}
- va_end(va); // expected-note{{Ended va_list}}
- va_start(va, fst); // expected-note{{Initialized va_list}}
-} // expected-warning{{Initialized va_list 'va' is leaked}} expected-note{{Initialized va_list 'va' is leaked}}}
-
-void f3(int fst, ...) {
- va_list va, va2;
- va_start(va, fst);
- va_copy(va2, va); // expected-note{{Initialized va_list}}
- va_end(va); // expected-warning{{Initialized va_list 'va2' is leaked}} expected-note{{Initialized va_list 'va2' is leaked}}
-}
-
-void f4(va_list *fst, ...) {
- va_start(*fst, fst); // expected-note{{Initialized va_list}}
- return; // expected-warning{{Initialized va_list is leaked}} expected-note{{Initialized va_list is leaked}}
-}
-
-void f5(va_list fst, ...) {
- va_start(fst, fst);
- //FIXME: this should cause a warning
-} // no-warning
-
-void f6(va_list *fst, ...) {
- va_start(*fst, fst); // expected-note{{Initialized va_list}}
- (void)va_arg(*fst, int);
- //FIXME: this should NOT cause a warning
- va_end(*fst); // expected-warning{{Initialized va_list is leaked}} expected-note{{Initialized va_list is leaked}}
-}
-
-void f7(int *fst, ...) {
- va_list x;
- va_list *y = &x;
- va_start(*y,fst); // expected-note{{Initialized va_list}}
-} // expected-warning{{Initialized va_list 'x' is leaked}} expected-note{{Initialized va_list 'x' is leaked}}
-
-void f8(int *fst, ...) {
- va_list x;
- va_list *y = &x;
- va_start(*y,fst);
- va_end(x);
-} // no-warning
-
-void reinit(int *fst, ...) {
- va_list va;
- va_start(va, fst); // expected-note{{Initialized va_list}} expected-note{{Initialized va_list}}
- va_start(va, fst); // expected-warning{{Initialized va_list 'va' is initialized again}} expected-note{{Initialized va_list 'va' is initialized again}}
-} // expected-warning{{Initialized va_list 'va' is leaked}} expected-note{{Initialized va_list 'va' is leaked}}
-
-void reinitOk(int *fst, ...) {
- va_list va;
- va_start(va, fst);
- va_end(va);
- va_start(va, fst);
- va_end(va);
-} // no-warning
-
-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{{va_list 'va' is copied onto itself}}
- va_end(va);
-} // no-warning
-
-void copyselfUninit(int fst, ...) {
- va_list va;
- va_copy(va, va); // expected-warning{{va_list 'va' is copied onto itself}} expected-note{{va_list 'va' is copied onto itself}}
-} // no-warning
-
-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{{Initialized va_list 'va' is overwritten by an uninitialized one}}
-} // no-warning
-
-//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);
- va_copy(va2, va); // expected-note{{Initialized va_list}}
- va_copy(va2, va); // expected-warning{{Initialized va_list 'va2' is initialized again}} expected-note{{Initialized va_list 'va2' is initialized again}}
- va_end(va);
- va_end(va2);
-} //no-warning
-
-void doublemsg(int fst, ...) {
- va_list va, va2;
- va_start(va, fst), va_start(va2, fst); // expected-warning{{Initialized va_list 'va' is leaked}} expected-warning{{Initialized va_list 'va2' is leaked}} expected-note{{Initialized va_list}} expected-note{{Initialized va_list}} expected-note{{Initialized va_list}} expected-note{{Initialized va_list 'va' is leaked}}
-}
-
-void in_array(int fst, ...) {
- va_list va_array[8];
- va_start(va_array[3], fst); // expected-note{{Initialized va_list}}
-} // expected-warning{{Initialized va_list 'va_array[3]' is leaked}} expected-note{{Initialized va_list 'va_array[3]' is leaked}}
-
-struct containing_a_valist {
- va_list vafield;
- int foobar;
-};
-
-void in_struct(int fst, ...) {
- struct containing_a_valist s;
- va_start(s.vafield, fst); // expected-note{{Initialized va_list}}
-} // expected-warning{{Initialized va_list 's.vafield' is leaked}} expected-note{{Initialized va_list 's.vafield' is leaked}}
-
-void casting(int fst, ...) {
- char mem[sizeof(va_list)];
- va_start(*(va_list *) mem, fst); // expected-note{{Initialized va_list}}
-} // expected-warning{{Initialized va_list 'mem[0]' is leaked}} expected-note{{Initialized va_list 'mem[0]' is leaked}}
-
-
-void castingOk(int fst, ...) {
- char mem[sizeof(va_list)];
- va_start(*(va_list *) mem, fst);
- va_end(*(va_list *) mem);
-} // no-warning
-
More information about the cfe-commits
mailing list