18687397a0f5e4c31632959d907f9d9b38d793b1cAnna Zaks//== CheckerContext.cpp - Context info for path-sensitive checkers-----------=//
28687397a0f5e4c31632959d907f9d9b38d793b1cAnna Zaks//
38687397a0f5e4c31632959d907f9d9b38d793b1cAnna Zaks//                     The LLVM Compiler Infrastructure
48687397a0f5e4c31632959d907f9d9b38d793b1cAnna Zaks//
58687397a0f5e4c31632959d907f9d9b38d793b1cAnna Zaks// This file is distributed under the University of Illinois Open Source
68687397a0f5e4c31632959d907f9d9b38d793b1cAnna Zaks// License. See LICENSE.TXT for details.
78687397a0f5e4c31632959d907f9d9b38d793b1cAnna Zaks//
88687397a0f5e4c31632959d907f9d9b38d793b1cAnna Zaks//===----------------------------------------------------------------------===//
98687397a0f5e4c31632959d907f9d9b38d793b1cAnna Zaks//
108687397a0f5e4c31632959d907f9d9b38d793b1cAnna Zaks//  This file defines CheckerContext that provides contextual info for
118687397a0f5e4c31632959d907f9d9b38d793b1cAnna Zaks//  path-sensitive checkers.
128687397a0f5e4c31632959d907f9d9b38d793b1cAnna Zaks//
138687397a0f5e4c31632959d907f9d9b38d793b1cAnna Zaks//===----------------------------------------------------------------------===//
148687397a0f5e4c31632959d907f9d9b38d793b1cAnna Zaks
158687397a0f5e4c31632959d907f9d9b38d793b1cAnna Zaks#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
169b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks#include "clang/Basic/Builtins.h"
17461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks#include "clang/Lex/Lexer.h"
189b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks
198687397a0f5e4c31632959d907f9d9b38d793b1cAnna Zaksusing namespace clang;
208687397a0f5e4c31632959d907f9d9b38d793b1cAnna Zaksusing namespace ento;
218687397a0f5e4c31632959d907f9d9b38d793b1cAnna Zaks
22b805c8ff133ef0c62df032fa711d6b13c5afd7f4Anna Zaksconst FunctionDecl *CheckerContext::getCalleeDecl(const CallExpr *CE) const {
238bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek  ProgramStateRef State = getState();
248687397a0f5e4c31632959d907f9d9b38d793b1cAnna Zaks  const Expr *Callee = CE->getCallee();
255eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  SVal L = State->getSVal(Callee, Pred->getLocationContext());
26b805c8ff133ef0c62df032fa711d6b13c5afd7f4Anna Zaks  return L.getAsFunctionDecl();
27b805c8ff133ef0c62df032fa711d6b13c5afd7f4Anna Zaks}
288687397a0f5e4c31632959d907f9d9b38d793b1cAnna Zaks
299b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna ZaksStringRef CheckerContext::getCalleeName(const FunctionDecl *FunDecl) const {
309b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  if (!FunDecl)
318687397a0f5e4c31632959d907f9d9b38d793b1cAnna Zaks    return StringRef();
329b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  IdentifierInfo *funI = FunDecl->getIdentifier();
338687397a0f5e4c31632959d907f9d9b38d793b1cAnna Zaks  if (!funI)
348687397a0f5e4c31632959d907f9d9b38d793b1cAnna Zaks    return StringRef();
358687397a0f5e4c31632959d907f9d9b38d793b1cAnna Zaks  return funI->getName();
368687397a0f5e4c31632959d907f9d9b38d793b1cAnna Zaks}
379b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks
389b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks
399b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaksbool CheckerContext::isCLibraryFunction(const FunctionDecl *FD,
40e00575f12cf280621ef0ed4d69e909bdfc9fef62Anna Zaks                                        StringRef Name) {
419b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  // To avoid false positives (Ex: finding user defined functions with
429b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  // similar names), only perform fuzzy name matching when it's a builtin.
439b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  // Using a string compare is slow, we might want to switch on BuiltinID here.
449b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  unsigned BId = FD->getBuiltinID();
459b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  if (BId != 0) {
462f3017f9cbd3774f690c979410bfec38423d03afJordan Rose    if (Name.empty())
472f3017f9cbd3774f690c979410bfec38423d03afJordan Rose      return true;
48d624607d4196e4b37d235daa14699bcb3c1012a6Jordan Rose    StringRef BName = FD->getASTContext().BuiltinInfo.GetName(BId);
49e00575f12cf280621ef0ed4d69e909bdfc9fef62Anna Zaks    if (BName.find(Name) != StringRef::npos)
509b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks      return true;
519b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  }
529b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks
5384aac9acc7a73360a7553c46f8da72773adbdd17Anna Zaks  const IdentifierInfo *II = FD->getIdentifier();
5484aac9acc7a73360a7553c46f8da72773adbdd17Anna Zaks  // If this is a special C++ name without IdentifierInfo, it can't be a
5584aac9acc7a73360a7553c46f8da72773adbdd17Anna Zaks  // C library function.
5684aac9acc7a73360a7553c46f8da72773adbdd17Anna Zaks  if (!II)
5784aac9acc7a73360a7553c46f8da72773adbdd17Anna Zaks    return false;
5884aac9acc7a73360a7553c46f8da72773adbdd17Anna Zaks
59d624607d4196e4b37d235daa14699bcb3c1012a6Jordan Rose  // Look through 'extern "C"' and anything similar invented in the future.
60d624607d4196e4b37d235daa14699bcb3c1012a6Jordan Rose  const DeclContext *DC = FD->getDeclContext();
61d624607d4196e4b37d235daa14699bcb3c1012a6Jordan Rose  while (DC->isTransparentContext())
62d624607d4196e4b37d235daa14699bcb3c1012a6Jordan Rose    DC = DC->getParent();
63d624607d4196e4b37d235daa14699bcb3c1012a6Jordan Rose
64d624607d4196e4b37d235daa14699bcb3c1012a6Jordan Rose  // If this function is in a namespace, it is not a C library function.
65d624607d4196e4b37d235daa14699bcb3c1012a6Jordan Rose  if (!DC->isTranslationUnit())
66d624607d4196e4b37d235daa14699bcb3c1012a6Jordan Rose    return false;
67d624607d4196e4b37d235daa14699bcb3c1012a6Jordan Rose
68d624607d4196e4b37d235daa14699bcb3c1012a6Jordan Rose  // If this function is not externally visible, it is not a C library function.
692f3017f9cbd3774f690c979410bfec38423d03afJordan Rose  // Note that we make an exception for inline functions, which may be
702f3017f9cbd3774f690c979410bfec38423d03afJordan Rose  // declared in header files without external linkage.
71181e3ecc0907ae0103586a9f4db52241995a8267Rafael Espindola  if (!FD->isInlined() && !FD->isExternallyVisible())
72d624607d4196e4b37d235daa14699bcb3c1012a6Jordan Rose    return false;
73d624607d4196e4b37d235daa14699bcb3c1012a6Jordan Rose
742f3017f9cbd3774f690c979410bfec38423d03afJordan Rose  if (Name.empty())
752f3017f9cbd3774f690c979410bfec38423d03afJordan Rose    return true;
762f3017f9cbd3774f690c979410bfec38423d03afJordan Rose
7784aac9acc7a73360a7553c46f8da72773adbdd17Anna Zaks  StringRef FName = II->getName();
78998e2754281b19bb1db19299ae16c2fd5947bcc0Anna Zaks  if (FName.equals(Name))
79998e2754281b19bb1db19299ae16c2fd5947bcc0Anna Zaks    return true;
80998e2754281b19bb1db19299ae16c2fd5947bcc0Anna Zaks
81998e2754281b19bb1db19299ae16c2fd5947bcc0Anna Zaks  if (FName.startswith("__inline") && (FName.find(Name) != StringRef::npos))
82998e2754281b19bb1db19299ae16c2fd5947bcc0Anna Zaks    return true;
83e00575f12cf280621ef0ed4d69e909bdfc9fef62Anna Zaks
84998e2754281b19bb1db19299ae16c2fd5947bcc0Anna Zaks  if (FName.startswith("__") && FName.endswith("_chk") &&
85998e2754281b19bb1db19299ae16c2fd5947bcc0Anna Zaks      FName.find(Name) != StringRef::npos)
869b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks    return true;
879b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks
889b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  return false;
899b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks}
90461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks
91461af1e502c9bd88330bbf17d449a7593fc0d624Anna ZaksStringRef CheckerContext::getMacroNameOrSpelling(SourceLocation &Loc) {
923026348bd4c13a0f83b59839f64065e0fcbea253David Blaikie  if (Loc.isMacroID())
93461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks    return Lexer::getImmediateMacroName(Loc, getSourceManager(),
944e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie                                             getLangOpts());
953026348bd4c13a0f83b59839f64065e0fcbea253David Blaikie  SmallVector<char, 16> buf;
964e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  return Lexer::getSpelling(Loc, buf, getSourceManager(), getLangOpts());
97461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks}
98461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks
99