20#include "llvm/ADT/SmallString.h"
21#include "llvm/ADT/StringSwitch.h"
22#include "llvm/Support/raw_ostream.h"
29 return T.getVendor() == llvm::Triple::Apple ||
38 bool check_bcmp =
false;
39 bool check_bcopy =
false;
40 bool check_bzero =
false;
41 bool check_gets =
false;
42 bool check_getpw =
false;
43 bool check_mktemp =
false;
44 bool check_mkstemp =
false;
45 bool check_strcpy =
false;
46 bool check_DeprecatedOrUnsafeBufferHandling =
false;
47 bool check_rand =
false;
48 bool check_vfork =
false;
49 bool check_FloatLoopCounter =
false;
50 bool check_UncheckedReturn =
false;
51 bool check_decodeValueOfObjCType =
false;
53 CheckerNameRef checkName_bcmp;
54 CheckerNameRef checkName_bcopy;
55 CheckerNameRef checkName_bzero;
56 CheckerNameRef checkName_gets;
57 CheckerNameRef checkName_getpw;
58 CheckerNameRef checkName_mktemp;
59 CheckerNameRef checkName_mkstemp;
60 CheckerNameRef checkName_strcpy;
61 CheckerNameRef checkName_DeprecatedOrUnsafeBufferHandling;
62 CheckerNameRef checkName_rand;
63 CheckerNameRef checkName_vfork;
64 CheckerNameRef checkName_FloatLoopCounter;
65 CheckerNameRef checkName_UncheckedReturn;
66 CheckerNameRef checkName_decodeValueOfObjCType;
71 AnalysisDeclContext* AC;
72 enum { num_setids = 6 };
73 IdentifierInfo *II_setid[num_setids];
76 const ChecksFilter &filter;
79 WalkAST(BugReporter &br, AnalysisDeclContext* ac,
80 const ChecksFilter &f)
81 : BR(br), AC(ac), II_setid(),
86 void VisitCallExpr(CallExpr *CE);
87 void VisitObjCMessageExpr(ObjCMessageExpr *CE);
88 void VisitForStmt(ForStmt *S);
90 void VisitStmt(Stmt *S) { VisitChildren(S); }
92 void VisitChildren(Stmt *S);
95 bool checkCall_strCommon(
const CallExpr *CE,
const FunctionDecl *FD);
97 typedef void (WalkAST::*FnCheck)(
const CallExpr *,
const FunctionDecl *);
98 typedef void (WalkAST::*MsgCheck)(
const ObjCMessageExpr *);
101 void checkLoopConditionForFloat(
const ForStmt *FS);
102 void checkCall_bcmp(
const CallExpr *CE,
const FunctionDecl *FD);
103 void checkCall_bcopy(
const CallExpr *CE,
const FunctionDecl *FD);
104 void checkCall_bzero(
const CallExpr *CE,
const FunctionDecl *FD);
105 void checkCall_gets(
const CallExpr *CE,
const FunctionDecl *FD);
106 void checkCall_getpw(
const CallExpr *CE,
const FunctionDecl *FD);
107 void checkCall_mktemp(
const CallExpr *CE,
const FunctionDecl *FD);
108 void checkCall_mkstemp(
const CallExpr *CE,
const FunctionDecl *FD);
109 void checkCall_strcpy(
const CallExpr *CE,
const FunctionDecl *FD);
110 void checkCall_strcat(
const CallExpr *CE,
const FunctionDecl *FD);
111 void checkDeprecatedOrUnsafeBufferHandling(
const CallExpr *CE,
112 const FunctionDecl *FD);
113 void checkCall_rand(
const CallExpr *CE,
const FunctionDecl *FD);
114 void checkCall_random(
const CallExpr *CE,
const FunctionDecl *FD);
115 void checkCall_vfork(
const CallExpr *CE,
const FunctionDecl *FD);
116 void checkMsg_decodeValueOfObjCType(
const ObjCMessageExpr *ME);
117 void checkUncheckedReturnValue(CallExpr *CE);
125void WalkAST::VisitChildren(
Stmt *S) {
131void WalkAST::VisitCallExpr(CallExpr *CE) {
142 StringRef Name = II->
getName();
143 Name.consume_front(
"__builtin_");
146 FnCheck evalFunction =
147 llvm::StringSwitch<FnCheck>(Name)
148 .Case(
"bcmp", &WalkAST::checkCall_bcmp)
149 .Case(
"bcopy", &WalkAST::checkCall_bcopy)
150 .Case(
"bzero", &WalkAST::checkCall_bzero)
151 .Case(
"gets", &WalkAST::checkCall_gets)
152 .Case(
"getpw", &WalkAST::checkCall_getpw)
153 .Case(
"mktemp", &WalkAST::checkCall_mktemp)
154 .Case(
"mkstemp", &WalkAST::checkCall_mkstemp)
155 .Case(
"mkdtemp", &WalkAST::checkCall_mkstemp)
156 .Case(
"mkstemps", &WalkAST::checkCall_mkstemp)
157 .Cases(
"strcpy",
"__strcpy_chk", &WalkAST::checkCall_strcpy)
158 .Cases(
"strcat",
"__strcat_chk", &WalkAST::checkCall_strcat)
159 .Cases(
"sprintf",
"vsprintf",
"scanf",
"wscanf",
"fscanf",
"fwscanf",
160 "vscanf",
"vwscanf",
"vfscanf",
"vfwscanf",
161 &WalkAST::checkDeprecatedOrUnsafeBufferHandling)
162 .Cases(
"sscanf",
"swscanf",
"vsscanf",
"vswscanf",
"swprintf",
163 "snprintf",
"vswprintf",
"vsnprintf",
"memcpy",
"memmove",
164 &WalkAST::checkDeprecatedOrUnsafeBufferHandling)
165 .Cases(
"strncpy",
"strncat",
"memset",
"fprintf",
166 &WalkAST::checkDeprecatedOrUnsafeBufferHandling)
167 .Case(
"drand48", &WalkAST::checkCall_rand)
168 .Case(
"erand48", &WalkAST::checkCall_rand)
169 .Case(
"jrand48", &WalkAST::checkCall_rand)
170 .Case(
"lrand48", &WalkAST::checkCall_rand)
171 .Case(
"mrand48", &WalkAST::checkCall_rand)
172 .Case(
"nrand48", &WalkAST::checkCall_rand)
173 .Case(
"lcong48", &WalkAST::checkCall_rand)
174 .Case(
"rand", &WalkAST::checkCall_rand)
175 .Case(
"rand_r", &WalkAST::checkCall_rand)
176 .Case(
"random", &WalkAST::checkCall_random)
177 .Case(
"vfork", &WalkAST::checkCall_vfork)
183 (this->*evalFunction)(CE, FD);
189void WalkAST::VisitObjCMessageExpr(ObjCMessageExpr *ME) {
190 MsgCheck evalFunction =
192 .Case(
"decodeValueOfObjCType:at:",
193 &WalkAST::checkMsg_decodeValueOfObjCType)
197 (this->*evalFunction)(ME);
206 if (CallExpr *CE = dyn_cast<CallExpr>(Child))
207 checkUncheckedReturnValue(CE);
212void WalkAST::VisitForStmt(ForStmt *FS) {
213 checkLoopConditionForFloat(FS);
226static const DeclRefExpr*
231 if (!(B->isAssignmentOp() || B->isCompoundAssignmentOp() ||
232 B->getOpcode() == BO_Comma))
246 return ND == x || ND == y ? DR :
nullptr;
250 return U->isIncrementDecrementOp()
260void WalkAST::checkLoopConditionForFloat(
const ForStmt *FS) {
261 if (!filter.check_FloatLoopCounter)
265 const Expr *condition = FS->
getCond();
271 const Expr *increment = FS->
getInc();
281 const BinaryOperator *B = dyn_cast<BinaryOperator>(condition);
291 const DeclRefExpr *drLHS =
293 const DeclRefExpr *drRHS =
300 if (!drLHS && !drRHS)
303 const VarDecl *vdLHS = drLHS ? dyn_cast<VarDecl>(drLHS->
getDecl()) :
nullptr;
304 const VarDecl *vdRHS = drRHS ? dyn_cast<VarDecl>(drRHS->
getDecl()) :
nullptr;
306 if (!vdLHS && !vdRHS)
315 assert(vdInc && (vdInc == vdLHS || vdInc == vdRHS));
319 const DeclRefExpr *drCond = vdLHS == vdInc ? drLHS : drRHS;
321 SmallVector<SourceRange, 2> ranges;
322 SmallString<256> sbuf;
323 llvm::raw_svector_ostream os(sbuf);
326 <<
"' with floating point type '" << drCond->
getType()
327 <<
"' should not be used as a loop counter";
332 const char *bugType =
"Floating point variable used as loop counter";
334 PathDiagnosticLocation FSLoc =
337 bugType,
"Security", os.str(),
347void WalkAST::checkCall_bcmp(
const CallExpr *CE,
const FunctionDecl *FD) {
348 if (!filter.check_bcmp)
351 const FunctionProtoType *FPT = FD->
getType()->
getAs<FunctionProtoType>();
359 for (
int i = 0; i < 2; i++) {
374 PathDiagnosticLocation CELoc =
377 "Use of deprecated function in call to 'bcmp()'",
379 "The bcmp() function is obsoleted by memcmp().",
389void WalkAST::checkCall_bcopy(
const CallExpr *CE,
const FunctionDecl *FD) {
390 if (!filter.check_bcopy)
393 const FunctionProtoType *FPT = FD->
getType()->
getAs<FunctionProtoType>();
401 for (
int i = 0; i < 2; i++) {
416 PathDiagnosticLocation CELoc =
419 "Use of deprecated function in call to 'bcopy()'",
421 "The bcopy() function is obsoleted by memcpy() "
432void WalkAST::checkCall_bzero(
const CallExpr *CE,
const FunctionDecl *FD) {
433 if (!filter.check_bzero)
436 const FunctionProtoType *FPT = FD->
getType()->
getAs<FunctionProtoType>();
457 PathDiagnosticLocation CELoc =
460 "Use of deprecated function in call to 'bzero()'",
462 "The bzero() function is obsoleted by memset().",
474void WalkAST::checkCall_gets(
const CallExpr *CE,
const FunctionDecl *FD) {
475 if (!filter.check_gets)
478 const FunctionProtoType *FPT = FD->
getType()->
getAs<FunctionProtoType>();
495 PathDiagnosticLocation CELoc =
498 "Potential buffer overflow in call to 'gets'",
500 "Call to function 'gets' is extremely insecure as it can "
501 "always result in a buffer overflow",
510void WalkAST::checkCall_getpw(
const CallExpr *CE,
const FunctionDecl *FD) {
511 if (!filter.check_getpw)
514 const FunctionProtoType *FPT = FD->
getType()->
getAs<FunctionProtoType>();
535 PathDiagnosticLocation CELoc =
538 "Potential buffer overflow in call to 'getpw'",
540 "The getpw() function is dangerous as it may overflow the "
541 "provided buffer. It is obsoleted by getpwuid().",
550void WalkAST::checkCall_mktemp(
const CallExpr *CE,
const FunctionDecl *FD) {
551 if (!filter.check_mktemp) {
554 checkCall_mkstemp(CE, FD);
558 const FunctionProtoType *FPT = FD->
getType()->
getAs<FunctionProtoType>();
576 PathDiagnosticLocation CELoc =
579 "Potential insecure temporary file in call 'mktemp'",
581 "Call to function 'mktemp' is insecure as it always "
582 "creates or uses insecure temporary file. Use 'mkstemp' "
591void WalkAST::checkCall_mkstemp(
const CallExpr *CE,
const FunctionDecl *FD) {
592 if (!filter.check_mkstemp)
596 std::pair<signed, signed> ArgSuffix =
597 llvm::StringSwitch<std::pair<signed, signed> >(Name)
598 .Case(
"mktemp", std::make_pair(0,-1))
599 .Case(
"mkstemp", std::make_pair(0,-1))
600 .Case(
"mkdtemp", std::make_pair(0,-1))
601 .Case(
"mkstemps", std::make_pair(0,1))
602 .Default(std::make_pair(-1, -1));
604 assert(ArgSuffix.first >= 0 &&
"Unsupported function");
608 if ((
signed) numArgs <= ArgSuffix.first)
611 const StringLiteral *strArg =
612 dyn_cast<StringLiteral>(CE->
getArg((
unsigned)ArgSuffix.first)
624 unsigned n = str.size();
628 if (ArgSuffix.second >= 0) {
629 const Expr *suffixEx = CE->
getArg((
unsigned)ArgSuffix.second);
630 Expr::EvalResult EVResult;
637 suffix = (unsigned)
Result.getZExtValue();
638 n = (n > suffix) ? n - suffix : 0;
641 for (
unsigned i = 0; i < n; ++i)
642 if (str[i] ==
'X') ++numX;
648 PathDiagnosticLocation CELoc =
650 SmallString<512> buf;
651 llvm::raw_svector_ostream
out(buf);
652 out <<
"Call to '" << Name <<
"' should have at least 6 'X's in the"
653 " format string to be secure (" << numX <<
" 'X'";
658 out <<
", " << suffix <<
" character";
661 out <<
" used as a suffix";
665 "Insecure temporary file creation",
"Security",
676void WalkAST::checkCall_strcpy(
const CallExpr *CE,
const FunctionDecl *FD) {
677 if (!filter.check_strcpy)
680 if (!checkCall_strCommon(CE, FD))
686 if (
const auto *Array = dyn_cast<ConstantArrayType>(
Target->getType())) {
688 if (
const auto *String = dyn_cast<StringLiteral>(Source)) {
689 if (ArraySize >= String->getLength() + 1)
695 PathDiagnosticLocation CELoc =
698 "Potential insecure memory buffer bounds restriction in "
701 "Call to function 'strcpy' is insecure as it does not "
702 "provide bounding of the memory buffer. Replace "
703 "unbounded copy functions with analogous functions that "
704 "support length arguments such as 'strlcpy'. CWE-119.",
715void WalkAST::checkCall_strcat(
const CallExpr *CE,
const FunctionDecl *FD) {
716 if (!filter.check_strcpy)
719 if (!checkCall_strCommon(CE, FD))
723 PathDiagnosticLocation CELoc =
726 "Potential insecure memory buffer bounds restriction in "
729 "Call to function 'strcat' is insecure as it does not "
730 "provide bounding of the memory buffer. Replace "
731 "unbounded copy functions with analogous functions that "
732 "support length arguments such as 'strlcat'. CWE-119.",
752void WalkAST::checkDeprecatedOrUnsafeBufferHandling(
const CallExpr *CE,
753 const FunctionDecl *FD) {
754 if (!filter.check_DeprecatedOrUnsafeBufferHandling)
762 enum { DEPR_ONLY = -1, UNKNOWN_CALL = -2 };
765 Name.consume_front(
"__builtin_");
768 llvm::StringSwitch<int>(Name)
769 .Cases(
"scanf",
"wscanf",
"vscanf",
"vwscanf", 0)
770 .Cases(
"fscanf",
"fwscanf",
"vfscanf",
"vfwscanf",
"sscanf",
771 "swscanf",
"vsscanf",
"vswscanf", 1)
772 .Cases(
"sprintf",
"vsprintf",
"fprintf", 1)
773 .Cases(
"swprintf",
"snprintf",
"vswprintf",
"vsnprintf",
"memcpy",
774 "memmove",
"memset",
"strncpy",
"strncat", DEPR_ONLY)
775 .Default(UNKNOWN_CALL);
777 assert(ArgIndex != UNKNOWN_CALL &&
"Unsupported function");
778 bool BoundsProvided = ArgIndex == DEPR_ONLY;
780 if (!BoundsProvided) {
786 if (FormatString && !FormatString->getString().contains(
"%s") &&
787 !FormatString->getString().contains(
"%["))
788 BoundsProvided =
true;
791 SmallString<128> Buf1;
792 SmallString<512> Buf2;
793 llvm::raw_svector_ostream Out1(Buf1);
794 llvm::raw_svector_ostream Out2(Buf2);
796 Out1 <<
"Potential insecure memory buffer bounds restriction in call '"
798 Out2 <<
"Call to function '" << Name
799 <<
"' is insecure as it does not provide ";
801 if (!BoundsProvided) {
802 Out2 <<
"bounding of the memory buffer or ";
805 Out2 <<
"security checks introduced "
806 "in the C11 standard. Replace with analogous functions that "
807 "support length arguments or provides boundary checks such as '"
808 << Name <<
"_s' in case of C11";
810 PathDiagnosticLocation CELoc =
813 filter.checkName_DeprecatedOrUnsafeBufferHandling,
814 Out1.str(),
"Security", Out2.str(), CELoc,
822bool WalkAST::checkCall_strCommon(
const CallExpr *CE,
const FunctionDecl *FD) {
823 const FunctionProtoType *FPT = FD->
getType()->
getAs<FunctionProtoType>();
829 if (numArgs != 2 && numArgs != 3)
833 for (
int i = 0; i < 2; i++) {
858void WalkAST::checkCall_rand(
const CallExpr *CE,
const FunctionDecl *FD) {
859 if (!filter.check_rand || !CheckRand)
862 const FunctionProtoType *FTP = FD->
getType()->
getAs<FunctionProtoType>();
879 SmallString<256> buf1;
880 llvm::raw_svector_ostream os1(buf1);
881 os1 <<
'\'' << *FD <<
"' is a poor random number generator";
883 SmallString<256> buf2;
884 llvm::raw_svector_ostream os2(buf2);
885 os2 <<
"Function '" << *FD
886 <<
"' is obsolete because it implements a poor random number generator."
887 <<
" Use 'arc4random' instead";
889 PathDiagnosticLocation CELoc =
892 "Security", os2.str(), CELoc,
897void WalkAST::checkCall_random(
const CallExpr *CE,
const FunctionDecl *FD) {
898 if (!CheckRand || !filter.check_rand)
901 const FunctionProtoType *FTP = FD->
getType()->
getAs<FunctionProtoType>();
910 PathDiagnosticLocation CELoc =
913 "'random' is not a secure random number generator",
915 "The 'random' function produces a sequence of values that "
916 "an adversary may be able to predict. Use 'arc4random' "
925void WalkAST::checkCall_vfork(
const CallExpr *CE,
const FunctionDecl *FD) {
926 if (!filter.check_vfork)
930 PathDiagnosticLocation CELoc =
933 "Potential insecure implementation-specific behavior in "
936 "Call to function 'vfork' is insecure as it can lead to "
937 "denial of service situations in the parent process. "
938 "Replace calls to vfork with calls to the safer "
939 "'posix_spawn' function",
949void WalkAST::checkMsg_decodeValueOfObjCType(
const ObjCMessageExpr *ME) {
950 if (!filter.check_decodeValueOfObjCType)
960 case llvm::Triple::IOS:
961 if (VT < VersionTuple(11, 0))
964 case llvm::Triple::MacOSX:
965 if (VT < VersionTuple(10, 13))
968 case llvm::Triple::WatchOS:
969 if (VT < VersionTuple(4, 0))
972 case llvm::Triple::TvOS:
973 if (VT < VersionTuple(11, 0))
976 case llvm::Triple::XROS:
982 PathDiagnosticLocation MELoc =
985 AC->
getDecl(), filter.checkName_decodeValueOfObjCType,
986 "Potential buffer overflow in '-decodeValueOfObjCType:at:'",
"Security",
987 "Deprecated method '-decodeValueOfObjCType:at:' is insecure "
988 "as it can lead to potential buffer overflows. Use the safer "
989 "'-decodeValueOfObjCType:at:size:' method.",
1008void WalkAST::checkUncheckedReturnValue(CallExpr *CE) {
1009 if (!filter.check_UncheckedReturn)
1016 if (II_setid[0] ==
nullptr) {
1017 static const char *
const identifiers[num_setids] = {
1018 "setuid",
"setgid",
"seteuid",
"setegid",
1019 "setreuid",
"setregid"
1022 for (
size_t i = 0; i < num_setids; i++)
1027 size_t identifierid;
1029 for (identifierid = 0; identifierid < num_setids; identifierid++)
1030 if (
id == II_setid[identifierid])
1033 if (identifierid >= num_setids)
1036 const FunctionProtoType *FTP = FD->
getType()->
getAs<FunctionProtoType>();
1051 SmallString<256> buf1;
1052 llvm::raw_svector_ostream os1(buf1);
1053 os1 <<
"Return value is not checked in call to '" << *FD <<
'\'';
1055 SmallString<256> buf2;
1056 llvm::raw_svector_ostream os2(buf2);
1057 os2 <<
"The return value from the call to '" << *FD
1058 <<
"' is not checked. If an error occurs in '" << *FD
1059 <<
"', the following code may execute with unexpected privileges";
1061 PathDiagnosticLocation CELoc =
1064 "Security", os2.str(), CELoc,
1073class SecuritySyntaxChecker :
public Checker<check::ASTCodeBody> {
1075 ChecksFilter filter;
1077 void checkASTCodeBody(
const Decl *D, AnalysisManager& mgr,
1078 BugReporter &BR)
const {
1085void ento::registerSecuritySyntaxChecker(CheckerManager &mgr) {
1089bool ento::shouldRegisterSecuritySyntaxChecker(
const CheckerManager &mgr) {
1093#define REGISTER_CHECKER(name) \
1094 void ento::register##name(CheckerManager &mgr) { \
1095 SecuritySyntaxChecker *checker = mgr.getChecker<SecuritySyntaxChecker>(); \
1096 checker->filter.check_##name = true; \
1097 checker->filter.checkName_##name = mgr.getCurrentCheckerName(); \
1100 bool ento::shouldRegister##name(const CheckerManager &mgr) { return true; }
This file defines AnalysisDeclContext, a class that manages the analysis context data for context sen...
#define REGISTER_CHECKER(name)
static const DeclRefExpr * getIncrementedVar(const Expr *expr, const VarDecl *x, const VarDecl *y)
static bool isArc4RandomAvailable(const ASTContext &Ctx)
llvm::MachO::Target Target
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const LangOptions & getLangOpts() const
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
const TargetInfo & getTargetInfo() const
const Decl * getDecl() const
ASTContext & getASTContext() const
A builtin binary operation expression such as "x + y" or "x <= y".
static bool isRelationalOp(Opcode Opc)
static bool isEqualityOp(Opcode Opc)
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
A reference to a declared variable, function, enum, etc.
virtual Stmt * getBody() const
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
Expr * IgnoreParenLValueCasts() LLVM_READONLY
Skip past any parentheses and lvalue casts which might surround this expression until reaching a fixe...
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
unsigned getNumParams() const
QualType getParamType(unsigned i) const
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Selector getSelector() const
QualType getPointeeType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
std::string getAsString() const
Derive the full selector name (e.g.
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Stmt - This represents one statement.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
StringRef getString() const
unsigned getCharByteWidth() const
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
VersionTuple getPlatformMinVersion() const
Retrieve the minimum desired version of the platform, to which the program should be compiled.
bool isIntegralOrUnscopedEnumerationType() const
Determine whether this type is an integral or unscoped enumeration type.
bool isRealFloatingType() const
Floating point categories.
const T * getAs() const
Member-template getAs<specific type>'.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Represents a variable declaration or definition.
AnalysisDeclContext * getAnalysisDeclContext(const Decl *D)
const SourceManager & getSourceManager()
ASTContext & getContext()
void EmitBasicReport(const Decl *DeclWithIssue, const CheckerFrontend *Checker, StringRef BugName, StringRef BugCategory, StringRef BugStr, PathDiagnosticLocation Loc, ArrayRef< SourceRange > Ranges={}, ArrayRef< FixItHint > Fixits={})
CHECKER * registerChecker(AT &&...Args)
Register a single-part checker (derived from Checker): construct its singleton instance,...
static PathDiagnosticLocation createBegin(const Decl *D, const SourceManager &SM)
Create a location for the beginning of the declaration.
Defines the clang::TargetInfo interface.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
The JSON file list parser is used to communicate input to InstallAPI.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ Result
The result type of a method or function.
const FunctionProtoType * T
U cast(CodeGen::Address addr)
APValue Val
Val - This is the value the expression can be folded to.