clang  11.0.0git
CheckSecuritySyntaxOnly.cpp
Go to the documentation of this file.
1 //==- CheckSecuritySyntaxOnly.cpp - Basic security checks --------*- C++ -*-==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines a set of flow-insensitive security checks.
10 //
11 //===----------------------------------------------------------------------===//
12 
14 #include "clang/AST/StmtVisitor.h"
16 #include "clang/Basic/TargetInfo.h"
20 #include "llvm/ADT/SmallString.h"
21 #include "llvm/ADT/StringSwitch.h"
22 #include "llvm/Support/raw_ostream.h"
23 
24 using namespace clang;
25 using namespace ento;
26 
27 static bool isArc4RandomAvailable(const ASTContext &Ctx) {
28  const llvm::Triple &T = Ctx.getTargetInfo().getTriple();
29  return T.getVendor() == llvm::Triple::Apple ||
30  T.getOS() == llvm::Triple::CloudABI ||
31  T.isOSFreeBSD() ||
32  T.isOSNetBSD() ||
33  T.isOSOpenBSD() ||
34  T.isOSDragonFly();
35 }
36 
37 namespace {
38 struct ChecksFilter {
39  DefaultBool check_bcmp;
40  DefaultBool check_bcopy;
41  DefaultBool check_bzero;
42  DefaultBool check_gets;
43  DefaultBool check_getpw;
44  DefaultBool check_mktemp;
45  DefaultBool check_mkstemp;
46  DefaultBool check_strcpy;
47  DefaultBool check_DeprecatedOrUnsafeBufferHandling;
48  DefaultBool check_rand;
49  DefaultBool check_vfork;
50  DefaultBool check_FloatLoopCounter;
51  DefaultBool check_UncheckedReturn;
52  DefaultBool check_decodeValueOfObjCType;
53 
54  CheckerNameRef checkName_bcmp;
55  CheckerNameRef checkName_bcopy;
56  CheckerNameRef checkName_bzero;
57  CheckerNameRef checkName_gets;
58  CheckerNameRef checkName_getpw;
59  CheckerNameRef checkName_mktemp;
60  CheckerNameRef checkName_mkstemp;
61  CheckerNameRef checkName_strcpy;
62  CheckerNameRef checkName_DeprecatedOrUnsafeBufferHandling;
63  CheckerNameRef checkName_rand;
64  CheckerNameRef checkName_vfork;
65  CheckerNameRef checkName_FloatLoopCounter;
66  CheckerNameRef checkName_UncheckedReturn;
67  CheckerNameRef checkName_decodeValueOfObjCType;
68 };
69 
70 class WalkAST : public StmtVisitor<WalkAST> {
71  BugReporter &BR;
73  enum { num_setids = 6 };
74  IdentifierInfo *II_setid[num_setids];
75 
76  const bool CheckRand;
77  const ChecksFilter &filter;
78 
79 public:
80  WalkAST(BugReporter &br, AnalysisDeclContext* ac,
81  const ChecksFilter &f)
82  : BR(br), AC(ac), II_setid(),
83  CheckRand(isArc4RandomAvailable(BR.getContext())),
84  filter(f) {}
85 
86  // Statement visitor methods.
87  void VisitCallExpr(CallExpr *CE);
88  void VisitObjCMessageExpr(ObjCMessageExpr *CE);
89  void VisitForStmt(ForStmt *S);
90  void VisitCompoundStmt (CompoundStmt *S);
91  void VisitStmt(Stmt *S) { VisitChildren(S); }
92 
93  void VisitChildren(Stmt *S);
94 
95  // Helpers.
96  bool checkCall_strCommon(const CallExpr *CE, const FunctionDecl *FD);
97 
98  typedef void (WalkAST::*FnCheck)(const CallExpr *, const FunctionDecl *);
99  typedef void (WalkAST::*MsgCheck)(const ObjCMessageExpr *);
100 
101  // Checker-specific methods.
102  void checkLoopConditionForFloat(const ForStmt *FS);
103  void checkCall_bcmp(const CallExpr *CE, const FunctionDecl *FD);
104  void checkCall_bcopy(const CallExpr *CE, const FunctionDecl *FD);
105  void checkCall_bzero(const CallExpr *CE, const FunctionDecl *FD);
106  void checkCall_gets(const CallExpr *CE, const FunctionDecl *FD);
107  void checkCall_getpw(const CallExpr *CE, const FunctionDecl *FD);
108  void checkCall_mktemp(const CallExpr *CE, const FunctionDecl *FD);
109  void checkCall_mkstemp(const CallExpr *CE, const FunctionDecl *FD);
110  void checkCall_strcpy(const CallExpr *CE, const FunctionDecl *FD);
111  void checkCall_strcat(const CallExpr *CE, const FunctionDecl *FD);
112  void checkDeprecatedOrUnsafeBufferHandling(const CallExpr *CE,
113  const FunctionDecl *FD);
114  void checkCall_rand(const CallExpr *CE, const FunctionDecl *FD);
115  void checkCall_random(const CallExpr *CE, const FunctionDecl *FD);
116  void checkCall_vfork(const CallExpr *CE, const FunctionDecl *FD);
117  void checkMsg_decodeValueOfObjCType(const ObjCMessageExpr *ME);
118  void checkUncheckedReturnValue(CallExpr *CE);
119 };
120 } // end anonymous namespace
121 
122 //===----------------------------------------------------------------------===//
123 // AST walking.
124 //===----------------------------------------------------------------------===//
125 
126 void WalkAST::VisitChildren(Stmt *S) {
127  for (Stmt *Child : S->children())
128  if (Child)
129  Visit(Child);
130 }
131 
132 void WalkAST::VisitCallExpr(CallExpr *CE) {
133  // Get the callee.
134  const FunctionDecl *FD = CE->getDirectCallee();
135 
136  if (!FD)
137  return;
138 
139  // Get the name of the callee. If it's a builtin, strip off the prefix.
140  IdentifierInfo *II = FD->getIdentifier();
141  if (!II) // if no identifier, not a simple C function
142  return;
143  StringRef Name = II->getName();
144  if (Name.startswith("__builtin_"))
145  Name = Name.substr(10);
146 
147  // Set the evaluation function by switching on the callee name.
148  FnCheck evalFunction = llvm::StringSwitch<FnCheck>(Name)
149  .Case("bcmp", &WalkAST::checkCall_bcmp)
150  .Case("bcopy", &WalkAST::checkCall_bcopy)
151  .Case("bzero", &WalkAST::checkCall_bzero)
152  .Case("gets", &WalkAST::checkCall_gets)
153  .Case("getpw", &WalkAST::checkCall_getpw)
154  .Case("mktemp", &WalkAST::checkCall_mktemp)
155  .Case("mkstemp", &WalkAST::checkCall_mkstemp)
156  .Case("mkdtemp", &WalkAST::checkCall_mkstemp)
157  .Case("mkstemps", &WalkAST::checkCall_mkstemp)
158  .Cases("strcpy", "__strcpy_chk", &WalkAST::checkCall_strcpy)
159  .Cases("strcat", "__strcat_chk", &WalkAST::checkCall_strcat)
160  .Cases("sprintf", "vsprintf", "scanf", "wscanf", "fscanf", "fwscanf",
161  "vscanf", "vwscanf", "vfscanf", "vfwscanf",
162  &WalkAST::checkDeprecatedOrUnsafeBufferHandling)
163  .Cases("sscanf", "swscanf", "vsscanf", "vswscanf", "swprintf",
164  "snprintf", "vswprintf", "vsnprintf", "memcpy", "memmove",
165  &WalkAST::checkDeprecatedOrUnsafeBufferHandling)
166  .Cases("strncpy", "strncat", "memset",
167  &WalkAST::checkDeprecatedOrUnsafeBufferHandling)
168  .Case("drand48", &WalkAST::checkCall_rand)
169  .Case("erand48", &WalkAST::checkCall_rand)
170  .Case("jrand48", &WalkAST::checkCall_rand)
171  .Case("lrand48", &WalkAST::checkCall_rand)
172  .Case("mrand48", &WalkAST::checkCall_rand)
173  .Case("nrand48", &WalkAST::checkCall_rand)
174  .Case("lcong48", &WalkAST::checkCall_rand)
175  .Case("rand", &WalkAST::checkCall_rand)
176  .Case("rand_r", &WalkAST::checkCall_rand)
177  .Case("random", &WalkAST::checkCall_random)
178  .Case("vfork", &WalkAST::checkCall_vfork)
179  .Default(nullptr);
180 
181  // If the callee isn't defined, it is not of security concern.
182  // Check and evaluate the call.
183  if (evalFunction)
184  (this->*evalFunction)(CE, FD);
185 
186  // Recurse and check children.
187  VisitChildren(CE);
188 }
189 
190 void WalkAST::VisitObjCMessageExpr(ObjCMessageExpr *ME) {
191  MsgCheck evalFunction =
192  llvm::StringSwitch<MsgCheck>(ME->getSelector().getAsString())
193  .Case("decodeValueOfObjCType:at:",
194  &WalkAST::checkMsg_decodeValueOfObjCType)
195  .Default(nullptr);
196 
197  if (evalFunction)
198  (this->*evalFunction)(ME);
199 
200  // Recurse and check children.
201  VisitChildren(ME);
202 }
203 
204 void WalkAST::VisitCompoundStmt(CompoundStmt *S) {
205  for (Stmt *Child : S->children())
206  if (Child) {
207  if (CallExpr *CE = dyn_cast<CallExpr>(Child))
208  checkUncheckedReturnValue(CE);
209  Visit(Child);
210  }
211 }
212 
213 void WalkAST::VisitForStmt(ForStmt *FS) {
214  checkLoopConditionForFloat(FS);
215 
216  // Recurse and check children.
217  VisitChildren(FS);
218 }
219 
220 //===----------------------------------------------------------------------===//
221 // Check: floating point variable used as loop counter.
222 // Originally: <rdar://problem/6336718>
223 // Implements: CERT security coding advisory FLP-30.
224 //===----------------------------------------------------------------------===//
225 
226 // Returns either 'x' or 'y', depending on which one of them is incremented
227 // in 'expr', or nullptr if none of them is incremented.
228 static const DeclRefExpr*
229 getIncrementedVar(const Expr *expr, const VarDecl *x, const VarDecl *y) {
230  expr = expr->IgnoreParenCasts();
231 
232  if (const BinaryOperator *B = dyn_cast<BinaryOperator>(expr)) {
233  if (!(B->isAssignmentOp() || B->isCompoundAssignmentOp() ||
234  B->getOpcode() == BO_Comma))
235  return nullptr;
236 
237  if (const DeclRefExpr *lhs = getIncrementedVar(B->getLHS(), x, y))
238  return lhs;
239 
240  if (const DeclRefExpr *rhs = getIncrementedVar(B->getRHS(), x, y))
241  return rhs;
242 
243  return nullptr;
244  }
245 
246  if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(expr)) {
247  const NamedDecl *ND = DR->getDecl();
248  return ND == x || ND == y ? DR : nullptr;
249  }
250 
251  if (const UnaryOperator *U = dyn_cast<UnaryOperator>(expr))
252  return U->isIncrementDecrementOp()
253  ? getIncrementedVar(U->getSubExpr(), x, y) : nullptr;
254 
255  return nullptr;
256 }
257 
258 /// CheckLoopConditionForFloat - This check looks for 'for' statements that
259 /// use a floating point variable as a loop counter.
260 /// CERT: FLP30-C, FLP30-CPP.
261 ///
262 void WalkAST::checkLoopConditionForFloat(const ForStmt *FS) {
263  if (!filter.check_FloatLoopCounter)
264  return;
265 
266  // Does the loop have a condition?
267  const Expr *condition = FS->getCond();
268 
269  if (!condition)
270  return;
271 
272  // Does the loop have an increment?
273  const Expr *increment = FS->getInc();
274 
275  if (!increment)
276  return;
277 
278  // Strip away '()' and casts.
279  condition = condition->IgnoreParenCasts();
280  increment = increment->IgnoreParenCasts();
281 
282  // Is the loop condition a comparison?
283  const BinaryOperator *B = dyn_cast<BinaryOperator>(condition);
284 
285  if (!B)
286  return;
287 
288  // Is this a comparison?
289  if (!(B->isRelationalOp() || B->isEqualityOp()))
290  return;
291 
292  // Are we comparing variables?
293  const DeclRefExpr *drLHS =
294  dyn_cast<DeclRefExpr>(B->getLHS()->IgnoreParenLValueCasts());
295  const DeclRefExpr *drRHS =
296  dyn_cast<DeclRefExpr>(B->getRHS()->IgnoreParenLValueCasts());
297 
298  // Does at least one of the variables have a floating point type?
299  drLHS = drLHS && drLHS->getType()->isRealFloatingType() ? drLHS : nullptr;
300  drRHS = drRHS && drRHS->getType()->isRealFloatingType() ? drRHS : nullptr;
301 
302  if (!drLHS && !drRHS)
303  return;
304 
305  const VarDecl *vdLHS = drLHS ? dyn_cast<VarDecl>(drLHS->getDecl()) : nullptr;
306  const VarDecl *vdRHS = drRHS ? dyn_cast<VarDecl>(drRHS->getDecl()) : nullptr;
307 
308  if (!vdLHS && !vdRHS)
309  return;
310 
311  // Does either variable appear in increment?
312  const DeclRefExpr *drInc = getIncrementedVar(increment, vdLHS, vdRHS);
313  if (!drInc)
314  return;
315 
316  const VarDecl *vdInc = cast<VarDecl>(drInc->getDecl());
317  assert(vdInc && (vdInc == vdLHS || vdInc == vdRHS));
318 
319  // Emit the error. First figure out which DeclRefExpr in the condition
320  // referenced the compared variable.
321  const DeclRefExpr *drCond = vdLHS == vdInc ? drLHS : drRHS;
322 
324  SmallString<256> sbuf;
325  llvm::raw_svector_ostream os(sbuf);
326 
327  os << "Variable '" << drCond->getDecl()->getName()
328  << "' with floating point type '" << drCond->getType().getAsString()
329  << "' should not be used as a loop counter";
330 
331  ranges.push_back(drCond->getSourceRange());
332  ranges.push_back(drInc->getSourceRange());
333 
334  const char *bugType = "Floating point variable used as loop counter";
335 
336  PathDiagnosticLocation FSLoc =
337  PathDiagnosticLocation::createBegin(FS, BR.getSourceManager(), AC);
338  BR.EmitBasicReport(AC->getDecl(), filter.checkName_FloatLoopCounter,
339  bugType, "Security", os.str(),
340  FSLoc, ranges);
341 }
342 
343 //===----------------------------------------------------------------------===//
344 // Check: Any use of bcmp.
345 // CWE-477: Use of Obsolete Functions
346 // bcmp was deprecated in POSIX.1-2008
347 //===----------------------------------------------------------------------===//
348 
349 void WalkAST::checkCall_bcmp(const CallExpr *CE, const FunctionDecl *FD) {
350  if (!filter.check_bcmp)
351  return;
352 
353  const FunctionProtoType *FPT = FD->getType()->getAs<FunctionProtoType>();
354  if (!FPT)
355  return;
356 
357  // Verify that the function takes three arguments.
358  if (FPT->getNumParams() != 3)
359  return;
360 
361  for (int i = 0; i < 2; i++) {
362  // Verify the first and second argument type is void*.
363  const PointerType *PT = FPT->getParamType(i)->getAs<PointerType>();
364  if (!PT)
365  return;
366 
367  if (PT->getPointeeType().getUnqualifiedType() != BR.getContext().VoidTy)
368  return;
369  }
370 
371  // Verify the third argument type is integer.
373  return;
374 
375  // Issue a warning.
376  PathDiagnosticLocation CELoc =
377  PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
378  BR.EmitBasicReport(AC->getDecl(), filter.checkName_bcmp,
379  "Use of deprecated function in call to 'bcmp()'",
380  "Security",
381  "The bcmp() function is obsoleted by memcmp().",
382  CELoc, CE->getCallee()->getSourceRange());
383 }
384 
385 //===----------------------------------------------------------------------===//
386 // Check: Any use of bcopy.
387 // CWE-477: Use of Obsolete Functions
388 // bcopy was deprecated in POSIX.1-2008
389 //===----------------------------------------------------------------------===//
390 
391 void WalkAST::checkCall_bcopy(const CallExpr *CE, const FunctionDecl *FD) {
392  if (!filter.check_bcopy)
393  return;
394 
395  const FunctionProtoType *FPT = FD->getType()->getAs<FunctionProtoType>();
396  if (!FPT)
397  return;
398 
399  // Verify that the function takes three arguments.
400  if (FPT->getNumParams() != 3)
401  return;
402 
403  for (int i = 0; i < 2; i++) {
404  // Verify the first and second argument type is void*.
405  const PointerType *PT = FPT->getParamType(i)->getAs<PointerType>();
406  if (!PT)
407  return;
408 
409  if (PT->getPointeeType().getUnqualifiedType() != BR.getContext().VoidTy)
410  return;
411  }
412 
413  // Verify the third argument type is integer.
415  return;
416 
417  // Issue a warning.
418  PathDiagnosticLocation CELoc =
419  PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
420  BR.EmitBasicReport(AC->getDecl(), filter.checkName_bcopy,
421  "Use of deprecated function in call to 'bcopy()'",
422  "Security",
423  "The bcopy() function is obsoleted by memcpy() "
424  "or memmove().",
425  CELoc, CE->getCallee()->getSourceRange());
426 }
427 
428 //===----------------------------------------------------------------------===//
429 // Check: Any use of bzero.
430 // CWE-477: Use of Obsolete Functions
431 // bzero was deprecated in POSIX.1-2008
432 //===----------------------------------------------------------------------===//
433 
434 void WalkAST::checkCall_bzero(const CallExpr *CE, const FunctionDecl *FD) {
435  if (!filter.check_bzero)
436  return;
437 
438  const FunctionProtoType *FPT = FD->getType()->getAs<FunctionProtoType>();
439  if (!FPT)
440  return;
441 
442  // Verify that the function takes two arguments.
443  if (FPT->getNumParams() != 2)
444  return;
445 
446  // Verify the first argument type is void*.
447  const PointerType *PT = FPT->getParamType(0)->getAs<PointerType>();
448  if (!PT)
449  return;
450 
451  if (PT->getPointeeType().getUnqualifiedType() != BR.getContext().VoidTy)
452  return;
453 
454  // Verify the second argument type is integer.
456  return;
457 
458  // Issue a warning.
459  PathDiagnosticLocation CELoc =
460  PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
461  BR.EmitBasicReport(AC->getDecl(), filter.checkName_bzero,
462  "Use of deprecated function in call to 'bzero()'",
463  "Security",
464  "The bzero() function is obsoleted by memset().",
465  CELoc, CE->getCallee()->getSourceRange());
466 }
467 
468 
469 //===----------------------------------------------------------------------===//
470 // Check: Any use of 'gets' is insecure.
471 // Originally: <rdar://problem/6335715>
472 // Implements (part of): 300-BSI (buildsecurityin.us-cert.gov)
473 // CWE-242: Use of Inherently Dangerous Function
474 //===----------------------------------------------------------------------===//
475 
476 void WalkAST::checkCall_gets(const CallExpr *CE, const FunctionDecl *FD) {
477  if (!filter.check_gets)
478  return;
479 
480  const FunctionProtoType *FPT = FD->getType()->getAs<FunctionProtoType>();
481  if (!FPT)
482  return;
483 
484  // Verify that the function takes a single argument.
485  if (FPT->getNumParams() != 1)
486  return;
487 
488  // Is the argument a 'char*'?
489  const PointerType *PT = FPT->getParamType(0)->getAs<PointerType>();
490  if (!PT)
491  return;
492 
493  if (PT->getPointeeType().getUnqualifiedType() != BR.getContext().CharTy)
494  return;
495 
496  // Issue a warning.
497  PathDiagnosticLocation CELoc =
498  PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
499  BR.EmitBasicReport(AC->getDecl(), filter.checkName_gets,
500  "Potential buffer overflow in call to 'gets'",
501  "Security",
502  "Call to function 'gets' is extremely insecure as it can "
503  "always result in a buffer overflow",
504  CELoc, CE->getCallee()->getSourceRange());
505 }
506 
507 //===----------------------------------------------------------------------===//
508 // Check: Any use of 'getpwd' is insecure.
509 // CWE-477: Use of Obsolete Functions
510 //===----------------------------------------------------------------------===//
511 
512 void WalkAST::checkCall_getpw(const CallExpr *CE, const FunctionDecl *FD) {
513  if (!filter.check_getpw)
514  return;
515 
516  const FunctionProtoType *FPT = FD->getType()->getAs<FunctionProtoType>();
517  if (!FPT)
518  return;
519 
520  // Verify that the function takes two arguments.
521  if (FPT->getNumParams() != 2)
522  return;
523 
524  // Verify the first argument type is integer.
526  return;
527 
528  // Verify the second argument type is char*.
529  const PointerType *PT = FPT->getParamType(1)->getAs<PointerType>();
530  if (!PT)
531  return;
532 
533  if (PT->getPointeeType().getUnqualifiedType() != BR.getContext().CharTy)
534  return;
535 
536  // Issue a warning.
537  PathDiagnosticLocation CELoc =
538  PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
539  BR.EmitBasicReport(AC->getDecl(), filter.checkName_getpw,
540  "Potential buffer overflow in call to 'getpw'",
541  "Security",
542  "The getpw() function is dangerous as it may overflow the "
543  "provided buffer. It is obsoleted by getpwuid().",
544  CELoc, CE->getCallee()->getSourceRange());
545 }
546 
547 //===----------------------------------------------------------------------===//
548 // Check: Any use of 'mktemp' is insecure. It is obsoleted by mkstemp().
549 // CWE-377: Insecure Temporary File
550 //===----------------------------------------------------------------------===//
551 
552 void WalkAST::checkCall_mktemp(const CallExpr *CE, const FunctionDecl *FD) {
553  if (!filter.check_mktemp) {
554  // Fall back to the security check of looking for enough 'X's in the
555  // format string, since that is a less severe warning.
556  checkCall_mkstemp(CE, FD);
557  return;
558  }
559 
560  const FunctionProtoType *FPT = FD->getType()->getAs<FunctionProtoType>();
561  if(!FPT)
562  return;
563 
564  // Verify that the function takes a single argument.
565  if (FPT->getNumParams() != 1)
566  return;
567 
568  // Verify that the argument is Pointer Type.
569  const PointerType *PT = FPT->getParamType(0)->getAs<PointerType>();
570  if (!PT)
571  return;
572 
573  // Verify that the argument is a 'char*'.
574  if (PT->getPointeeType().getUnqualifiedType() != BR.getContext().CharTy)
575  return;
576 
577  // Issue a warning.
578  PathDiagnosticLocation CELoc =
579  PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
580  BR.EmitBasicReport(AC->getDecl(), filter.checkName_mktemp,
581  "Potential insecure temporary file in call 'mktemp'",
582  "Security",
583  "Call to function 'mktemp' is insecure as it always "
584  "creates or uses insecure temporary file. Use 'mkstemp' "
585  "instead",
586  CELoc, CE->getCallee()->getSourceRange());
587 }
588 
589 //===----------------------------------------------------------------------===//
590 // Check: Use of 'mkstemp', 'mktemp', 'mkdtemp' should contain at least 6 X's.
591 //===----------------------------------------------------------------------===//
592 
593 void WalkAST::checkCall_mkstemp(const CallExpr *CE, const FunctionDecl *FD) {
594  if (!filter.check_mkstemp)
595  return;
596 
597  StringRef Name = FD->getIdentifier()->getName();
598  std::pair<signed, signed> ArgSuffix =
599  llvm::StringSwitch<std::pair<signed, signed> >(Name)
600  .Case("mktemp", std::make_pair(0,-1))
601  .Case("mkstemp", std::make_pair(0,-1))
602  .Case("mkdtemp", std::make_pair(0,-1))
603  .Case("mkstemps", std::make_pair(0,1))
604  .Default(std::make_pair(-1, -1));
605 
606  assert(ArgSuffix.first >= 0 && "Unsupported function");
607 
608  // Check if the number of arguments is consistent with out expectations.
609  unsigned numArgs = CE->getNumArgs();
610  if ((signed) numArgs <= ArgSuffix.first)
611  return;
612 
613  const StringLiteral *strArg =
614  dyn_cast<StringLiteral>(CE->getArg((unsigned)ArgSuffix.first)
615  ->IgnoreParenImpCasts());
616 
617  // Currently we only handle string literals. It is possible to do better,
618  // either by looking at references to const variables, or by doing real
619  // flow analysis.
620  if (!strArg || strArg->getCharByteWidth() != 1)
621  return;
622 
623  // Count the number of X's, taking into account a possible cutoff suffix.
624  StringRef str = strArg->getString();
625  unsigned numX = 0;
626  unsigned n = str.size();
627 
628  // Take into account the suffix.
629  unsigned suffix = 0;
630  if (ArgSuffix.second >= 0) {
631  const Expr *suffixEx = CE->getArg((unsigned)ArgSuffix.second);
632  Expr::EvalResult EVResult;
633  if (!suffixEx->EvaluateAsInt(EVResult, BR.getContext()))
634  return;
635  llvm::APSInt Result = EVResult.Val.getInt();
636  // FIXME: Issue a warning.
637  if (Result.isNegative())
638  return;
639  suffix = (unsigned) Result.getZExtValue();
640  n = (n > suffix) ? n - suffix : 0;
641  }
642 
643  for (unsigned i = 0; i < n; ++i)
644  if (str[i] == 'X') ++numX;
645 
646  if (numX >= 6)
647  return;
648 
649  // Issue a warning.
650  PathDiagnosticLocation CELoc =
651  PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
652  SmallString<512> buf;
653  llvm::raw_svector_ostream out(buf);
654  out << "Call to '" << Name << "' should have at least 6 'X's in the"
655  " format string to be secure (" << numX << " 'X'";
656  if (numX != 1)
657  out << 's';
658  out << " seen";
659  if (suffix) {
660  out << ", " << suffix << " character";
661  if (suffix > 1)
662  out << 's';
663  out << " used as a suffix";
664  }
665  out << ')';
666  BR.EmitBasicReport(AC->getDecl(), filter.checkName_mkstemp,
667  "Insecure temporary file creation", "Security",
668  out.str(), CELoc, strArg->getSourceRange());
669 }
670 
671 //===----------------------------------------------------------------------===//
672 // Check: Any use of 'strcpy' is insecure.
673 //
674 // CWE-119: Improper Restriction of Operations within
675 // the Bounds of a Memory Buffer
676 //===----------------------------------------------------------------------===//
677 
678 void WalkAST::checkCall_strcpy(const CallExpr *CE, const FunctionDecl *FD) {
679  if (!filter.check_strcpy)
680  return;
681 
682  if (!checkCall_strCommon(CE, FD))
683  return;
684 
685  const auto *Target = CE->getArg(0)->IgnoreImpCasts(),
686  *Source = CE->getArg(1)->IgnoreImpCasts();
687 
688  if (const auto *Array = dyn_cast<ConstantArrayType>(Target->getType())) {
689  uint64_t ArraySize = BR.getContext().getTypeSize(Array) / 8;
690  if (const auto *String = dyn_cast<StringLiteral>(Source)) {
691  if (ArraySize >= String->getLength() + 1)
692  return;
693  }
694  }
695 
696  // Issue a warning.
697  PathDiagnosticLocation CELoc =
698  PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
699  BR.EmitBasicReport(AC->getDecl(), filter.checkName_strcpy,
700  "Potential insecure memory buffer bounds restriction in "
701  "call 'strcpy'",
702  "Security",
703  "Call to function 'strcpy' is insecure as it does not "
704  "provide bounding of the memory buffer. Replace "
705  "unbounded copy functions with analogous functions that "
706  "support length arguments such as 'strlcpy'. CWE-119.",
707  CELoc, CE->getCallee()->getSourceRange());
708 }
709 
710 //===----------------------------------------------------------------------===//
711 // Check: Any use of 'strcat' is insecure.
712 //
713 // CWE-119: Improper Restriction of Operations within
714 // the Bounds of a Memory Buffer
715 //===----------------------------------------------------------------------===//
716 
717 void WalkAST::checkCall_strcat(const CallExpr *CE, const FunctionDecl *FD) {
718  if (!filter.check_strcpy)
719  return;
720 
721  if (!checkCall_strCommon(CE, FD))
722  return;
723 
724  // Issue a warning.
725  PathDiagnosticLocation CELoc =
726  PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
727  BR.EmitBasicReport(AC->getDecl(), filter.checkName_strcpy,
728  "Potential insecure memory buffer bounds restriction in "
729  "call 'strcat'",
730  "Security",
731  "Call to function 'strcat' is insecure as it does not "
732  "provide bounding of the memory buffer. Replace "
733  "unbounded copy functions with analogous functions that "
734  "support length arguments such as 'strlcat'. CWE-119.",
735  CELoc, CE->getCallee()->getSourceRange());
736 }
737 
738 //===----------------------------------------------------------------------===//
739 // Check: Any use of 'sprintf', 'vsprintf', 'scanf', 'wscanf', 'fscanf',
740 // 'fwscanf', 'vscanf', 'vwscanf', 'vfscanf', 'vfwscanf', 'sscanf',
741 // 'swscanf', 'vsscanf', 'vswscanf', 'swprintf', 'snprintf', 'vswprintf',
742 // 'vsnprintf', 'memcpy', 'memmove', 'strncpy', 'strncat', 'memset'
743 // is deprecated since C11.
744 //
745 // Use of 'sprintf', 'vsprintf', 'scanf', 'wscanf','fscanf',
746 // 'fwscanf', 'vscanf', 'vwscanf', 'vfscanf', 'vfwscanf', 'sscanf',
747 // 'swscanf', 'vsscanf', 'vswscanf' without buffer limitations
748 // is insecure.
749 //
750 // CWE-119: Improper Restriction of Operations within
751 // the Bounds of a Memory Buffer
752 //===----------------------------------------------------------------------===//
753 
754 void WalkAST::checkDeprecatedOrUnsafeBufferHandling(const CallExpr *CE,
755  const FunctionDecl *FD) {
756  if (!filter.check_DeprecatedOrUnsafeBufferHandling)
757  return;
758 
759  if (!BR.getContext().getLangOpts().C11)
760  return;
761 
762  // Issue a warning. ArgIndex == -1: Deprecated but not unsafe (has size
763  // restrictions).
764  enum { DEPR_ONLY = -1, UNKNOWN_CALL = -2 };
765 
766  StringRef Name = FD->getIdentifier()->getName();
767  if (Name.startswith("__builtin_"))
768  Name = Name.substr(10);
769 
770  int ArgIndex =
771  llvm::StringSwitch<int>(Name)
772  .Cases("scanf", "wscanf", "vscanf", "vwscanf", 0)
773  .Cases("sprintf", "vsprintf", "fscanf", "fwscanf", "vfscanf",
774  "vfwscanf", "sscanf", "swscanf", "vsscanf", "vswscanf", 1)
775  .Cases("swprintf", "snprintf", "vswprintf", "vsnprintf", "memcpy",
776  "memmove", "memset", "strncpy", "strncat", DEPR_ONLY)
777  .Default(UNKNOWN_CALL);
778 
779  assert(ArgIndex != UNKNOWN_CALL && "Unsupported function");
780  bool BoundsProvided = ArgIndex == DEPR_ONLY;
781 
782  if (!BoundsProvided) {
783  // Currently we only handle (not wide) string literals. It is possible to do
784  // better, either by looking at references to const variables, or by doing
785  // real flow analysis.
786  auto FormatString =
787  dyn_cast<StringLiteral>(CE->getArg(ArgIndex)->IgnoreParenImpCasts());
788  if (FormatString &&
789  FormatString->getString().find("%s") == StringRef::npos &&
790  FormatString->getString().find("%[") == StringRef::npos)
791  BoundsProvided = true;
792  }
793 
794  SmallString<128> Buf1;
795  SmallString<512> Buf2;
796  llvm::raw_svector_ostream Out1(Buf1);
797  llvm::raw_svector_ostream Out2(Buf2);
798 
799  Out1 << "Potential insecure memory buffer bounds restriction in call '"
800  << Name << "'";
801  Out2 << "Call to function '" << Name
802  << "' is insecure as it does not provide ";
803 
804  if (!BoundsProvided) {
805  Out2 << "bounding of the memory buffer or ";
806  }
807 
808  Out2 << "security checks introduced "
809  "in the C11 standard. Replace with analogous functions that "
810  "support length arguments or provides boundary checks such as '"
811  << Name << "_s' in case of C11";
812 
813  PathDiagnosticLocation CELoc =
814  PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
815  BR.EmitBasicReport(AC->getDecl(),
816  filter.checkName_DeprecatedOrUnsafeBufferHandling,
817  Out1.str(), "Security", Out2.str(), CELoc,
818  CE->getCallee()->getSourceRange());
819 }
820 
821 //===----------------------------------------------------------------------===//
822 // Common check for str* functions with no bounds parameters.
823 //===----------------------------------------------------------------------===//
824 
825 bool WalkAST::checkCall_strCommon(const CallExpr *CE, const FunctionDecl *FD) {
826  const FunctionProtoType *FPT = FD->getType()->getAs<FunctionProtoType>();
827  if (!FPT)
828  return false;
829 
830  // Verify the function takes two arguments, three in the _chk version.
831  int numArgs = FPT->getNumParams();
832  if (numArgs != 2 && numArgs != 3)
833  return false;
834 
835  // Verify the type for both arguments.
836  for (int i = 0; i < 2; i++) {
837  // Verify that the arguments are pointers.
838  const PointerType *PT = FPT->getParamType(i)->getAs<PointerType>();
839  if (!PT)
840  return false;
841 
842  // Verify that the argument is a 'char*'.
843  if (PT->getPointeeType().getUnqualifiedType() != BR.getContext().CharTy)
844  return false;
845  }
846 
847  return true;
848 }
849 
850 //===----------------------------------------------------------------------===//
851 // Check: Linear congruent random number generators should not be used
852 // Originally: <rdar://problem/63371000>
853 // CWE-338: Use of cryptographically weak prng
854 //===----------------------------------------------------------------------===//
855 
856 void WalkAST::checkCall_rand(const CallExpr *CE, const FunctionDecl *FD) {
857  if (!filter.check_rand || !CheckRand)
858  return;
859 
860  const FunctionProtoType *FTP = FD->getType()->getAs<FunctionProtoType>();
861  if (!FTP)
862  return;
863 
864  if (FTP->getNumParams() == 1) {
865  // Is the argument an 'unsigned short *'?
866  // (Actually any integer type is allowed.)
867  const PointerType *PT = FTP->getParamType(0)->getAs<PointerType>();
868  if (!PT)
869  return;
870 
872  return;
873  } else if (FTP->getNumParams() != 0)
874  return;
875 
876  // Issue a warning.
877  SmallString<256> buf1;
878  llvm::raw_svector_ostream os1(buf1);
879  os1 << '\'' << *FD << "' is a poor random number generator";
880 
881  SmallString<256> buf2;
882  llvm::raw_svector_ostream os2(buf2);
883  os2 << "Function '" << *FD
884  << "' is obsolete because it implements a poor random number generator."
885  << " Use 'arc4random' instead";
886 
887  PathDiagnosticLocation CELoc =
888  PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
889  BR.EmitBasicReport(AC->getDecl(), filter.checkName_rand, os1.str(),
890  "Security", os2.str(), CELoc,
891  CE->getCallee()->getSourceRange());
892 }
893 
894 //===----------------------------------------------------------------------===//
895 // Check: 'random' should not be used
896 // Originally: <rdar://problem/63371000>
897 //===----------------------------------------------------------------------===//
898 
899 void WalkAST::checkCall_random(const CallExpr *CE, const FunctionDecl *FD) {
900  if (!CheckRand || !filter.check_rand)
901  return;
902 
903  const FunctionProtoType *FTP = FD->getType()->getAs<FunctionProtoType>();
904  if (!FTP)
905  return;
906 
907  // Verify that the function takes no argument.
908  if (FTP->getNumParams() != 0)
909  return;
910 
911  // Issue a warning.
912  PathDiagnosticLocation CELoc =
913  PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
914  BR.EmitBasicReport(AC->getDecl(), filter.checkName_rand,
915  "'random' is not a secure random number generator",
916  "Security",
917  "The 'random' function produces a sequence of values that "
918  "an adversary may be able to predict. Use 'arc4random' "
919  "instead", CELoc, CE->getCallee()->getSourceRange());
920 }
921 
922 //===----------------------------------------------------------------------===//
923 // Check: 'vfork' should not be used.
924 // POS33-C: Do not use vfork().
925 //===----------------------------------------------------------------------===//
926 
927 void WalkAST::checkCall_vfork(const CallExpr *CE, const FunctionDecl *FD) {
928  if (!filter.check_vfork)
929  return;
930 
931  // All calls to vfork() are insecure, issue a warning.
932  PathDiagnosticLocation CELoc =
933  PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
934  BR.EmitBasicReport(AC->getDecl(), filter.checkName_vfork,
935  "Potential insecure implementation-specific behavior in "
936  "call 'vfork'",
937  "Security",
938  "Call to function 'vfork' is insecure as it can lead to "
939  "denial of service situations in the parent process. "
940  "Replace calls to vfork with calls to the safer "
941  "'posix_spawn' function",
942  CELoc, CE->getCallee()->getSourceRange());
943 }
944 
945 //===----------------------------------------------------------------------===//
946 // Check: '-decodeValueOfObjCType:at:' should not be used.
947 // It is deprecated in favor of '-decodeValueOfObjCType:at:size:' due to
948 // likelihood of buffer overflows.
949 //===----------------------------------------------------------------------===//
950 
951 void WalkAST::checkMsg_decodeValueOfObjCType(const ObjCMessageExpr *ME) {
952  if (!filter.check_decodeValueOfObjCType)
953  return;
954 
955  // Check availability of the secure alternative:
956  // iOS 11+, macOS 10.13+, tvOS 11+, and watchOS 4.0+
957  // FIXME: We probably shouldn't register the check if it's not available.
958  const TargetInfo &TI = AC->getASTContext().getTargetInfo();
959  const llvm::Triple &T = TI.getTriple();
960  const VersionTuple &VT = TI.getPlatformMinVersion();
961  switch (T.getOS()) {
962  case llvm::Triple::IOS:
963  if (VT < VersionTuple(11, 0))
964  return;
965  break;
966  case llvm::Triple::MacOSX:
967  if (VT < VersionTuple(10, 13))
968  return;
969  break;
970  case llvm::Triple::WatchOS:
971  if (VT < VersionTuple(4, 0))
972  return;
973  break;
974  case llvm::Triple::TvOS:
975  if (VT < VersionTuple(11, 0))
976  return;
977  break;
978  default:
979  return;
980  }
981 
982  PathDiagnosticLocation MELoc =
983  PathDiagnosticLocation::createBegin(ME, BR.getSourceManager(), AC);
984  BR.EmitBasicReport(
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.",
990  MELoc, ME->getSourceRange());
991 }
992 
993 //===----------------------------------------------------------------------===//
994 // Check: Should check whether privileges are dropped successfully.
995 // Originally: <rdar://problem/6337132>
996 //===----------------------------------------------------------------------===//
997 
998 void WalkAST::checkUncheckedReturnValue(CallExpr *CE) {
999  if (!filter.check_UncheckedReturn)
1000  return;
1001 
1002  const FunctionDecl *FD = CE->getDirectCallee();
1003  if (!FD)
1004  return;
1005 
1006  if (II_setid[0] == nullptr) {
1007  static const char * const identifiers[num_setids] = {
1008  "setuid", "setgid", "seteuid", "setegid",
1009  "setreuid", "setregid"
1010  };
1011 
1012  for (size_t i = 0; i < num_setids; i++)
1013  II_setid[i] = &BR.getContext().Idents.get(identifiers[i]);
1014  }
1015 
1016  const IdentifierInfo *id = FD->getIdentifier();
1017  size_t identifierid;
1018 
1019  for (identifierid = 0; identifierid < num_setids; identifierid++)
1020  if (id == II_setid[identifierid])
1021  break;
1022 
1023  if (identifierid >= num_setids)
1024  return;
1025 
1026  const FunctionProtoType *FTP = FD->getType()->getAs<FunctionProtoType>();
1027  if (!FTP)
1028  return;
1029 
1030  // Verify that the function takes one or two arguments (depending on
1031  // the function).
1032  if (FTP->getNumParams() != (identifierid < 4 ? 1 : 2))
1033  return;
1034 
1035  // The arguments must be integers.
1036  for (unsigned i = 0; i < FTP->getNumParams(); i++)
1038  return;
1039 
1040  // Issue a warning.
1041  SmallString<256> buf1;
1042  llvm::raw_svector_ostream os1(buf1);
1043  os1 << "Return value is not checked in call to '" << *FD << '\'';
1044 
1045  SmallString<256> buf2;
1046  llvm::raw_svector_ostream os2(buf2);
1047  os2 << "The return value from the call to '" << *FD
1048  << "' is not checked. If an error occurs in '" << *FD
1049  << "', the following code may execute with unexpected privileges";
1050 
1051  PathDiagnosticLocation CELoc =
1052  PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
1053  BR.EmitBasicReport(AC->getDecl(), filter.checkName_UncheckedReturn, os1.str(),
1054  "Security", os2.str(), CELoc,
1055  CE->getCallee()->getSourceRange());
1056 }
1057 
1058 //===----------------------------------------------------------------------===//
1059 // SecuritySyntaxChecker
1060 //===----------------------------------------------------------------------===//
1061 
1062 namespace {
1063 class SecuritySyntaxChecker : public Checker<check::ASTCodeBody> {
1064 public:
1065  ChecksFilter filter;
1066 
1067  void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
1068  BugReporter &BR) const {
1069  WalkAST walker(BR, mgr.getAnalysisDeclContext(D), filter);
1070  walker.Visit(D->getBody());
1071  }
1072 };
1073 }
1074 
1075 void ento::registerSecuritySyntaxChecker(CheckerManager &mgr) {
1076  mgr.registerChecker<SecuritySyntaxChecker>();
1077 }
1078 
1079 bool ento::shouldRegisterSecuritySyntaxChecker(const CheckerManager &mgr) {
1080  return true;
1081 }
1082 
1083 #define REGISTER_CHECKER(name) \
1084  void ento::register##name(CheckerManager &mgr) { \
1085  SecuritySyntaxChecker *checker = mgr.getChecker<SecuritySyntaxChecker>(); \
1086  checker->filter.check_##name = true; \
1087  checker->filter.checkName_##name = mgr.getCurrentCheckerName(); \
1088  } \
1089  \
1090  bool ento::shouldRegister##name(const CheckerManager &mgr) { return true; }
1091 
1092 REGISTER_CHECKER(bcmp)
1093 REGISTER_CHECKER(bcopy)
1094 REGISTER_CHECKER(bzero)
1095 REGISTER_CHECKER(gets)
1096 REGISTER_CHECKER(getpw)
1097 REGISTER_CHECKER(mkstemp)
1098 REGISTER_CHECKER(mktemp)
1099 REGISTER_CHECKER(strcpy)
1100 REGISTER_CHECKER(rand)
1101 REGISTER_CHECKER(vfork)
1102 REGISTER_CHECKER(FloatLoopCounter)
1103 REGISTER_CHECKER(UncheckedReturn)
1104 REGISTER_CHECKER(DeprecatedOrUnsafeBufferHandling)
1105 REGISTER_CHECKER(decodeValueOfObjCType)
Expr * getInc()
Definition: Stmt.h:2477
Represents a function declaration or definition.
Definition: Decl.h:1783
VersionTuple getPlatformMinVersion() const
Retrieve the minimum desired version of the platform, to which the program should be compiled...
Definition: TargetInfo.h:1341
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:2645
QualType getPointeeType() const
Definition: Type.h:2655
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Definition: Expr.h:2910
Selector getSelector() const
Definition: ExprObjC.cpp:306
virtual Stmt * getBody() const
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
Definition: DeclBase.h:1006
Stmt - This represents one statement.
Definition: Stmt.h:68
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
Definition: Expr.h:2897
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Definition: TargetInfo.h:1056
bool isRealFloatingType() const
Floating point categories.
Definition: Type.cpp:2122
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:89
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:647
Represents a variable declaration or definition.
Definition: Decl.h:820
unsigned getNumParams() const
Definition: Type.h:4096
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
const T * getAs() const
Member-template getAs<specific type>&#39;.
Definition: Type.h:7153
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition: Decl.h:244
One of these records is kept for each identifier that is lexed.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:174
AnalysisDeclContext contains the context data for the function, method or block under analysis...
unsigned getCharByteWidth() const
Definition: Expr.h:1833
static bool isRelationalOp(Opcode Opc)
Definition: Expr.h:3725
ForStmt - This represents a &#39;for (init;cond;inc)&#39; stmt.
Definition: Stmt.h:2444
static bool isEqualityOp(Opcode Opc)
Definition: Expr.h:3728
APValue Val
Val - This is the value the expression can be folded to.
Definition: Expr.h:596
child_range children()
Definition: Stmt.cpp:224
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:3632
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
Definition: Expr.cpp:2952
Expr * getCond()
Definition: Stmt.h:2476
child_range children()
Definition: Stmt.h:1481
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point...
Definition: Expr.cpp:2927
bool isIntegralOrUnscopedEnumerationType() const
Determine whether this type is an integral or unscoped enumeration type.
Definition: Type.cpp:1941
StringRef getString() const
Definition: Expr.h:1803
CompoundStmt - This represents a group of statements like { stmt stmt }.
Definition: Stmt.h:1366
Represents a prototype with parameter type info, e.g.
Definition: Type.h:3886
Exposes information about the current target.
Definition: TargetInfo.h:179
This represents one expression.
Definition: Expr.h:110
Expr * getCallee()
Definition: Expr.h:2871
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
Definition: Expr.h:2889
QualType getType() const
Definition: Expr.h:142
An expression that sends a message to the given Objective-C object or class.
Definition: ExprObjC.h:940
UnaryOperator - This represents the unary-expression&#39;s (except sizeof and alignof), the postinc/postdec operators from postfix-expression, and various extensions.
Definition: Expr.h:2119
ValueDecl * getDecl()
Definition: Expr.h:1250
This file defines AnalysisDeclContext, a class that manages the analysis context data for context sen...
static PathDiagnosticLocation createBegin(const Decl *D, const SourceManager &SM)
Create a location for the beginning of the declaration.
std::string getAsString() const
Derive the full selector name (e.g.
llvm::APSInt APSInt
static const DeclRefExpr * getIncrementedVar(const Expr *expr, const VarDecl *x, const VarDecl *y)
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:183
#define REGISTER_CHECKER(name)
Expr * getLHS() const
Definition: Expr.h:3681
StringRef getName() const
Return the actual identifier string.
Dataflow Directional Tag Classes.
EvalResult is a struct with detailed info about an evaluated expression.
Definition: Expr.h:594
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
Definition: Type.h:997
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Definition: Expr.cpp:2947
Expr * IgnoreParenLValueCasts() LLVM_READONLY
Skip past any parentheses and lvalue casts which might surround this expression until reaching a fixe...
Definition: Expr.cpp:2964
QualType getParamType(unsigned i) const
Definition: Type.h:4098
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...
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition: Type.h:6482
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:263
StringLiteral - This represents a string literal expression, e.g.
Definition: Expr.h:1720
Defines the clang::TargetInfo interface.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2756
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:250
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1178
Expr * getRHS() const
Definition: Expr.h:3683
static bool isArc4RandomAvailable(const ASTContext &Ctx)
QualType getType() const
Definition: Decl.h:630
This represents a decl that may have a name.
Definition: Decl.h:223
APSInt & getInt()
Definition: APValue.h:380