27 #include "llvm/Support/YAMLTraits.h" 30 #include <unordered_map> 33 using namespace clang;
35 using namespace taint;
38 class GenericTaintChecker
39 :
public Checker<check::PostStmt<CallExpr>, check::PreStmt<CallExpr>> {
41 static void *getTag() {
46 void checkPostStmt(
const CallExpr *CE, CheckerContext &C)
const;
48 void checkPreStmt(
const CallExpr *CE, CheckerContext &C)
const;
51 const char *Sep)
const override;
56 enum class VariadicType {
None, Src, Dst };
59 struct TaintConfiguration {
60 using NameScopeArgs = std::tuple<std::string, std::string, ArgVector>;
66 SignedArgVector DstArgs;
71 std::vector<Propagation> Propagations;
72 std::vector<NameScopeArgs> Filters;
73 std::vector<NameScopeArgs> Sinks;
75 TaintConfiguration() =
default;
76 TaintConfiguration(
const TaintConfiguration &) =
default;
77 TaintConfiguration(TaintConfiguration &&) =
default;
78 TaintConfiguration &operator=(
const TaintConfiguration &) =
default;
79 TaintConfiguration &operator=(TaintConfiguration &&) =
default;
83 ArgVector convertToArgVector(CheckerManager &Mgr,
const std::string &Option,
84 SignedArgVector Args);
88 TaintConfiguration &&Config);
96 mutable std::unique_ptr<BugType> BT;
97 void initBugType()
const {
99 BT.reset(
new BugType(
this,
"Use of Untrusted Data",
"Untrusted Data"));
102 struct FunctionData {
103 FunctionData() =
delete;
104 FunctionData(
const FunctionData &) =
default;
105 FunctionData(FunctionData &&) =
default;
106 FunctionData &operator=(
const FunctionData &) =
delete;
107 FunctionData &operator=(FunctionData &&) =
delete;
110 const CheckerContext &C) {
113 FDecl->
getKind() != Decl::CXXMethod))
116 StringRef Name = C.getCalleeName(FDecl);
118 if (Name.empty() || FullName.empty())
121 return FunctionData{FDecl, Name, FullName};
124 bool isInScope(StringRef
Scope)
const {
125 return StringRef(FullName).startswith(Scope);
129 const StringRef Name;
130 const std::string FullName;
135 bool checkPre(
const CallExpr *CE,
const FunctionData &FData,
136 CheckerContext &C)
const;
139 bool addSourcesPre(
const CallExpr *CE,
const FunctionData &FData,
140 CheckerContext &C)
const;
144 bool addFiltersPre(
const CallExpr *CE,
const FunctionData &FData,
145 CheckerContext &C)
const;
148 bool propagateFromPre(
const CallExpr *CE, CheckerContext &C)
const;
152 static bool isStdin(
const Expr *E, CheckerContext &C);
158 static constexpr llvm::StringLiteral MsgUncontrolledFormatString =
159 "Untrusted data is used as a format string " 160 "(CWE-134: Uncontrolled Format String)";
161 bool checkUncontrolledFormatString(
const CallExpr *CE,
162 CheckerContext &C)
const;
167 static constexpr llvm::StringLiteral MsgSanitizeSystemArgs =
168 "Untrusted data is passed to a system call " 169 "(CERT/STR02-C. Sanitize data passed to complex subsystems)";
170 bool checkSystemCall(
const CallExpr *CE, StringRef Name,
171 CheckerContext &C)
const;
175 static constexpr llvm::StringLiteral MsgTaintedBufferSize =
176 "Untrusted data is used to specify the buffer size " 177 "(CERT/STR31-C. Guarantee that storage for strings has sufficient space " 178 "for character data and the null terminator)";
180 CheckerContext &C)
const;
183 static constexpr llvm::StringLiteral MsgCustomSink =
184 "Untrusted data is passed to a user-defined sink";
185 bool checkCustomSinks(
const CallExpr *CE,
const FunctionData &FData,
186 CheckerContext &C)
const;
189 bool generateReportIfTainted(
const Expr *E, StringRef Msg,
190 CheckerContext &C)
const;
192 struct TaintPropagationRule;
193 template <
typename T>
194 using ConfigDataMap =
195 std::unordered_multimap<std::string, std::pair<std::string, T>>;
196 using NameRuleMap = ConfigDataMap<TaintPropagationRule>;
197 using NameArgMap = ConfigDataMap<ArgVector>;
201 template <
typename T>
202 static auto findFunctionInConfig(
const ConfigDataMap<T> &Map,
203 const FunctionData &FData);
214 struct TaintPropagationRule {
215 using PropagationFuncType =
bool (*)(
bool IsTainted,
const CallExpr *,
223 unsigned VariadicIndex;
226 VariadicType VarType;
229 PropagationFuncType PropagationFunc;
231 TaintPropagationRule()
232 : VariadicIndex(InvalidArgIndex), VarType(VariadicType::
None),
233 PropagationFunc(nullptr) {}
235 TaintPropagationRule(ArgVector &&Src, ArgVector &&Dst,
237 unsigned VarIndex = InvalidArgIndex,
238 PropagationFuncType Func =
nullptr)
239 : SrcArgs(
std::move(Src)), DstArgs(
std::move(Dst)),
240 VariadicIndex(VarIndex), VarType(Var), PropagationFunc(Func) {}
243 static TaintPropagationRule
244 getTaintPropagationRule(
const NameRuleMap &CustomPropagations,
245 const FunctionData &FData, CheckerContext &C);
247 void addSrcArg(
unsigned A) { SrcArgs.push_back(A); }
248 void addDstArg(
unsigned A) { DstArgs.push_back(A); }
250 bool isNull()
const {
251 return SrcArgs.empty() && DstArgs.empty() &&
255 bool isDestinationArgument(
unsigned ArgNum)
const {
256 return (llvm::find(DstArgs, ArgNum) != DstArgs.end());
261 if (
isTainted(State, E, C.getLocationContext()) || isStdin(E, C))
276 static bool postSocket(
bool IsTainted,
const CallExpr *CE,
282 NameRuleMap CustomPropagations;
286 NameArgMap CustomFilters;
289 NameArgMap CustomSinks;
292 const unsigned GenericTaintChecker::ReturnValueIndex;
293 const unsigned GenericTaintChecker::InvalidArgIndex;
296 constexpr llvm::StringLiteral GenericTaintChecker::MsgUncontrolledFormatString;
297 constexpr llvm::StringLiteral GenericTaintChecker::MsgSanitizeSystemArgs;
298 constexpr llvm::StringLiteral GenericTaintChecker::MsgTaintedBufferSize;
299 constexpr llvm::StringLiteral GenericTaintChecker::MsgCustomSink;
304 LLVM_YAML_IS_SEQUENCE_VECTOR(TaintConfig::Propagation)
305 LLVM_YAML_IS_SEQUENCE_VECTOR(TaintConfig::NameScopeArgs)
311 IO.mapOptional(
"Propagations", Config.Propagations);
312 IO.mapOptional(
"Filters", Config.Filters);
313 IO.mapOptional(
"Sinks", Config.Sinks);
318 static void mapping(IO &IO, TaintConfig::Propagation &Propagation) {
319 IO.mapRequired(
"Name", Propagation.Name);
320 IO.mapOptional(
"Scope", Propagation.Scope);
321 IO.mapOptional(
"SrcArgs", Propagation.SrcArgs);
322 IO.mapOptional(
"DstArgs", Propagation.DstArgs);
323 IO.mapOptional(
"VariadicType", Propagation.VarType,
325 IO.mapOptional(
"VariadicIndex", Propagation.VarIndex,
326 GenericTaintChecker::InvalidArgIndex);
330 template <>
struct ScalarEnumerationTraits<GenericTaintChecker::VariadicType> {
333 IO.enumCase(Value,
"Src", GenericTaintChecker::VariadicType::Src);
334 IO.enumCase(Value,
"Dst", GenericTaintChecker::VariadicType::Dst);
339 static void mapping(IO &IO, TaintConfig::NameScopeArgs &NSA) {
340 IO.mapRequired(
"Name", std::get<0>(NSA));
341 IO.mapOptional(
"Scope", std::get<1>(NSA));
342 IO.mapRequired(
"Args", std::get<2>(NSA));
355 CheckerManager &Mgr,
const std::string &Option, SignedArgVector Args) {
357 for (
int Arg : Args) {
359 Result.push_back(ReturnValueIndex);
361 Result.push_back(InvalidArgIndex);
362 Mgr.reportInvalidCheckerOptionValue(
364 "an argument number for propagation rules greater or equal to -1");
366 Result.push_back(static_cast<unsigned>(Arg));
372 const std::string &Option,
373 TaintConfiguration &&Config) {
374 for (
auto &
P : Config.Propagations) {
375 GenericTaintChecker::CustomPropagations.emplace(
377 std::make_pair(
P.Scope, TaintPropagationRule{
378 std::move(P.SrcArgs),
379 convertToArgVector(Mgr, Option, P.DstArgs),
380 P.VarType, P.VarIndex}));
383 for (
auto &F : Config.Filters) {
384 GenericTaintChecker::CustomFilters.emplace(
386 std::make_pair(std::move(std::get<1>(F)), std::move(std::get<2>(F))));
389 for (
auto &S : Config.Sinks) {
390 GenericTaintChecker::CustomSinks.emplace(
392 std::make_pair(std::move(std::get<1>(S)), std::move(std::get<2>(S))));
396 template <
typename T>
397 auto GenericTaintChecker::findFunctionInConfig(
const ConfigDataMap<T> &Map,
398 const FunctionData &FData) {
399 auto Range = Map.equal_range(FData.Name);
401 std::find_if(Range.first, Range.second, [&FData](
const auto &Entry) {
402 const auto &Value = Entry.second;
403 StringRef Scope = Value.first;
404 return Scope.empty() || FData.isInScope(Scope);
406 return It != Range.second ? It : Map.end();
409 GenericTaintChecker::TaintPropagationRule
410 GenericTaintChecker::TaintPropagationRule::getTaintPropagationRule(
411 const NameRuleMap &CustomPropagations,
const FunctionData &FData,
418 TaintPropagationRule Rule =
419 llvm::StringSwitch<TaintPropagationRule>(FData.FullName)
422 .Case(
"fdopen", TaintPropagationRule({}, {ReturnValueIndex}))
423 .Case(
"fopen", TaintPropagationRule({}, {ReturnValueIndex}))
424 .Case(
"freopen", TaintPropagationRule({}, {ReturnValueIndex}))
425 .Case(
"getch", TaintPropagationRule({}, {ReturnValueIndex}))
426 .Case(
"getchar", TaintPropagationRule({}, {ReturnValueIndex}))
427 .Case(
"getchar_unlocked",
428 TaintPropagationRule({}, {ReturnValueIndex}))
429 .Case(
"getenv", TaintPropagationRule({}, {ReturnValueIndex}))
430 .Case(
"gets", TaintPropagationRule({}, {0, ReturnValueIndex}))
431 .Case(
"scanf", TaintPropagationRule({}, {}, VariadicType::Dst, 1))
435 &TaintPropagationRule::postSocket))
436 .Case(
"wgetch", TaintPropagationRule({}, {ReturnValueIndex}))
438 .Case(
"atoi", TaintPropagationRule({0}, {ReturnValueIndex}))
439 .Case(
"atol", TaintPropagationRule({0}, {ReturnValueIndex}))
440 .Case(
"atoll", TaintPropagationRule({0}, {ReturnValueIndex}))
441 .Case(
"fgetc", TaintPropagationRule({0}, {ReturnValueIndex}))
442 .Case(
"fgetln", TaintPropagationRule({0}, {ReturnValueIndex}))
443 .Case(
"fgets", TaintPropagationRule({2}, {0, ReturnValueIndex}))
444 .Case(
"fscanf", TaintPropagationRule({0}, {}, VariadicType::Dst, 2))
445 .Case(
"getc", TaintPropagationRule({0}, {ReturnValueIndex}))
446 .Case(
"getc_unlocked", TaintPropagationRule({0}, {ReturnValueIndex}))
447 .Case(
"getdelim", TaintPropagationRule({3}, {0}))
448 .Case(
"getline", TaintPropagationRule({2}, {0}))
449 .Case(
"getw", TaintPropagationRule({0}, {ReturnValueIndex}))
451 TaintPropagationRule({0, 1, 2, 3}, {1, ReturnValueIndex}))
452 .Case(
"read", TaintPropagationRule({0, 2}, {1, ReturnValueIndex}))
453 .Case(
"strchr", TaintPropagationRule({0}, {ReturnValueIndex}))
454 .Case(
"strrchr", TaintPropagationRule({0}, {ReturnValueIndex}))
455 .Case(
"tolower", TaintPropagationRule({0}, {ReturnValueIndex}))
456 .Case(
"toupper", TaintPropagationRule({0}, {ReturnValueIndex}))
457 .Default(TaintPropagationRule());
468 case Builtin::BImemcpy:
469 case Builtin::BImemmove:
470 case Builtin::BIstrncpy:
471 case Builtin::BIstrncat:
472 return TaintPropagationRule({1, 2}, {0, ReturnValueIndex});
473 case Builtin::BIstrlcpy:
474 case Builtin::BIstrlcat:
475 return TaintPropagationRule({1, 2}, {0});
476 case Builtin::BIstrndup:
477 return TaintPropagationRule({0, 1}, {ReturnValueIndex});
485 if (C.isCLibraryFunction(FDecl,
"snprintf"))
486 return TaintPropagationRule({1}, {0, ReturnValueIndex}, VariadicType::Src,
488 else if (C.isCLibraryFunction(FDecl,
"sprintf"))
489 return TaintPropagationRule({}, {0, ReturnValueIndex}, VariadicType::Src,
491 else if (C.isCLibraryFunction(FDecl,
"strcpy") ||
492 C.isCLibraryFunction(FDecl,
"stpcpy") ||
493 C.isCLibraryFunction(FDecl,
"strcat"))
494 return TaintPropagationRule({1}, {0, ReturnValueIndex});
495 else if (C.isCLibraryFunction(FDecl,
"bcopy"))
496 return TaintPropagationRule({0, 2}, {1});
497 else if (C.isCLibraryFunction(FDecl,
"strdup") ||
498 C.isCLibraryFunction(FDecl,
"strdupa"))
499 return TaintPropagationRule({0}, {ReturnValueIndex});
500 else if (C.isCLibraryFunction(FDecl,
"wcsdup"))
501 return TaintPropagationRule({0}, {ReturnValueIndex});
508 auto It = findFunctionInConfig(CustomPropagations, FData);
509 if (It != CustomPropagations.end()) {
510 const auto &
Value = It->second;
514 return TaintPropagationRule();
517 void GenericTaintChecker::checkPreStmt(
const CallExpr *CE,
518 CheckerContext &C)
const {
525 if (checkPre(CE, *FData, C))
530 if (addSourcesPre(CE, *FData, C))
533 addFiltersPre(CE, *FData, C);
536 void GenericTaintChecker::checkPostStmt(
const CallExpr *CE,
537 CheckerContext &C)
const {
540 propagateFromPre(CE, C);
543 void GenericTaintChecker::printState(raw_ostream &Out,
ProgramStateRef State,
544 const char *NL,
const char *Sep)
const {
548 bool GenericTaintChecker::addSourcesPre(
const CallExpr *CE,
549 const FunctionData &FData,
550 CheckerContext &C)
const {
552 TaintPropagationRule Rule = TaintPropagationRule::getTaintPropagationRule(
553 this->CustomPropagations, FData, C);
554 if (!Rule.isNull()) {
557 C.addTransition(State);
564 bool GenericTaintChecker::addFiltersPre(
const CallExpr *CE,
565 const FunctionData &FData,
566 CheckerContext &C)
const {
567 auto It = findFunctionInConfig(CustomFilters, FData);
568 if (It == CustomFilters.end())
572 const auto &
Value = It->second;
573 const ArgVector &Args =
Value.second;
574 for (
unsigned ArgNum : Args) {
584 if (State != C.getState()) {
585 C.addTransition(State);
591 bool GenericTaintChecker::propagateFromPre(
const CallExpr *CE,
592 CheckerContext &C)
const {
598 TaintArgsOnPostVisitTy TaintArgs = State->get<TaintArgsOnPostVisit>();
599 if (TaintArgs.isEmpty())
602 for (
unsigned ArgNum : TaintArgs) {
604 if (ArgNum == ReturnValueIndex) {
605 State =
addTaint(State, CE, C.getLocationContext());
620 State = State->remove<TaintArgsOnPostVisit>();
622 if (State != C.getState()) {
623 C.addTransition(State);
629 bool GenericTaintChecker::checkPre(
const CallExpr *CE,
630 const FunctionData &FData,
631 CheckerContext &C)
const {
633 if (checkUncontrolledFormatString(CE, C))
636 if (checkSystemCall(CE, FData.Name, C))
639 if (checkTaintedBufferSize(CE, FData.FDecl, C))
642 if (checkCustomSinks(CE, FData, C))
648 Optional<SVal> GenericTaintChecker::getPointedToSVal(CheckerContext &C,
652 if (AddrVal.isUnknownOrUndef())
661 return State->getSVal(*AddrLoc);
668 ValTy = C.getASTContext().CharTy;
670 return State->getSVal(*AddrLoc, ValTy);
674 GenericTaintChecker::TaintPropagationRule::process(
const CallExpr *CE,
675 CheckerContext &C)
const {
679 bool IsTainted =
true;
680 for (
unsigned ArgNum : SrcArgs) {
684 if ((IsTainted = isTaintedOrPointsToTainted(CE->
getArg(ArgNum),
State, C)))
689 if (!IsTainted && VariadicType::Src == VarType) {
691 for (
unsigned i = VariadicIndex; i < CE->
getNumArgs(); ++i) {
692 if ((IsTainted = isTaintedOrPointsToTainted(CE->
getArg(i),
State, C)))
698 IsTainted = PropagationFunc(IsTainted, CE, C);
704 for (
unsigned ArgNum : DstArgs) {
706 if (ArgNum == ReturnValueIndex) {
707 State = State->add<TaintArgsOnPostVisit>(ReturnValueIndex);
715 State = State->add<TaintArgsOnPostVisit>(ArgNum);
719 if (VariadicType::Dst == VarType) {
724 for (
unsigned i = VariadicIndex; i < CE->
getNumArgs(); ++i) {
731 State = State->add<TaintArgsOnPostVisit>(i);
739 bool GenericTaintChecker::TaintPropagationRule::postSocket(
bool ,
743 StringRef DomName = C.getMacroNameOrSpelling(DomLoc);
745 if (DomName.equals(
"AF_SYSTEM") || DomName.equals(
"AF_LOCAL") ||
746 DomName.equals(
"AF_UNIX") || DomName.equals(
"AF_RESERVED_36"))
752 bool GenericTaintChecker::isStdin(
const Expr *E, CheckerContext &C) {
754 SVal Val = C.getSVal(E);
757 const MemRegion *MemReg = Val.getAsRegion();
760 const SymbolicRegion *SymReg = dyn_cast_or_null<SymbolicRegion>(MemReg);
765 const SymbolRegionValue *Sm =
766 dyn_cast<SymbolRegionValue>(SymReg->getSymbol());
769 const DeclRegion *DeclReg = dyn_cast_or_null<DeclRegion>(Sm->getRegion());
775 if (
const auto *D = dyn_cast_or_null<VarDecl>(DeclReg->getDecl())) {
776 D = D->getCanonicalDecl();
777 if ((D->getName().find(
"stdin") != StringRef::npos) && D->isExternC()) {
778 const auto *PtrTy = dyn_cast<
PointerType>(D->getType().getTypePtr());
779 if (PtrTy && PtrTy->getPointeeType().getCanonicalType() ==
780 C.getASTContext().getFILEType().getCanonicalType())
788 const CheckerContext &C,
797 ArgNum = Format->getFormatIdx() - 1;
798 if ((Format->getType()->getName() ==
"printf") && CE->
getNumArgs() > ArgNum)
803 if (C.getCalleeName(CE).find(
"setproctitle") != StringRef::npos) {
811 bool GenericTaintChecker::generateReportIfTainted(
const Expr *E, StringRef Msg,
812 CheckerContext &C)
const {
819 if (PointedToSVal &&
isTainted(State, *PointedToSVal))
820 TaintedSVal = *PointedToSVal;
821 else if (
isTainted(State, E, C.getLocationContext()))
822 TaintedSVal = C.getSVal(E);
827 if (ExplodedNode *N = C.generateNonFatalErrorNode()) {
829 auto report = std::make_unique<PathSensitiveBugReport>(*BT, Msg, N);
831 report->addVisitor(std::make_unique<TaintBugVisitor>(TaintedSVal));
832 C.emitReport(std::move(report));
838 bool GenericTaintChecker::checkUncontrolledFormatString(
839 const CallExpr *CE, CheckerContext &C)
const {
847 return generateReportIfTainted(CE->
getArg(ArgNum),
848 MsgUncontrolledFormatString, C);
851 bool GenericTaintChecker::checkSystemCall(
const CallExpr *CE, StringRef Name,
852 CheckerContext &C)
const {
856 unsigned ArgNum = llvm::StringSwitch<unsigned>(Name)
867 .Default(InvalidArgIndex);
869 if (ArgNum == InvalidArgIndex || CE->
getNumArgs() < (ArgNum + 1))
872 return generateReportIfTainted(CE->
getArg(ArgNum), MsgSanitizeSystemArgs, C);
877 bool GenericTaintChecker::checkTaintedBufferSize(
const CallExpr *CE,
879 CheckerContext &C)
const {
881 unsigned ArgNum = InvalidArgIndex;
885 case Builtin::BImemcpy:
886 case Builtin::BImemmove:
887 case Builtin::BIstrncpy:
890 case Builtin::BIstrndup:
897 if (ArgNum == InvalidArgIndex) {
898 if (C.isCLibraryFunction(FDecl,
"malloc") ||
899 C.isCLibraryFunction(FDecl,
"calloc") ||
900 C.isCLibraryFunction(FDecl,
"alloca"))
902 else if (C.isCLibraryFunction(FDecl,
"memccpy"))
904 else if (C.isCLibraryFunction(FDecl,
"realloc"))
906 else if (C.isCLibraryFunction(FDecl,
"bcopy"))
910 return ArgNum != InvalidArgIndex && CE->
getNumArgs() > ArgNum &&
911 generateReportIfTainted(CE->
getArg(ArgNum), MsgTaintedBufferSize, C);
914 bool GenericTaintChecker::checkCustomSinks(
const CallExpr *CE,
915 const FunctionData &FData,
916 CheckerContext &C)
const {
917 auto It = findFunctionInConfig(CustomSinks, FData);
918 if (It == CustomSinks.end())
921 const auto &
Value = It->second;
922 const GenericTaintChecker::ArgVector &Args =
Value.second;
923 for (
unsigned ArgNum : Args) {
927 if (generateReportIfTainted(CE->
getArg(ArgNum), MsgCustomSink, C))
934 void ento::registerGenericTaintChecker(CheckerManager &Mgr) {
935 auto *Checker = Mgr.registerChecker<GenericTaintChecker>();
936 std::string Option{
"Config"};
937 StringRef ConfigFile =
938 Mgr.getAnalyzerOptions().getCheckerStringOption(Checker, Option);
940 getConfiguration<TaintConfig>(Mgr, Checker, Option, ConfigFile);
942 Checker->parseConfiguration(Mgr, Option, std::move(Config.getValue()));
945 bool ento::shouldRegisterGenericTaintChecker(
const LangOptions &LO) {
Represents a function declaration or definition.
static void enumeration(IO &IO, GenericTaintChecker::VariadicType &Value)
unsigned getMemoryFunctionKind() const
Identify a memory copying or setting function.
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Specialize PointerLikeTypeTraits to allow LazyGenerationalUpdatePtr to be placed into a PointerUnion...
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
The base class of the type hierarchy.
constexpr XRayInstrMask Function
static void mapping(IO &IO, TaintConfig::Propagation &Propagation)
bool isReferenceType() const
__DEVICE__ int max(int __a, int __b)
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Scope - A scope is a transient data structure that is used while parsing the program.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
GenericTaintChecker::TaintConfiguration TaintConfig
void printTaint(ProgramStateRef State, raw_ostream &Out, const char *nl="\, const char *sep="")
This represents one expression.
static bool getPrintfFormatArgumentNum(const CallExpr *CE, const CheckerContext &C, unsigned &ArgNum)
bool isNull() const
Return true if this QualType doesn't point to a type yet.
static void mapping(IO &IO, TaintConfig::NameScopeArgs &NSA)
static void mapping(IO &IO, TaintConfig &Config)
bool isConstQualified() const
Determine whether this type is const-qualified.
QualType getCanonicalType() const
Encodes a location in the source.
bool isTainted(ProgramStateRef State, const Stmt *S, const LocationContext *LCtx, TaintTagType Kind=TaintTagGeneric)
Check if the statement has a tainted value in the given state.
LLVM_NODISCARD ProgramStateRef addTaint(ProgramStateRef State, const Stmt *S, const LocationContext *LCtx, TaintTagType Kind=TaintTagGeneric)
Create a new state in which the value of the statement is marked as tainted.
constexpr XRayInstrMask None
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
#define REGISTER_SET_WITH_PROGRAMSTATE(Name, Elem)
Declares an immutable set of type NameTy, suitable for placement into the ProgramState.
Dataflow Directional Tag Classes.
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
LLVM_NODISCARD ProgramStateRef removeTaint(ProgramStateRef State, SVal V)
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
std::string getQualifiedNameAsString() const
bool isPointerType() const
Defines enum values for all the target-independent builtin functions.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point...