Home | History | Annotate | Download | only in Core
      1 //== CheckerContext.cpp - Context info for path-sensitive checkers-----------=//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 //  This file defines CheckerContext that provides contextual info for
     11 //  path-sensitive checkers.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
     16 #include "clang/Basic/Builtins.h"
     17 #include "clang/Lex/Lexer.h"
     18 
     19 using namespace clang;
     20 using namespace ento;
     21 
     22 const FunctionDecl *CheckerContext::getCalleeDecl(const CallExpr *CE) const {
     23   ProgramStateRef State = getState();
     24   const Expr *Callee = CE->getCallee();
     25   SVal L = State->getSVal(Callee, Pred->getLocationContext());
     26   return L.getAsFunctionDecl();
     27 }
     28 
     29 StringRef CheckerContext::getCalleeName(const FunctionDecl *FunDecl) const {
     30   if (!FunDecl)
     31     return StringRef();
     32   IdentifierInfo *funI = FunDecl->getIdentifier();
     33   if (!funI)
     34     return StringRef();
     35   return funI->getName();
     36 }
     37 
     38 
     39 bool CheckerContext::isCLibraryFunction(const FunctionDecl *FD,
     40                                         StringRef Name) {
     41   // To avoid false positives (Ex: finding user defined functions with
     42   // similar names), only perform fuzzy name matching when it's a builtin.
     43   // Using a string compare is slow, we might want to switch on BuiltinID here.
     44   unsigned BId = FD->getBuiltinID();
     45   if (BId != 0) {
     46     if (Name.empty())
     47       return true;
     48     StringRef BName = FD->getASTContext().BuiltinInfo.GetName(BId);
     49     if (BName.find(Name) != StringRef::npos)
     50       return true;
     51   }
     52 
     53   const IdentifierInfo *II = FD->getIdentifier();
     54   // If this is a special C++ name without IdentifierInfo, it can't be a
     55   // C library function.
     56   if (!II)
     57     return false;
     58 
     59   // Look through 'extern "C"' and anything similar invented in the future.
     60   const DeclContext *DC = FD->getDeclContext();
     61   while (DC->isTransparentContext())
     62     DC = DC->getParent();
     63 
     64   // If this function is in a namespace, it is not a C library function.
     65   if (!DC->isTranslationUnit())
     66     return false;
     67 
     68   // If this function is not externally visible, it is not a C library function.
     69   // Note that we make an exception for inline functions, which may be
     70   // declared in header files without external linkage.
     71   if (!FD->isInlined() && !FD->isExternallyVisible())
     72     return false;
     73 
     74   if (Name.empty())
     75     return true;
     76 
     77   StringRef FName = II->getName();
     78   if (FName.equals(Name))
     79     return true;
     80 
     81   if (FName.startswith("__inline") && (FName.find(Name) != StringRef::npos))
     82     return true;
     83 
     84   if (FName.startswith("__") && FName.endswith("_chk") &&
     85       FName.find(Name) != StringRef::npos)
     86     return true;
     87 
     88   return false;
     89 }
     90 
     91 StringRef CheckerContext::getMacroNameOrSpelling(SourceLocation &Loc) {
     92   if (Loc.isMacroID())
     93     return Lexer::getImmediateMacroName(Loc, getSourceManager(),
     94                                              getLangOpts());
     95   SmallVector<char, 16> buf;
     96   return Lexer::getSpelling(Loc, buf, getSourceManager(), getLangOpts());
     97 }
     98 
     99