summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp167
1 files changed, 90 insertions, 77 deletions
diff --git a/contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
index c3736d7..0693bd6f 100644
--- a/contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
+++ b/contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
@@ -35,11 +35,8 @@ class CStringChecker : public Checker< eval::Call,
check::DeadSymbols,
check::RegionChanges
> {
- mutable OwningPtr<BugType> BT_Null,
- BT_Bounds,
- BT_Overlap,
- BT_NotCString,
- BT_AdditionOverflow;
+ mutable std::unique_ptr<BugType> BT_Null, BT_Bounds, BT_Overlap,
+ BT_NotCString, BT_AdditionOverflow;
mutable const char *CurrentFunctionDescription;
@@ -51,6 +48,11 @@ public:
DefaultBool CheckCStringOutOfBounds;
DefaultBool CheckCStringBufferOverlap;
DefaultBool CheckCStringNotNullTerm;
+
+ CheckName CheckNameCStringNullArg;
+ CheckName CheckNameCStringOutOfBounds;
+ CheckName CheckNameCStringBufferOverlap;
+ CheckName CheckNameCStringNotNullTerm;
};
CStringChecksFilter Filter;
@@ -157,24 +159,24 @@ public:
ProgramStateRef state,
const Expr *S,
SVal l,
- const char *message = NULL) const;
+ const char *message = nullptr) const;
ProgramStateRef CheckBufferAccess(CheckerContext &C,
ProgramStateRef state,
const Expr *Size,
const Expr *FirstBuf,
const Expr *SecondBuf,
- const char *firstMessage = NULL,
- const char *secondMessage = NULL,
+ const char *firstMessage = nullptr,
+ const char *secondMessage = nullptr,
bool WarnAboutSize = false) const;
ProgramStateRef CheckBufferAccess(CheckerContext &C,
ProgramStateRef state,
const Expr *Size,
const Expr *Buf,
- const char *message = NULL,
+ const char *message = nullptr,
bool WarnAboutSize = false) const {
// This is a convenience override.
- return CheckBufferAccess(C, state, Size, Buf, NULL, message, NULL,
+ return CheckBufferAccess(C, state, Size, Buf, nullptr, message, nullptr,
WarnAboutSize);
}
ProgramStateRef CheckOverlap(CheckerContext &C,
@@ -218,22 +220,23 @@ ProgramStateRef CStringChecker::checkNonNull(CheckerContext &C,
const Expr *S, SVal l) const {
// If a previous check has failed, propagate the failure.
if (!state)
- return NULL;
+ return nullptr;
ProgramStateRef stateNull, stateNonNull;
- llvm::tie(stateNull, stateNonNull) = assumeZero(C, state, l, S->getType());
+ std::tie(stateNull, stateNonNull) = assumeZero(C, state, l, S->getType());
if (stateNull && !stateNonNull) {
if (!Filter.CheckCStringNullArg)
- return NULL;
+ return nullptr;
ExplodedNode *N = C.generateSink(stateNull);
if (!N)
- return NULL;
+ return nullptr;
if (!BT_Null)
- BT_Null.reset(new BuiltinBug(categories::UnixAPI,
- "Null pointer argument in call to byte string function"));
+ BT_Null.reset(new BuiltinBug(
+ Filter.CheckNameCStringNullArg, categories::UnixAPI,
+ "Null pointer argument in call to byte string function"));
SmallString<80> buf;
llvm::raw_svector_ostream os(buf);
@@ -247,7 +250,7 @@ ProgramStateRef CStringChecker::checkNonNull(CheckerContext &C,
report->addRange(S->getSourceRange());
bugreporter::trackNullOrUndefValue(N, S, *report);
C.emitReport(report);
- return NULL;
+ return nullptr;
}
// From here on, assume that the value is non-null.
@@ -262,7 +265,7 @@ ProgramStateRef CStringChecker::CheckLocation(CheckerContext &C,
const char *warningMsg) const {
// If a previous check has failed, propagate the failure.
if (!state)
- return NULL;
+ return nullptr;
// Check for out of bound array element access.
const MemRegion *R = l.getAsRegion();
@@ -291,11 +294,12 @@ ProgramStateRef CStringChecker::CheckLocation(CheckerContext &C,
if (StOutBound && !StInBound) {
ExplodedNode *N = C.generateSink(StOutBound);
if (!N)
- return NULL;
+ return nullptr;
if (!BT_Bounds) {
- BT_Bounds.reset(new BuiltinBug("Out-of-bound array access",
- "Byte string function accesses out-of-bound array element"));
+ BT_Bounds.reset(new BuiltinBug(
+ Filter.CheckNameCStringOutOfBounds, "Out-of-bound array access",
+ "Byte string function accesses out-of-bound array element"));
}
BuiltinBug *BT = static_cast<BuiltinBug*>(BT_Bounds.get());
@@ -321,7 +325,7 @@ ProgramStateRef CStringChecker::CheckLocation(CheckerContext &C,
report->addRange(S->getSourceRange());
C.emitReport(report);
- return NULL;
+ return nullptr;
}
// Array bound check succeeded. From this point forward the array bound
@@ -339,7 +343,7 @@ ProgramStateRef CStringChecker::CheckBufferAccess(CheckerContext &C,
bool WarnAboutSize) const {
// If a previous check has failed, propagate the failure.
if (!state)
- return NULL;
+ return nullptr;
SValBuilder &svalBuilder = C.getSValBuilder();
ASTContext &Ctx = svalBuilder.getContext();
@@ -352,7 +356,7 @@ ProgramStateRef CStringChecker::CheckBufferAccess(CheckerContext &C,
SVal BufVal = state->getSVal(FirstBuf, LCtx);
state = checkNonNull(C, state, FirstBuf, BufVal);
if (!state)
- return NULL;
+ return nullptr;
// If out-of-bounds checking is turned off, skip the rest.
if (!Filter.CheckCStringOutOfBounds)
@@ -382,7 +386,7 @@ ProgramStateRef CStringChecker::CheckBufferAccess(CheckerContext &C,
// If the buffer isn't large enough, abort.
if (!state)
- return NULL;
+ return nullptr;
}
// If there's a second buffer, check it as well.
@@ -390,7 +394,7 @@ ProgramStateRef CStringChecker::CheckBufferAccess(CheckerContext &C,
BufVal = state->getSVal(SecondBuf, LCtx);
state = checkNonNull(C, state, SecondBuf, BufVal);
if (!state)
- return NULL;
+ return nullptr;
BufStart = svalBuilder.evalCast(BufVal, PtrTy, SecondBuf->getType());
if (Optional<Loc> BufLoc = BufStart.getAs<Loc>()) {
@@ -420,7 +424,7 @@ ProgramStateRef CStringChecker::CheckOverlap(CheckerContext &C,
// If a previous check has failed, propagate the failure.
if (!state)
- return NULL;
+ return nullptr;
ProgramStateRef stateTrue, stateFalse;
@@ -439,13 +443,13 @@ ProgramStateRef CStringChecker::CheckOverlap(CheckerContext &C,
// Are the two values the same?
SValBuilder &svalBuilder = C.getSValBuilder();
- llvm::tie(stateTrue, stateFalse) =
+ std::tie(stateTrue, stateFalse) =
state->assume(svalBuilder.evalEQ(state, *firstLoc, *secondLoc));
if (stateTrue && !stateFalse) {
// If the values are known to be equal, that's automatically an overlap.
emitOverlapBug(C, stateTrue, First, Second);
- return NULL;
+ return nullptr;
}
// assume the two expressions are not equal.
@@ -461,7 +465,7 @@ ProgramStateRef CStringChecker::CheckOverlap(CheckerContext &C,
if (!reverseTest)
return state;
- llvm::tie(stateTrue, stateFalse) = state->assume(*reverseTest);
+ std::tie(stateTrue, stateFalse) = state->assume(*reverseTest);
if (stateTrue) {
if (stateFalse) {
// If we don't know which one comes first, we can't perform this test.
@@ -506,12 +510,12 @@ ProgramStateRef CStringChecker::CheckOverlap(CheckerContext &C,
if (!OverlapTest)
return state;
- llvm::tie(stateTrue, stateFalse) = state->assume(*OverlapTest);
+ std::tie(stateTrue, stateFalse) = state->assume(*OverlapTest);
if (stateTrue && !stateFalse) {
// Overlap!
emitOverlapBug(C, stateTrue, First, Second);
- return NULL;
+ return nullptr;
}
// assume the two expressions don't overlap.
@@ -526,7 +530,8 @@ void CStringChecker::emitOverlapBug(CheckerContext &C, ProgramStateRef state,
return;
if (!BT_Overlap)
- BT_Overlap.reset(new BugType(categories::UnixAPI, "Improper arguments"));
+ BT_Overlap.reset(new BugType(Filter.CheckNameCStringBufferOverlap,
+ categories::UnixAPI, "Improper arguments"));
// Generate a report for this bug.
BugReport *report =
@@ -548,7 +553,7 @@ ProgramStateRef CStringChecker::checkAdditionOverflow(CheckerContext &C,
// If a previous check has failed, propagate the failure.
if (!state)
- return NULL;
+ return nullptr;
SValBuilder &svalBuilder = C.getSValBuilder();
BasicValueFactory &BVF = svalBuilder.getBasicValueFactory();
@@ -576,18 +581,19 @@ ProgramStateRef CStringChecker::checkAdditionOverflow(CheckerContext &C,
*maxMinusRightNL, cmpTy);
ProgramStateRef stateOverflow, stateOkay;
- llvm::tie(stateOverflow, stateOkay) =
+ std::tie(stateOverflow, stateOkay) =
state->assume(willOverflow.castAs<DefinedOrUnknownSVal>());
if (stateOverflow && !stateOkay) {
// We have an overflow. Emit a bug report.
ExplodedNode *N = C.generateSink(stateOverflow);
if (!N)
- return NULL;
+ return nullptr;
if (!BT_AdditionOverflow)
- BT_AdditionOverflow.reset(new BuiltinBug("API",
- "Sum of expressions causes overflow"));
+ BT_AdditionOverflow.reset(
+ new BuiltinBug(Filter.CheckNameCStringOutOfBounds, "API",
+ "Sum of expressions causes overflow"));
// This isn't a great error message, but this should never occur in real
// code anyway -- you'd have to create a buffer longer than a size_t can
@@ -600,7 +606,7 @@ ProgramStateRef CStringChecker::checkAdditionOverflow(CheckerContext &C,
BugReport *report = new BugReport(*BT_AdditionOverflow, warning, N);
C.emitReport(report);
- return NULL;
+ return nullptr;
}
// From now on, assume an overflow didn't occur.
@@ -703,8 +709,9 @@ SVal CStringChecker::getCStringLength(CheckerContext &C, ProgramStateRef &state,
if (ExplodedNode *N = C.addTransition(state)) {
if (!BT_NotCString)
- BT_NotCString.reset(new BuiltinBug(categories::UnixAPI,
- "Argument is not a null-terminated string."));
+ BT_NotCString.reset(new BuiltinBug(
+ Filter.CheckNameCStringNotNullTerm, categories::UnixAPI,
+ "Argument is not a null-terminated string."));
SmallString<120> buf;
llvm::raw_svector_ostream os(buf);
@@ -714,8 +721,7 @@ SVal CStringChecker::getCStringLength(CheckerContext &C, ProgramStateRef &state,
<< "', which is not a null-terminated string";
// Generate a report for this bug.
- BugReport *report = new BugReport(*BT_NotCString,
- os.str(), N);
+ BugReport *report = new BugReport(*BT_NotCString, os.str(), N);
report->addRange(Ex->getSourceRange());
C.emitReport(report);
@@ -763,8 +769,9 @@ SVal CStringChecker::getCStringLength(CheckerContext &C, ProgramStateRef &state,
if (ExplodedNode *N = C.addTransition(state)) {
if (!BT_NotCString)
- BT_NotCString.reset(new BuiltinBug(categories::UnixAPI,
- "Argument is not a null-terminated string."));
+ BT_NotCString.reset(new BuiltinBug(
+ Filter.CheckNameCStringNotNullTerm, categories::UnixAPI,
+ "Argument is not a null-terminated string."));
SmallString<120> buf;
llvm::raw_svector_ostream os(buf);
@@ -795,7 +802,7 @@ const StringLiteral *CStringChecker::getCStringLiteral(CheckerContext &C,
// Get the memory region pointed to by the val.
const MemRegion *bufRegion = val.getAsRegion();
if (!bufRegion)
- return NULL;
+ return nullptr;
// Strip casts off the memory region.
bufRegion = bufRegion->StripCasts();
@@ -803,7 +810,7 @@ const StringLiteral *CStringChecker::getCStringLiteral(CheckerContext &C,
// Cast the memory region to a string region.
const StringRegion *strRegion= dyn_cast<StringRegion>(bufRegion);
if (!strRegion)
- return NULL;
+ return nullptr;
// Return the actual string in the string region.
return strRegion->getStringLiteral();
@@ -845,7 +852,8 @@ ProgramStateRef CStringChecker::InvalidateBuffer(CheckerContext &C,
}
return state->invalidateRegions(R, E, C.blockCount(), LCtx,
- CausesPointerEscape, 0, 0, &ITraits);
+ CausesPointerEscape, nullptr, nullptr,
+ &ITraits);
}
// If we have a non-region value by chance, just remove the binding.
@@ -909,7 +917,7 @@ void CStringChecker::evalCopyCommon(CheckerContext &C,
QualType sizeTy = Size->getType();
ProgramStateRef stateZeroSize, stateNonZeroSize;
- llvm::tie(stateZeroSize, stateNonZeroSize) =
+ std::tie(stateZeroSize, stateNonZeroSize) =
assumeZero(C, state, sizeVal, sizeTy);
// Get the value of the Dest.
@@ -946,7 +954,7 @@ void CStringChecker::evalCopyCommon(CheckerContext &C,
const char * const writeWarning =
"Memory copy function overflows destination buffer";
state = CheckBufferAccess(C, state, Size, Dest, Source,
- writeWarning, /* sourceWarning = */ NULL);
+ writeWarning, /* sourceWarning = */ nullptr);
if (Restricted)
state = CheckOverlap(C, state, Size, Dest, Source);
@@ -971,7 +979,7 @@ void CStringChecker::evalCopyCommon(CheckerContext &C,
} else {
// If we don't know how much we copied, we can at least
// conjure a return value for later.
- SVal result = C.getSValBuilder().conjureSymbolVal(0, CE, LCtx,
+ SVal result = C.getSValBuilder().conjureSymbolVal(nullptr, CE, LCtx,
C.blockCount());
state = state->BindExpr(CE, LCtx, result);
}
@@ -1066,7 +1074,7 @@ void CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE) const {
QualType sizeTy = Size->getType();
ProgramStateRef stateZeroSize, stateNonZeroSize;
- llvm::tie(stateZeroSize, stateNonZeroSize) =
+ std::tie(stateZeroSize, stateNonZeroSize) =
assumeZero(C, state, sizeVal, sizeTy);
// If the size can be zero, the result will be 0 in that case, and we don't
@@ -1092,7 +1100,7 @@ void CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE) const {
// See if they are the same.
DefinedOrUnknownSVal SameBuf = svalBuilder.evalEQ(state, LV, RV);
ProgramStateRef StSameBuf, StNotSameBuf;
- llvm::tie(StSameBuf, StNotSameBuf) = state->assume(SameBuf);
+ std::tie(StSameBuf, StNotSameBuf) = state->assume(SameBuf);
// If the two arguments might be the same buffer, we know the result is 0,
// and we only need to check one size.
@@ -1113,7 +1121,8 @@ void CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE) const {
state = CheckBufferAccess(C, state, Size, Left, Right);
if (state) {
// The return value is the comparison result, which we don't know.
- SVal CmpV = svalBuilder.conjureSymbolVal(0, CE, LCtx, C.blockCount());
+ SVal CmpV = svalBuilder.conjureSymbolVal(nullptr, CE, LCtx,
+ C.blockCount());
state = state->BindExpr(CE, LCtx, CmpV);
C.addTransition(state);
}
@@ -1150,7 +1159,7 @@ void CStringChecker::evalstrLengthCommon(CheckerContext &C, const CallExpr *CE,
SVal maxlenVal = state->getSVal(maxlenExpr, LCtx);
ProgramStateRef stateZeroSize, stateNonZeroSize;
- llvm::tie(stateZeroSize, stateNonZeroSize) =
+ std::tie(stateZeroSize, stateNonZeroSize) =
assumeZero(C, state, maxlenVal, maxlenExpr->getType());
// If the size can be zero, the result will be 0 in that case, and we don't
@@ -1204,10 +1213,10 @@ void CStringChecker::evalstrLengthCommon(CheckerContext &C, const CallExpr *CE,
ProgramStateRef stateStringTooLong, stateStringNotTooLong;
// Check if the strLength is greater than the maxlen.
- llvm::tie(stateStringTooLong, stateStringNotTooLong) =
- state->assume(C.getSValBuilder().evalBinOpNN(
- state, BO_GT, *strLengthNL, *maxlenValNL, cmpTy)
- .castAs<DefinedOrUnknownSVal>());
+ std::tie(stateStringTooLong, stateStringNotTooLong) = state->assume(
+ C.getSValBuilder()
+ .evalBinOpNN(state, BO_GT, *strLengthNL, *maxlenValNL, cmpTy)
+ .castAs<DefinedOrUnknownSVal>());
if (stateStringTooLong && !stateStringNotTooLong) {
// If the string is longer than maxlen, return maxlen.
@@ -1223,7 +1232,8 @@ void CStringChecker::evalstrLengthCommon(CheckerContext &C, const CallExpr *CE,
// no guarantee the full string length will actually be returned.
// All we know is the return value is the min of the string length
// and the limit. This is better than nothing.
- result = C.getSValBuilder().conjureSymbolVal(0, CE, LCtx, C.blockCount());
+ result = C.getSValBuilder().conjureSymbolVal(nullptr, CE, LCtx,
+ C.blockCount());
NonLoc resultNL = result.castAs<NonLoc>();
if (strLengthNL) {
@@ -1246,7 +1256,8 @@ void CStringChecker::evalstrLengthCommon(CheckerContext &C, const CallExpr *CE,
// If we don't know the length of the string, conjure a return
// value, so it can be used in constraints, at least.
if (result.isUnknown()) {
- result = C.getSValBuilder().conjureSymbolVal(0, CE, LCtx, C.blockCount());
+ result = C.getSValBuilder().conjureSymbolVal(nullptr, CE, LCtx,
+ C.blockCount());
}
}
@@ -1349,7 +1360,7 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
// - potential overflows caused by a bound that could exceed the destination
SVal amountCopied = UnknownVal();
SVal maxLastElementIndex = UnknownVal();
- const char *boundWarning = NULL;
+ const char *boundWarning = nullptr;
// If the function is strncpy, strncat, etc... it is bounded.
if (isBounded) {
@@ -1371,7 +1382,7 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
// Check if the max number to copy is less than the length of the src.
// If the bound is equal to the source length, strncpy won't null-
// terminate the result!
- llvm::tie(stateSourceTooLong, stateSourceNotTooLong) = state->assume(
+ std::tie(stateSourceTooLong, stateSourceNotTooLong) = state->assume(
svalBuilder.evalBinOpNN(state, BO_GE, *strLengthNL, *lenValNL, cmpTy)
.castAs<DefinedOrUnknownSVal>());
@@ -1418,7 +1429,7 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
// case strncpy will do no work at all. Our bounds check uses n-1
// as the last element accessed, so n == 0 is problematic.
ProgramStateRef StateZeroSize, StateNonZeroSize;
- llvm::tie(StateZeroSize, StateNonZeroSize) =
+ std::tie(StateZeroSize, StateNonZeroSize) =
assumeZero(C, state, *lenValNL, sizeTy);
// If the size is known to be zero, we're done.
@@ -1629,7 +1640,7 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
// If this is a stpcpy-style copy, but we were unable to check for a buffer
// overflow, we still need a result. Conjure a return value.
if (returnEnd && Result.isUnknown()) {
- Result = svalBuilder.conjureSymbolVal(0, CE, LCtx, C.blockCount());
+ Result = svalBuilder.conjureSymbolVal(nullptr, CE, LCtx, C.blockCount());
}
// Set the return value.
@@ -1711,7 +1722,7 @@ void CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallExpr *CE,
SValBuilder &svalBuilder = C.getSValBuilder();
DefinedOrUnknownSVal SameBuf = svalBuilder.evalEQ(state, LV, RV);
ProgramStateRef StSameBuf, StNotSameBuf;
- llvm::tie(StSameBuf, StNotSameBuf) = state->assume(SameBuf);
+ std::tie(StSameBuf, StNotSameBuf) = state->assume(SameBuf);
// If the two arguments might be the same buffer, we know the result is 0,
// and we only need to check one size.
@@ -1786,7 +1797,8 @@ void CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallExpr *CE,
if (!canComputeResult) {
// Conjure a symbolic value. It's the best we can do.
- SVal resultVal = svalBuilder.conjureSymbolVal(0, CE, LCtx, C.blockCount());
+ SVal resultVal = svalBuilder.conjureSymbolVal(nullptr, CE, LCtx,
+ C.blockCount());
state = state->BindExpr(CE, LCtx, resultVal);
}
@@ -1843,7 +1855,7 @@ void CStringChecker::evalStrsep(CheckerContext &C, const CallExpr *CE) const {
} else {
assert(SearchStrVal.isUnknown());
// Conjure a symbolic value. It's the best we can do.
- Result = SVB.conjureSymbolVal(0, CE, LCtx, C.blockCount());
+ Result = SVB.conjureSymbolVal(nullptr, CE, LCtx, C.blockCount());
}
// Set the return value, and finish.
@@ -1863,7 +1875,7 @@ bool CStringChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
return false;
// FIXME: Poorly-factored string switches are slow.
- FnCheck evalFunction = 0;
+ FnCheck evalFunction = nullptr;
if (C.isCLibraryFunction(FDecl, "memcpy"))
evalFunction = &CStringChecker::evalMemcpy;
else if (C.isCLibraryFunction(FDecl, "mempcpy"))
@@ -1907,7 +1919,7 @@ bool CStringChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
// Make sure each function sets its own description.
// (But don't bother in a release build.)
- assert(!(CurrentFunctionDescription = NULL));
+ assert(!(CurrentFunctionDescription = nullptr));
// Check and evaluate the call.
(this->*evalFunction)(C, CE);
@@ -1928,9 +1940,8 @@ void CStringChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
// Record string length for char a[] = "abc";
ProgramStateRef state = C.getState();
- for (DeclStmt::const_decl_iterator I = DS->decl_begin(), E = DS->decl_end();
- I != E; ++I) {
- const VarDecl *D = dyn_cast<VarDecl>(*I);
+ for (const auto *I : DS->decls()) {
+ const VarDecl *D = dyn_cast<VarDecl>(I);
if (!D)
continue;
@@ -2057,10 +2068,12 @@ void CStringChecker::checkDeadSymbols(SymbolReaper &SR,
C.addTransition(state);
}
-#define REGISTER_CHECKER(name) \
-void ento::register##name(CheckerManager &mgr) {\
- mgr.registerChecker<CStringChecker>()->Filter.Check##name = true; \
-}
+#define REGISTER_CHECKER(name) \
+ void ento::register##name(CheckerManager &mgr) { \
+ CStringChecker *checker = mgr.registerChecker<CStringChecker>(); \
+ checker->Filter.Check##name = true; \
+ checker->Filter.CheckName##name = mgr.getCurrentCheckName(); \
+ }
REGISTER_CHECKER(CStringNullArg)
REGISTER_CHECKER(CStringOutOfBounds)
OpenPOWER on IntegriCloud