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 StringRef CheckerContext::getDeclDescription(const Decl *D) {
     39   if (isa<ObjCMethodDecl>(D) || isa<CXXMethodDecl>(D))
     40     return "method";
     41   if (isa<BlockDecl>(D))
     42     return "anonymous block";
     43   return "function";
     44 }
     45 
     46 bool CheckerContext::isCLibraryFunction(const FunctionDecl *FD,
     47                                         StringRef Name) {
     48   // To avoid false positives (Ex: finding user defined functions with
     49   // similar names), only perform fuzzy name matching when it's a builtin.
     50   // Using a string compare is slow, we might want to switch on BuiltinID here.
     51   unsigned BId = FD->getBuiltinID();
     52   if (BId != 0) {
     53     if (Name.empty())
     54       return true;
     55     StringRef BName = FD->getASTContext().BuiltinInfo.getName(BId);
     56     if (BName.find(Name) != StringRef::npos)
     57       return true;
     58   }
     59 
     60   const IdentifierInfo *II = FD->getIdentifier();
     61   // If this is a special C++ name without IdentifierInfo, it can't be a
     62   // C library function.
     63   if (!II)
     64     return false;
     65 
     66   // Look through 'extern "C"' and anything similar invented in the future.
     67   // If this function is not in TU directly, it is not a C library function.
     68   if (!FD->getDeclContext()->getRedeclContext()->isTranslationUnit())
     69     return false;
     70 
     71   // If this function is not externally visible, it is not a C library function.
     72   // Note that we make an exception for inline functions, which may be
     73   // declared in header files without external linkage.
     74   if (!FD->isInlined() && !FD->isExternallyVisible())
     75     return false;
     76 
     77   if (Name.empty())
     78     return true;
     79 
     80   StringRef FName = II->getName();
     81   if (FName.equals(Name))
     82     return true;
     83 
     84   if (FName.startswith("__inline") && (FName.find(Name) != StringRef::npos))
     85     return true;
     86 
     87   if (FName.startswith("__") && FName.endswith("_chk") &&
     88       FName.find(Name) != StringRef::npos)
     89     return true;
     90 
     91   return false;
     92 }
     93 
     94 StringRef CheckerContext::getMacroNameOrSpelling(SourceLocation &Loc) {
     95   if (Loc.isMacroID())
     96     return Lexer::getImmediateMacroName(Loc, getSourceManager(),
     97                                              getLangOpts());
     98   SmallVector<char, 16> buf;
     99   return Lexer::getSpelling(Loc, buf, getSourceManager(), getLangOpts());
    100 }
    101 
    102