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