clang  14.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 && !FormatString->getString().contains("%s") &&
789  !FormatString->getString().contains("%["))
790  BoundsProvided = true;
791  }
792 
793  SmallString<128> Buf1;
794  SmallString<512> Buf2;
795  llvm::raw_svector_ostream Out1(Buf1);
796  llvm::raw_svector_ostream Out2(Buf2);
797 
798  Out1 << "Potential insecure memory buffer bounds restriction in call '"
799  << Name << "'";
800  Out2 << "Call to function '" << Name
801  << "' is insecure as it does not provide ";
802 
803  if (!BoundsProvided) {
804  Out2 << "bounding of the memory buffer or ";
805  }
806 
807  Out2 << "security checks introduced "
808  "in the C11 standard. Replace with analogous functions that "
809  "support length arguments or provides boundary checks such as '"
810  << Name << "_s' in case of C11";
811 
812  PathDiagnosticLocation CELoc =
813  PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
814  BR.EmitBasicReport(AC->getDecl(),
815  filter.checkName_DeprecatedOrUnsafeBufferHandling,
816  Out1.str(), "Security", Out2.str(), CELoc,
817  CE->getCallee()->getSourceRange());
818 }
819 
820 //===----------------------------------------------------------------------===//
821 // Common check for str* functions with no bounds parameters.
822 //===----------------------------------------------------------------------===//
823 
824 bool WalkAST::checkCall_strCommon(const CallExpr *CE, const FunctionDecl *FD) {
825  const FunctionProtoType *FPT = FD->getType()->getAs<FunctionProtoType>();
826  if (!FPT)
827  return false;
828 
829  // Verify the function takes two arguments, three in the _chk version.
830  int numArgs = FPT->getNumParams();
831  if (numArgs != 2 && numArgs != 3)
832  return false;
833 
834  // Verify the type for both arguments.
835  for (int i = 0; i < 2; i++) {
836  // Verify that the arguments are pointers.
837  const PointerType *PT = FPT->getParamType(i)->getAs<PointerType>();
838  if (!PT)
839  return false;
840 
841  // Verify that the argument is a 'char*'.
842  if (PT->getPointeeType().getUnqualifiedType() != BR.getContext().CharTy)
843  return false;
844  }
845 
846  return true;
847 }
848 
849 //===----------------------------------------------------------------------===//
850 // Check: Linear congruent random number generators should not be used
851 // Originally: <rdar://problem/63371000>
852 // CWE-338: Use of cryptographically weak prng
853 //===----------------------------------------------------------------------===//
854 
855 void WalkAST::checkCall_rand(const CallExpr *CE, const FunctionDecl *FD) {
856  if (!filter.check_rand || !CheckRand)
857  return;
858 
859  const FunctionProtoType *FTP = FD->getType()->getAs<FunctionProtoType>();
860  if (!FTP)
861  return;
862 
863  if (FTP->getNumParams() == 1) {
864  // Is the argument an 'unsigned short *'?
865  // (Actually any integer type is allowed.)
866  const PointerType *PT = FTP->getParamType(0)->getAs<PointerType>();
867  if (!PT)
868  return;
869 
871  return;
872  } else if (FTP->getNumParams() != 0)
873  return;
874 
875  // Issue a warning.
876  SmallString<256> buf1;
877  llvm::raw_svector_ostream os1(buf1);
878  os1 << '\'' << *FD << "' is a poor random number generator";
879 
880  SmallString<256> buf2;
881  llvm::raw_svector_ostream os2(buf2);
882  os2 << "Function '" << *FD
883  << "' is obsolete because it implements a poor random number generator."
884  << " Use 'arc4random' instead";
885 
886  PathDiagnosticLocation CELoc =
887  PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
888  BR.EmitBasicReport(AC->getDecl(), filter.checkName_rand, os1.str(),
889  "Security", os2.str(), CELoc,
890  CE->getCallee()->getSourceRange());
891 }
892 
893 //===----------------------------------------------------------------------===//
894 // Check: 'random' should not be used
895 // Originally: <rdar://problem/63371000>
896 //===----------------------------------------------------------------------===//
897 
898 void WalkAST::checkCall_random(const CallExpr *CE, const FunctionDecl *FD) {
899  if (!CheckRand || !filter.check_rand)
900  return;
901 
902  const FunctionProtoType *FTP = FD->getType()->getAs<FunctionProtoType>();
903  if (!FTP)
904  return;
905 
906  // Verify that the function takes no argument.
907  if (FTP->getNumParams() != 0)
908  return;
909 
910  // Issue a warning.
911  PathDiagnosticLocation CELoc =
912  PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
913  BR.EmitBasicReport(AC->getDecl(), filter.checkName_rand,
914  "'random' is not a secure random number generator",
915  "Security",
916  "The 'random' function produces a sequence of values that "
917  "an adversary may be able to predict. Use 'arc4random' "
918  "instead", CELoc, CE->getCallee()->getSourceRange());
919 }
920 
921 //===----------------------------------------------------------------------===//
922 // Check: 'vfork' should not be used.
923 // POS33-C: Do not use vfork().
924 //===----------------------------------------------------------------------===//
925 
926 void WalkAST::checkCall_vfork(const CallExpr *CE, const FunctionDecl *FD) {
927  if (!filter.check_vfork)
928  return;
929 
930  // All calls to vfork() are insecure, issue a warning.
931  PathDiagnosticLocation CELoc =
932  PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
933  BR.EmitBasicReport(AC->getDecl(), filter.checkName_vfork,
934  "Potential insecure implementation-specific behavior in "
935  "call 'vfork'",
936  "Security",
937  "Call to function 'vfork' is insecure as it can lead to "
938  "denial of service situations in the parent process. "
939  "Replace calls to vfork with calls to the safer "
940  "'posix_spawn' function",
941  CELoc, CE->getCallee()->getSourceRange());
942 }
943 
944 //===----------------------------------------------------------------------===//
945 // Check: '-decodeValueOfObjCType:at:' should not be used.
946 // It is deprecated in favor of '-decodeValueOfObjCType:at:size:' due to
947 // likelihood of buffer overflows.
948 //===----------------------------------------------------------------------===//
949 
950 void WalkAST::checkMsg_decodeValueOfObjCType(const ObjCMessageExpr *ME) {
951  if (!filter.check_decodeValueOfObjCType)
952  return;
953 
954  // Check availability of the secure alternative:
955  // iOS 11+, macOS 10.13+, tvOS 11+, and watchOS 4.0+
956  // FIXME: We probably shouldn't register the check if it's not available.
957  const TargetInfo &TI = AC->getASTContext().getTargetInfo();
958  const llvm::Triple &T = TI.getTriple();
959  const VersionTuple &VT = TI.getPlatformMinVersion();
960  switch (T.getOS()) {
961  case llvm::Triple::IOS:
962  if (VT < VersionTuple(11, 0))
963  return;
964  break;
965  case llvm::Triple::MacOSX:
966  if (VT < VersionTuple(10, 13))
967  return;
968  break;
969  case llvm::Triple::WatchOS:
970  if (VT < VersionTuple(4, 0))
971  return;
972  break;
973  case llvm::Triple::TvOS:
974  if (VT < VersionTuple(11, 0))
975  return;
976  break;
977  default:
978  return;
979  }
980 
981  PathDiagnosticLocation MELoc =
982  PathDiagnosticLocation::createBegin(ME, BR.getSourceManager(), AC);
983  BR.EmitBasicReport(
984  AC->getDecl(), filter.checkName_decodeValueOfObjCType,
985  "Potential buffer overflow in '-decodeValueOfObjCType:at:'", "Security",
986  "Deprecated method '-decodeValueOfObjCType:at:' is insecure "
987  "as it can lead to potential buffer overflows. Use the safer "
988  "'-decodeValueOfObjCType:at:size:' method.",
989  MELoc, ME->getSourceRange());
990 }
991 
992 //===----------------------------------------------------------------------===//
993 // Check: Should check whether privileges are dropped successfully.
994 // Originally: <rdar://problem/6337132>
995 //===----------------------------------------------------------------------===//
996 
997 void WalkAST::checkUncheckedReturnValue(CallExpr *CE) {
998  if (!filter.check_UncheckedReturn)
999  return;
1000 
1001  const FunctionDecl *FD = CE->getDirectCallee();
1002  if (!FD)
1003  return;
1004 
1005  if (II_setid[0] == nullptr) {
1006  static const char * const identifiers[num_setids] = {
1007  "setuid", "setgid", "seteuid", "setegid",
1008  "setreuid", "setregid"
1009  };
1010 
1011  for (size_t i = 0; i < num_setids; i++)
1012  II_setid[i] = &BR.getContext().Idents.get(identifiers[i]);
1013  }
1014 
1015  const IdentifierInfo *id = FD->getIdentifier();
1016  size_t identifierid;
1017 
1018  for (identifierid = 0; identifierid < num_setids; identifierid++)
1019  if (id == II_setid[identifierid])
1020  break;
1021 
1022  if (identifierid >= num_setids)
1023  return;
1024 
1025  const FunctionProtoType *FTP = FD->getType()->getAs<FunctionProtoType>();
1026  if (!FTP)
1027  return;
1028 
1029  // Verify that the function takes one or two arguments (depending on
1030  // the function).
1031  if (FTP->getNumParams() != (identifierid < 4 ? 1 : 2))
1032  return;
1033 
1034  // The arguments must be integers.
1035  for (unsigned i = 0; i < FTP->getNumParams(); i++)
1037  return;
1038 
1039  // Issue a warning.
1040  SmallString<256> buf1;
1041  llvm::raw_svector_ostream os1(buf1);
1042  os1 << "Return value is not checked in call to '" << *FD << '\'';
1043 
1044  SmallString<256> buf2;
1045  llvm::raw_svector_ostream os2(buf2);
1046  os2 << "The return value from the call to '" << *FD
1047  << "' is not checked. If an error occurs in '" << *FD
1048  << "', the following code may execute with unexpected privileges";
1049 
1050  PathDiagnosticLocation CELoc =
1051  PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
1052  BR.EmitBasicReport(AC->getDecl(), filter.checkName_UncheckedReturn, os1.str(),
1053  "Security", os2.str(), CELoc,
1054  CE->getCallee()->getSourceRange());
1055 }
1056 
1057 //===----------------------------------------------------------------------===//
1058 // SecuritySyntaxChecker
1059 //===----------------------------------------------------------------------===//
1060 
1061 namespace {
1062 class SecuritySyntaxChecker : public Checker<check::ASTCodeBody> {
1063 public:
1064  ChecksFilter filter;
1065 
1066  void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
1067  BugReporter &BR) const {
1068  WalkAST walker(BR, mgr.getAnalysisDeclContext(D), filter);
1069  walker.Visit(D->getBody());
1070  }
1071 };
1072 }
1073 
1074 void ento::registerSecuritySyntaxChecker(CheckerManager &mgr) {
1075  mgr.registerChecker<SecuritySyntaxChecker>();
1076 }
1077 
1078 bool ento::shouldRegisterSecuritySyntaxChecker(const CheckerManager &mgr) {
1079  return true;
1080 }
1081 
1082 #define REGISTER_CHECKER(name) \
1083  void ento::register##name(CheckerManager &mgr) { \
1084  SecuritySyntaxChecker *checker = mgr.getChecker<SecuritySyntaxChecker>(); \
1085  checker->filter.check_##name = true; \
1086  checker->filter.checkName_##name = mgr.getCurrentCheckerName(); \
1087  } \
1088  \
1089  bool ento::shouldRegister##name(const CheckerManager &mgr) { return true; }
1090 
1091 REGISTER_CHECKER(bcmp)
1092 REGISTER_CHECKER(bcopy)
1093 REGISTER_CHECKER(bzero)
1094 REGISTER_CHECKER(gets)
1095 REGISTER_CHECKER(getpw)
1096 REGISTER_CHECKER(mkstemp)
1097 REGISTER_CHECKER(mktemp)
1098 REGISTER_CHECKER(strcpy)
1099 REGISTER_CHECKER(rand)
1100 REGISTER_CHECKER(vfork)
1101 REGISTER_CHECKER(FloatLoopCounter)
1102 REGISTER_CHECKER(UncheckedReturn)
1103 REGISTER_CHECKER(DeprecatedOrUnsafeBufferHandling)
1104 REGISTER_CHECKER(decodeValueOfObjCType)
clang::StmtVisitor
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:183
isArc4RandomAvailable
static bool isArc4RandomAvailable(const ASTContext &Ctx)
Definition: CheckSecuritySyntaxOnly.cpp:27
clang::ObjCMessageExpr::getSelector
Selector getSelector() const
Definition: ExprObjC.cpp:293
AnalysisDeclContext.h
llvm::SmallVector
Definition: LLVM.h:38
clang::APValue::getInt
APSInt & getInt()
Definition: APValue.h:415
clang::NamedDecl
This represents a decl that may have a name.
Definition: Decl.h:249
TargetInfo.h
clang::MultiVersionKind::Target
@ Target
clang::Stmt::getSourceRange
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:324
clang::AnalysisDeclContext
AnalysisDeclContext contains the context data for the function, method or block under analysis.
Definition: AnalysisDeclContext.h:72
clang::TargetInfo
Exposes information about the current target.
Definition: TargetInfo.h:189
clang::Type::isRealFloatingType
bool isRealFloatingType() const
Floating point categories.
Definition: Type.cpp:2120
clang::UnaryOperator
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition: Expr.h:2157
clang::QualType::getAsString
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
Definition: Type.h:1015
clang::Expr::IgnoreImpCasts
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
Definition: Expr.cpp:2899
clang::Expr::EvalResult::Val
APValue Val
Val - This is the value the expression can be folded to.
Definition: Expr.h:608
APSInt
llvm::APSInt APSInt
Definition: ByteCodeEmitter.cpp:19
clang::StructuralEquivalenceKind::Default
@ Default
U
clang::CallExpr::getCallee
Expr * getCallee()
Definition: Expr.h:2945
clang::ast_matchers::expr
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
Definition: ASTMatchersInternal.cpp:889
clang::CallExpr::getDirectCallee
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
Definition: Expr.h:2965
BuiltinCheckerRegistration.h
clang::CompoundStmt
CompoundStmt - This represents a group of statements like { stmt stmt }.
Definition: Stmt.h:1399
clang::BinaryOperator
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:3803
BugReporter.h
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:212
clang::BinaryOperator::isRelationalOp
static bool isRelationalOp(Opcode Opc)
Definition: Expr.h:3896
clang::Type::getAs
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:7161
clang::CallExpr::getArg
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Definition: Expr.h:2986
clang::ForStmt
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Definition: Stmt.h:2534
clang::FunctionProtoType::getParamType
QualType getParamType(unsigned i) const
Definition: Type.h:4097
clang::TargetInfo::getPlatformMinVersion
VersionTuple getPlatformMinVersion() const
Retrieve the minimum desired version of the platform, to which the program should be compiled.
Definition: TargetInfo.h:1439
clang::BinaryOperator::isEqualityOp
static bool isEqualityOp(Opcode Opc)
Definition: Expr.h:3899
clang::DeclRefExpr::getDecl
ValueDecl * getDecl()
Definition: Expr.h:1289
llvm::SmallString
Definition: LLVM.h:37
clang::Expr::EvalResult
EvalResult is a struct with detailed info about an evaluated expression.
Definition: Expr.h:606
clang::VarDecl
Represents a variable declaration or definition.
Definition: Decl.h:876
clang::StringLiteral
StringLiteral - This represents a string literal expression, e.g.
Definition: Expr.h:1761
clang::Expr::IgnoreParenLValueCasts
Expr * IgnoreParenLValueCasts() LLVM_READONLY
Skip past any parentheses and lvalue casts which might surround this expression until reaching a fixe...
Definition: Expr.cpp:2936
x
IRgen optimization opportunities The common pattern of short x
Definition: README.txt:7
clang::ObjCMessageExpr
An expression that sends a message to the given Objective-C object or class.
Definition: ExprObjC.h:940
clang::QualType::getUnqualifiedType
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition: Type.h:6504
clang::Expr::IgnoreParenCasts
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
Definition: Expr.cpp:2924
clang::TargetInfo::getTriple
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Definition: TargetInfo.h:1130
clang::NamedDecl::getIdentifier
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition: Decl.h:270
clang::BinaryOperator::getLHS
Expr * getLHS() const
Definition: Expr.h:3852
clang::FunctionProtoType
Represents a prototype with parameter type info, e.g.
Definition: Type.h:3885
clang::CallExpr::getNumArgs
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
Definition: Expr.h:2973
clang::Decl
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:89
clang::Expr::IgnoreParenImpCasts
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Definition: Expr.cpp:2919
StmtVisitor.h
clang::FunctionProtoType::getNumParams
unsigned getNumParams() const
Definition: Type.h:4095
clang::Selector::getAsString
std::string getAsString() const
Derive the full selector name (e.g.
Definition: IdentifierTable.cpp:519
clang::IdentifierInfo
One of these records is kept for each identifier that is lexed.
Definition: IdentifierTable.h:84
clang::Expr::EvaluateAsInt
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,...
Definition: ExprConstant.cpp:14735
clang::ASTContext::getTargetInfo
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:747
clang::StringLiteral::getCharByteWidth
unsigned getCharByteWidth() const
Definition: Expr.h:1874
clang::Decl::getBody
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:1010
Checker.h
clang::PointerType
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:2640
clang::IdentifierInfo::getName
StringRef getName() const
Return the actual identifier string.
Definition: IdentifierTable.h:195
getIncrementedVar
static const DeclRefExpr * getIncrementedVar(const Expr *expr, const VarDecl *x, const VarDecl *y)
Definition: CheckSecuritySyntaxOnly.cpp:229
clang
Definition: CalledOnceCheck.h:17
clang::Type::isIntegralOrUnscopedEnumerationType
bool isIntegralOrUnscopedEnumerationType() const
Determine whether this type is an integral or unscoped enumeration type.
Definition: Type.cpp:1938
REGISTER_CHECKER
#define REGISTER_CHECKER(name)
Definition: CheckSecuritySyntaxOnly.cpp:1082
clang::Stmt
Stmt - This represents one statement.
Definition: Stmt.h:69
clang::BinaryOperator::getRHS
Expr * getRHS() const
Definition: Expr.h:3854
clang::Expr::getType
QualType getType() const
Definition: Expr.h:141
clang::ento::PathDiagnosticLocation::createBegin
static PathDiagnosticLocation createBegin(const Decl *D, const SourceManager &SM)
Create a location for the beginning of the declaration.
Definition: PathDiagnostic.cpp:580
unsigned
clang::PointerType::getPointeeType
QualType getPointeeType() const
Definition: Type.h:2650
clang::ValueDecl::getType
QualType getType() const
Definition: Decl.h:687
clang::Expr
This represents one expression.
Definition: Expr.h:109
AnalysisManager.h
clang::DeclRefExpr
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1217
clang::FunctionDecl
Represents a function declaration or definition.
Definition: Decl.h:1856
clang::CallExpr
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2795
clang::StringLiteral::getString
StringRef getString() const
Definition: Expr.h:1844
clang::NamedDecl::getName
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:276