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 19using namespace clang; 20using namespace ento; 21 22const 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 29StringRef 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 38StringRef 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 46bool 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 94StringRef 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