21#include "llvm/ADT/SmallString.h"
22#include "llvm/ADT/StringSwitch.h"
23#include "llvm/Support/raw_ostream.h"
31 return T.getVendor() == llvm::Triple::Apple ||
40enum class ReportPolicy {
All, Actionable, C11Only };
43 bool check_bcmp =
false;
44 bool check_bcopy =
false;
45 bool check_bzero =
false;
46 bool check_gets =
false;
47 bool check_getpw =
false;
48 bool check_mktemp =
false;
49 bool check_mkstemp =
false;
50 bool check_strcpy =
false;
51 bool check_DeprecatedOrUnsafeBufferHandling =
false;
52 bool check_rand =
false;
53 bool check_vfork =
false;
54 bool check_FloatLoopCounter =
false;
55 bool check_UncheckedReturn =
false;
56 bool check_decodeValueOfObjCType =
false;
58 ReportPolicy ReportMode = ReportPolicy::C11Only;
60 CheckerNameRef checkName_bcmp;
61 CheckerNameRef checkName_bcopy;
62 CheckerNameRef checkName_bzero;
63 CheckerNameRef checkName_gets;
64 CheckerNameRef checkName_getpw;
65 CheckerNameRef checkName_mktemp;
66 CheckerNameRef checkName_mkstemp;
67 CheckerNameRef checkName_strcpy;
68 CheckerNameRef checkName_DeprecatedOrUnsafeBufferHandling;
69 CheckerNameRef checkName_rand;
70 CheckerNameRef checkName_vfork;
71 CheckerNameRef checkName_FloatLoopCounter;
72 CheckerNameRef checkName_UncheckedReturn;
73 CheckerNameRef checkName_decodeValueOfObjCType;
78 AnalysisDeclContext* AC;
79 enum { num_setids = 6 };
80 IdentifierInfo *II_setid[num_setids];
84 const ChecksFilter &filter;
85 const bool ShouldReportAnnexKRelated;
88 WalkAST(BugReporter &br, AnalysisDeclContext *ac,
const ChecksFilter &f,
89 bool shouldReportAnnexKRelated)
90 : BR(br), AC(ac), II_setid(),
92 ShouldReportAnnexKRelated(shouldReportAnnexKRelated) {}
95 void VisitCallExpr(CallExpr *CE);
96 void VisitObjCMessageExpr(ObjCMessageExpr *CE);
97 void VisitForStmt(ForStmt *S);
99 void VisitStmt(Stmt *S) { VisitChildren(S); }
101 void VisitChildren(Stmt *S);
104 bool checkCall_strCommon(
const CallExpr *CE,
const FunctionDecl *FD);
106 typedef void (WalkAST::*FnCheck)(
const CallExpr *,
const FunctionDecl *);
107 typedef void (WalkAST::*MsgCheck)(
const ObjCMessageExpr *);
110 void checkLoopConditionForFloat(
const ForStmt *FS);
111 void checkCall_bcmp(
const CallExpr *CE,
const FunctionDecl *FD);
112 void checkCall_bcopy(
const CallExpr *CE,
const FunctionDecl *FD);
113 void checkCall_bzero(
const CallExpr *CE,
const FunctionDecl *FD);
114 void checkCall_gets(
const CallExpr *CE,
const FunctionDecl *FD);
115 void checkCall_getpw(
const CallExpr *CE,
const FunctionDecl *FD);
116 void checkCall_mktemp(
const CallExpr *CE,
const FunctionDecl *FD);
117 void checkCall_mkstemp(
const CallExpr *CE,
const FunctionDecl *FD);
118 void checkCall_strcpy(
const CallExpr *CE,
const FunctionDecl *FD);
119 void checkCall_strcat(
const CallExpr *CE,
const FunctionDecl *FD);
120 void checkDeprecatedOrUnsafeBufferHandling(
const CallExpr *CE,
121 const FunctionDecl *FD);
122 void checkCall_rand(
const CallExpr *CE,
const FunctionDecl *FD);
123 void checkCall_random(
const CallExpr *CE,
const FunctionDecl *FD);
124 void checkCall_vfork(
const CallExpr *CE,
const FunctionDecl *FD);
125 void checkMsg_decodeValueOfObjCType(
const ObjCMessageExpr *ME);
126 void checkUncheckedReturnValue(CallExpr *CE);
134void WalkAST::VisitChildren(
Stmt *S) {
140void WalkAST::VisitCallExpr(CallExpr *CE) {
151 StringRef Name = II->
getName();
152 Name.consume_front(
"__builtin_");
155 FnCheck evalFunction =
156 llvm::StringSwitch<FnCheck>(Name)
157 .Case(
"bcmp", &WalkAST::checkCall_bcmp)
158 .Case(
"bcopy", &WalkAST::checkCall_bcopy)
159 .Case(
"bzero", &WalkAST::checkCall_bzero)
160 .Case(
"gets", &WalkAST::checkCall_gets)
161 .Case(
"getpw", &WalkAST::checkCall_getpw)
162 .Case(
"mktemp", &WalkAST::checkCall_mktemp)
163 .Case(
"mkstemp", &WalkAST::checkCall_mkstemp)
164 .Case(
"mkdtemp", &WalkAST::checkCall_mkstemp)
165 .Case(
"mkstemps", &WalkAST::checkCall_mkstemp)
166 .Cases({
"strcpy",
"__strcpy_chk"}, &WalkAST::checkCall_strcpy)
167 .Cases({
"strcat",
"__strcat_chk"}, &WalkAST::checkCall_strcat)
168 .Cases({
"sprintf",
"vsprintf",
"scanf",
"wscanf",
"fscanf",
"fwscanf",
169 "vscanf",
"vwscanf",
"vfscanf",
"vfwscanf"},
170 &WalkAST::checkDeprecatedOrUnsafeBufferHandling)
171 .Cases({
"sscanf",
"swscanf",
"vsscanf",
"vswscanf",
"swprintf",
172 "snprintf",
"vswprintf",
"vsnprintf",
"memcpy",
"memmove"},
173 &WalkAST::checkDeprecatedOrUnsafeBufferHandling)
174 .Cases({
"strncpy",
"strncat",
"memset",
"fprintf"},
175 &WalkAST::checkDeprecatedOrUnsafeBufferHandling)
176 .Case(
"drand48", &WalkAST::checkCall_rand)
177 .Case(
"erand48", &WalkAST::checkCall_rand)
178 .Case(
"jrand48", &WalkAST::checkCall_rand)
179 .Case(
"lrand48", &WalkAST::checkCall_rand)
180 .Case(
"mrand48", &WalkAST::checkCall_rand)
181 .Case(
"nrand48", &WalkAST::checkCall_rand)
182 .Case(
"lcong48", &WalkAST::checkCall_rand)
183 .Case(
"rand", &WalkAST::checkCall_rand)
184 .Case(
"rand_r", &WalkAST::checkCall_rand)
185 .Case(
"random", &WalkAST::checkCall_random)
186 .Case(
"vfork", &WalkAST::checkCall_vfork)
192 (this->*evalFunction)(CE, FD);
198void WalkAST::VisitObjCMessageExpr(ObjCMessageExpr *ME) {
199 MsgCheck evalFunction =
201 .Case(
"decodeValueOfObjCType:at:",
202 &WalkAST::checkMsg_decodeValueOfObjCType)
206 (this->*evalFunction)(ME);
215 if (CallExpr *CE = dyn_cast<CallExpr>(Child))
216 checkUncheckedReturnValue(CE);
221void WalkAST::VisitForStmt(ForStmt *FS) {
222 checkLoopConditionForFloat(FS);
235static const DeclRefExpr*
240 if (!(B->isAssignmentOp() || B->isCompoundAssignmentOp() ||
241 B->getOpcode() == BO_Comma))
255 return ND == x || ND == y ? DR :
nullptr;
259 return U->isIncrementDecrementOp()
269void WalkAST::checkLoopConditionForFloat(
const ForStmt *FS) {
270 if (!filter.check_FloatLoopCounter)
280 const Expr *increment = FS->
getInc();
290 const BinaryOperator *B = dyn_cast<BinaryOperator>(
condition);
300 const DeclRefExpr *drLHS =
302 const DeclRefExpr *drRHS =
309 if (!drLHS && !drRHS)
312 const VarDecl *vdLHS = drLHS ? dyn_cast<VarDecl>(drLHS->
getDecl()) :
nullptr;
313 const VarDecl *vdRHS = drRHS ? dyn_cast<VarDecl>(drRHS->
getDecl()) :
nullptr;
315 if (!vdLHS && !vdRHS)
324 assert(vdInc && (vdInc == vdLHS || vdInc == vdRHS));
328 const DeclRefExpr *drCond = vdLHS == vdInc ? drLHS : drRHS;
330 SmallVector<SourceRange, 2> ranges;
331 SmallString<256> sbuf;
332 llvm::raw_svector_ostream os(sbuf);
335 <<
"' with floating point type '" << drCond->
getType()
336 <<
"' should not be used as a loop counter";
341 const char *bugType =
"Floating point variable used as loop counter";
343 PathDiagnosticLocation FSLoc =
346 bugType,
"Security", os.str(),
356void WalkAST::checkCall_bcmp(
const CallExpr *CE,
const FunctionDecl *FD) {
357 if (!filter.check_bcmp)
360 const FunctionProtoType *FPT = FD->
getType()->
getAs<FunctionProtoType>();
368 for (
int i = 0; i < 2; i++) {
383 PathDiagnosticLocation CELoc =
386 "Use of deprecated function in call to 'bcmp()'",
388 "The bcmp() function is obsoleted by memcmp().",
398void WalkAST::checkCall_bcopy(
const CallExpr *CE,
const FunctionDecl *FD) {
399 if (!filter.check_bcopy)
402 const FunctionProtoType *FPT = FD->
getType()->
getAs<FunctionProtoType>();
410 for (
int i = 0; i < 2; i++) {
425 PathDiagnosticLocation CELoc =
428 "Use of deprecated function in call to 'bcopy()'",
430 "The bcopy() function is obsoleted by memcpy() "
441void WalkAST::checkCall_bzero(
const CallExpr *CE,
const FunctionDecl *FD) {
442 if (!filter.check_bzero)
445 const FunctionProtoType *FPT = FD->
getType()->
getAs<FunctionProtoType>();
466 PathDiagnosticLocation CELoc =
469 "Use of deprecated function in call to 'bzero()'",
471 "The bzero() function is obsoleted by memset().",
483void WalkAST::checkCall_gets(
const CallExpr *CE,
const FunctionDecl *FD) {
484 if (!filter.check_gets)
487 const FunctionProtoType *FPT = FD->
getType()->
getAs<FunctionProtoType>();
504 PathDiagnosticLocation CELoc =
507 "Potential buffer overflow in call to 'gets'",
509 "Call to function 'gets' is extremely insecure as it can "
510 "always result in a buffer overflow",
519void WalkAST::checkCall_getpw(
const CallExpr *CE,
const FunctionDecl *FD) {
520 if (!filter.check_getpw)
523 const FunctionProtoType *FPT = FD->
getType()->
getAs<FunctionProtoType>();
544 PathDiagnosticLocation CELoc =
547 "Potential buffer overflow in call to 'getpw'",
549 "The getpw() function is dangerous as it may overflow the "
550 "provided buffer. It is obsoleted by getpwuid().",
559void WalkAST::checkCall_mktemp(
const CallExpr *CE,
const FunctionDecl *FD) {
560 if (!filter.check_mktemp) {
563 checkCall_mkstemp(CE, FD);
567 const FunctionProtoType *FPT = FD->
getType()->
getAs<FunctionProtoType>();
585 PathDiagnosticLocation CELoc =
588 "Potential insecure temporary file in call 'mktemp'",
590 "Call to function 'mktemp' is insecure as it always "
591 "creates or uses insecure temporary file. Use 'mkstemp' "
600void WalkAST::checkCall_mkstemp(
const CallExpr *CE,
const FunctionDecl *FD) {
601 if (!filter.check_mkstemp)
605 std::pair<signed, signed> ArgSuffix =
606 llvm::StringSwitch<std::pair<signed, signed> >(Name)
607 .Case(
"mktemp", std::make_pair(0,-1))
608 .Case(
"mkstemp", std::make_pair(0,-1))
609 .Case(
"mkdtemp", std::make_pair(0,-1))
610 .Case(
"mkstemps", std::make_pair(0,1))
611 .Default(std::make_pair(-1, -1));
613 assert(ArgSuffix.first >= 0 &&
"Unsupported function");
617 if ((
signed) numArgs <= ArgSuffix.first)
620 const StringLiteral *strArg =
621 dyn_cast<StringLiteral>(CE->
getArg((
unsigned)ArgSuffix.first)
633 unsigned n = str.size();
637 if (ArgSuffix.second >= 0) {
638 const Expr *suffixEx = CE->
getArg((
unsigned)ArgSuffix.second);
639 Expr::EvalResult EVResult;
646 suffix = (unsigned)
Result.getZExtValue();
647 n = (n > suffix) ? n - suffix : 0;
650 for (
unsigned i = 0; i < n; ++i)
651 if (str[i] ==
'X') ++numX;
657 PathDiagnosticLocation CELoc =
659 SmallString<512> buf;
660 llvm::raw_svector_ostream
out(buf);
661 out <<
"Call to '" << Name <<
"' should have at least 6 'X's in the"
662 " format string to be secure (" << numX <<
" 'X'";
667 out <<
", " << suffix <<
" character";
670 out <<
" used as a suffix";
674 "Insecure temporary file creation",
"Security",
685void WalkAST::checkCall_strcpy(
const CallExpr *CE,
const FunctionDecl *FD) {
686 if (!filter.check_strcpy)
689 if (!checkCall_strCommon(CE, FD))
695 if (
const auto *Array = dyn_cast<ConstantArrayType>(
Target->getType())) {
697 if (
const auto *String = dyn_cast<StringLiteral>(Source)) {
698 if (ArraySize >= String->getLength() + 1)
704 PathDiagnosticLocation CELoc =
707 "Potential insecure memory buffer bounds restriction in "
710 "Call to function 'strcpy' is insecure as it does not "
711 "provide bounding of the memory buffer. Replace "
712 "unbounded copy functions with analogous functions that "
713 "support length arguments such as 'strlcpy'. CWE-119.",
724void WalkAST::checkCall_strcat(
const CallExpr *CE,
const FunctionDecl *FD) {
725 if (!filter.check_strcpy)
728 if (!checkCall_strCommon(CE, FD))
732 PathDiagnosticLocation CELoc =
735 "Potential insecure memory buffer bounds restriction in "
738 "Call to function 'strcat' is insecure as it does not "
739 "provide bounding of the memory buffer. Replace "
740 "unbounded copy functions with analogous functions that "
741 "support length arguments such as 'strlcat'. CWE-119.",
761void WalkAST::checkDeprecatedOrUnsafeBufferHandling(
const CallExpr *CE,
762 const FunctionDecl *FD) {
763 if (!filter.check_DeprecatedOrUnsafeBufferHandling ||
764 !ShouldReportAnnexKRelated)
769 enum { DEPR_ONLY = -1, UNKNOWN_CALL = -2 };
772 Name.consume_front(
"__builtin_");
775 llvm::StringSwitch<int>(Name)
776 .Cases({
"scanf",
"wscanf",
"vscanf",
"vwscanf"}, 0)
777 .Cases({
"fscanf",
"fwscanf",
"vfscanf",
"vfwscanf",
"sscanf",
778 "swscanf",
"vsscanf",
"vswscanf"},
780 .Cases({
"sprintf",
"vsprintf",
"fprintf"}, 1)
781 .Cases({
"swprintf",
"snprintf",
"vswprintf",
"vsnprintf",
"memcpy",
782 "memmove",
"memset",
"strncpy",
"strncat"},
786 assert(ArgIndex != UNKNOWN_CALL &&
"Unsupported function");
787 bool BoundsProvided = ArgIndex == DEPR_ONLY;
789 if (!BoundsProvided) {
795 if (FormatString && !FormatString->getString().contains(
"%s") &&
796 !FormatString->getString().contains(
"%["))
797 BoundsProvided =
true;
800 SmallString<128> Buf1;
801 SmallString<512> Buf2;
802 llvm::raw_svector_ostream Out1(Buf1);
803 llvm::raw_svector_ostream Out2(Buf2);
805 Out1 <<
"Potential insecure memory buffer bounds restriction in call '"
807 Out2 <<
"Call to function '" << Name
808 <<
"' is insecure as it does not provide ";
810 if (!BoundsProvided) {
811 Out2 <<
"bounding of the memory buffer or ";
814 Out2 <<
"security checks introduced "
815 "in the C11 standard. Replace with analogous functions that "
816 "support length arguments or provides boundary checks such as '"
817 << Name <<
"_s' in case of C11";
819 PathDiagnosticLocation CELoc =
822 filter.checkName_DeprecatedOrUnsafeBufferHandling,
823 Out1.str(),
"Security", Out2.str(), CELoc,
831bool WalkAST::checkCall_strCommon(
const CallExpr *CE,
const FunctionDecl *FD) {
832 const FunctionProtoType *FPT = FD->
getType()->
getAs<FunctionProtoType>();
838 if (numArgs != 2 && numArgs != 3)
842 for (
int i = 0; i < 2; i++) {
867void WalkAST::checkCall_rand(
const CallExpr *CE,
const FunctionDecl *FD) {
868 if (!filter.check_rand || !CheckRand)
871 const FunctionProtoType *FTP = FD->
getType()->
getAs<FunctionProtoType>();
888 SmallString<256> buf1;
889 llvm::raw_svector_ostream os1(buf1);
890 os1 <<
'\'' << *FD <<
"' is a poor random number generator";
892 SmallString<256> buf2;
893 llvm::raw_svector_ostream os2(buf2);
894 os2 <<
"Function '" << *FD
895 <<
"' is obsolete because it implements a poor random number generator."
896 <<
" Use 'arc4random' instead";
898 PathDiagnosticLocation CELoc =
901 "Security", os2.str(), CELoc,
906void WalkAST::checkCall_random(
const CallExpr *CE,
const FunctionDecl *FD) {
907 if (!CheckRand || !filter.check_rand)
910 const FunctionProtoType *FTP = FD->
getType()->
getAs<FunctionProtoType>();
919 PathDiagnosticLocation CELoc =
922 "'random' is not a secure random number generator",
924 "The 'random' function produces a sequence of values that "
925 "an adversary may be able to predict. Use 'arc4random' "
934void WalkAST::checkCall_vfork(
const CallExpr *CE,
const FunctionDecl *FD) {
935 if (!filter.check_vfork)
939 PathDiagnosticLocation CELoc =
942 "Potential insecure implementation-specific behavior in "
945 "Call to function 'vfork' is insecure as it can lead to "
946 "denial of service situations in the parent process. "
947 "Replace calls to vfork with calls to the safer "
948 "'posix_spawn' function",
958void WalkAST::checkMsg_decodeValueOfObjCType(
const ObjCMessageExpr *ME) {
959 if (!filter.check_decodeValueOfObjCType)
969 case llvm::Triple::IOS:
970 if (VT < VersionTuple(11, 0))
973 case llvm::Triple::MacOSX:
974 if (VT < VersionTuple(10, 13))
977 case llvm::Triple::WatchOS:
978 if (VT < VersionTuple(4, 0))
981 case llvm::Triple::TvOS:
982 if (VT < VersionTuple(11, 0))
985 case llvm::Triple::XROS:
991 PathDiagnosticLocation MELoc =
994 AC->
getDecl(), filter.checkName_decodeValueOfObjCType,
995 "Potential buffer overflow in '-decodeValueOfObjCType:at:'",
"Security",
996 "Deprecated method '-decodeValueOfObjCType:at:' is insecure "
997 "as it can lead to potential buffer overflows. Use the safer "
998 "'-decodeValueOfObjCType:at:size:' method.",
1017void WalkAST::checkUncheckedReturnValue(CallExpr *CE) {
1018 if (!filter.check_UncheckedReturn)
1025 if (II_setid[0] ==
nullptr) {
1026 static const char *
const identifiers[num_setids] = {
1027 "setuid",
"setgid",
"seteuid",
"setegid",
1028 "setreuid",
"setregid"
1031 for (
size_t i = 0; i < num_setids; i++)
1036 size_t identifierid;
1038 for (identifierid = 0; identifierid < num_setids; identifierid++)
1039 if (
id == II_setid[identifierid])
1042 if (identifierid >= num_setids)
1045 const FunctionProtoType *FTP = FD->
getType()->
getAs<FunctionProtoType>();
1060 SmallString<256> buf1;
1061 llvm::raw_svector_ostream os1(buf1);
1062 os1 <<
"Return value is not checked in call to '" << *FD <<
'\'';
1064 SmallString<256> buf2;
1065 llvm::raw_svector_ostream os2(buf2);
1066 os2 <<
"The return value from the call to '" << *FD
1067 <<
"' is not checked. If an error occurs in '" << *FD
1068 <<
"', the following code may execute with unexpected privileges";
1070 PathDiagnosticLocation CELoc =
1073 "Security", os2.str(), CELoc,
1085[[nodiscard]]
bool shouldReportAnnexKRelated(BugReporter &BR,
1086 const ChecksFilter &Filter) {
1091 switch (
Filter.ReportMode) {
1092 case ReportPolicy::All:
1094 case ReportPolicy::Actionable:
1095 return IsAnnexKAvailable;
1096 case ReportPolicy::C11Only:
1097 return IsC11OrLaterStandard;
1099 llvm_unreachable(
"Unknown ReportPolicy value");
1102class SecuritySyntaxChecker :
public Checker<check::ASTCodeBody> {
1104 ChecksFilter filter;
1105 mutable std::optional<bool> CachedShouldReportAnnexKRelated;
1107 void checkASTCodeBody(
const Decl *D, AnalysisManager& mgr,
1108 BugReporter &BR)
const {
1110 if (!CachedShouldReportAnnexKRelated.has_value()) {
1111 CachedShouldReportAnnexKRelated = shouldReportAnnexKRelated(BR, filter);
1115 *CachedShouldReportAnnexKRelated);
1121void ento::registerSecuritySyntaxChecker(CheckerManager &mgr) {
1125bool ento::shouldRegisterSecuritySyntaxChecker(
const CheckerManager &mgr) {
1129#define REGISTER_CHECKER(name) \
1130 void ento::register##name(CheckerManager &mgr) { \
1131 SecuritySyntaxChecker *checker = mgr.getChecker<SecuritySyntaxChecker>(); \
1132 checker->filter.check_##name = true; \
1133 checker->filter.checkName_##name = mgr.getCurrentCheckerName(); \
1136 bool ento::shouldRegister##name(const CheckerManager &mgr) { return true; }
1151void ento::registerDeprecatedOrUnsafeBufferHandling(
CheckerManager &Mgr) {
1153 Checker->filter.check_DeprecatedOrUnsafeBufferHandling =
true;
1154 Checker->filter.checkName_DeprecatedOrUnsafeBufferHandling =
1160 Checker->filter.ReportMode = ReportPolicy::C11Only;
1161 auto RequestedReportPolicy =
1162 llvm::StringSwitch<std::optional<ReportPolicy>>(ReportModeStr)
1163 .Case(
"all", ReportPolicy::All)
1164 .Case(
"actionable", ReportPolicy::Actionable)
1165 .Case(
"c11-only", ReportPolicy::C11Only)
1167 if (!RequestedReportPolicy)
1170 "one of the following values: \"all\", \"actionable\" or \"c11-only\" "
1173 Checker->filter.ReportMode = *RequestedReportPolicy;
1176bool ento::shouldRegisterDeprecatedOrUnsafeBufferHandling(
1177 const CheckerManager &) {
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
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a an optional score condition
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
StringRef getCheckerStringOption(StringRef CheckerName, StringRef OptionName, bool SearchInParents=false) const
Query an option's string value.
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)
Preprocessor & getPreprocessor()
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={})
const AnalyzerOptions & getAnalyzerOptions() const
CHECKER * registerChecker(AT &&...Args)
Register a single-part checker (derived from Checker): construct its singleton instance,...
void reportInvalidCheckerOptionValue(const CheckerFrontend *Checker, StringRef OptionName, StringRef ExpectedValueDesc) const
Emits an error through a DiagnosticsEngine about an invalid user supplied checker option value.
CheckerNameRef getCurrentCheckerName() const
CHECKER * getChecker(AT &&...Args)
If the the singleton instance of a checker class is not yet constructed, then construct it (with the ...
Simple checker classes that implement one frontend (i.e.
static PathDiagnosticLocation createBegin(const Decl *D, const SourceManager &SM)
Create a location for the beginning of the declaration.
Defines the clang::TargetInfo interface.
bool isAnnexKAvailable(Preprocessor *PP, const LangOptions &LO)
Calculates whether Annex K is available for the current translation unit based on the macro definitio...
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.