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   return isCLibraryFunction(FD, Name, getASTContext());
     42 }
     43 
     44 bool CheckerContext::isCLibraryFunction(const FunctionDecl *FD,
     45                                         StringRef Name, ASTContext &Context) {
     46   // To avoid false positives (Ex: finding user defined functions with
     47   // similar names), only perform fuzzy name matching when it's a builtin.
     48   // Using a string compare is slow, we might want to switch on BuiltinID here.
     49   unsigned BId = FD->getBuiltinID();
     50   if (BId != 0) {
     51     StringRef BName = Context.BuiltinInfo.GetName(BId);
     52     if (BName.find(Name) != StringRef::npos)
     53       return true;
     54   }
     55 
     56   const IdentifierInfo *II = FD->getIdentifier();
     57   // If this is a special C++ name without IdentifierInfo, it can't be a
     58   // C library function.
     59   if (!II)
     60     return false;
     61 
     62   StringRef FName = II->getName();
     63   if (FName.equals(Name))
     64     return true;
     65 
     66   if (FName.startswith("__inline") && (FName.find(Name) != StringRef::npos))
     67     return true;
     68 
     69   if (FName.startswith("__") && FName.endswith("_chk") &&
     70       FName.find(Name) != StringRef::npos)
     71     return true;
     72 
     73   return false;
     74 }
     75 
     76 StringRef CheckerContext::getMacroNameOrSpelling(SourceLocation &Loc) {
     77   if (Loc.isMacroID())
     78     return Lexer::getImmediateMacroName(Loc, getSourceManager(),
     79                                              getLangOpts());
     80   SmallVector<char, 16> buf;
     81   return Lexer::getSpelling(Loc, buf, getSourceManager(), getLangOpts());
     82 }
     83 
     84