CheckerContext.cpp revision 263508
1249259Sdim//== CheckerContext.cpp - Context info for path-sensitive checkers-----------=// 2249259Sdim// 3249259Sdim// The LLVM Compiler Infrastructure 4249259Sdim// 5249259Sdim// This file is distributed under the University of Illinois Open Source 6249259Sdim// License. See LICENSE.TXT for details. 7249259Sdim// 8249259Sdim//===----------------------------------------------------------------------===// 9249259Sdim// 10249259Sdim// This file defines CheckerContext that provides contextual info for 11249259Sdim// path-sensitive checkers. 12249259Sdim// 13249259Sdim//===----------------------------------------------------------------------===// 14249259Sdim 15249259Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" 16249259Sdim#include "clang/Basic/Builtins.h" 17249259Sdim#include "clang/Lex/Lexer.h" 18249259Sdim 19249259Sdimusing namespace clang; 20249259Sdimusing namespace ento; 21249259Sdim 22249259Sdimconst FunctionDecl *CheckerContext::getCalleeDecl(const CallExpr *CE) const { 23249259Sdim ProgramStateRef State = getState(); 24249259Sdim const Expr *Callee = CE->getCallee(); 25249259Sdim SVal L = State->getSVal(Callee, Pred->getLocationContext()); 26249259Sdim return L.getAsFunctionDecl(); 27249259Sdim} 28249259Sdim 29249259SdimStringRef CheckerContext::getCalleeName(const FunctionDecl *FunDecl) const { 30249259Sdim if (!FunDecl) 31249259Sdim return StringRef(); 32249259Sdim IdentifierInfo *funI = FunDecl->getIdentifier(); 33249259Sdim if (!funI) 34249259Sdim return StringRef(); 35249259Sdim return funI->getName(); 36249259Sdim} 37249259Sdim 38249259Sdim 39249259Sdimbool CheckerContext::isCLibraryFunction(const FunctionDecl *FD, 40249259Sdim StringRef Name) { 41249259Sdim // To avoid false positives (Ex: finding user defined functions with 42249259Sdim // similar names), only perform fuzzy name matching when it's a builtin. 43249259Sdim // Using a string compare is slow, we might want to switch on BuiltinID here. 44249259Sdim unsigned BId = FD->getBuiltinID(); 45249259Sdim if (BId != 0) { 46249259Sdim if (Name.empty()) 47249259Sdim return true; 48249259Sdim StringRef BName = FD->getASTContext().BuiltinInfo.GetName(BId); 49249259Sdim if (BName.find(Name) != StringRef::npos) 50249259Sdim return true; 51249259Sdim } 52249259Sdim 53249259Sdim const IdentifierInfo *II = FD->getIdentifier(); 54249259Sdim // If this is a special C++ name without IdentifierInfo, it can't be a 55249259Sdim // C library function. 56249259Sdim if (!II) 57249259Sdim return false; 58249259Sdim 59249259Sdim // Look through 'extern "C"' and anything similar invented in the future. 60249259Sdim const DeclContext *DC = FD->getDeclContext(); 61249259Sdim while (DC->isTransparentContext()) 62249259Sdim DC = DC->getParent(); 63249259Sdim 64249259Sdim // If this function is in a namespace, it is not a C library function. 65249259Sdim if (!DC->isTranslationUnit()) 66249259Sdim return false; 67249259Sdim 68249259Sdim // If this function is not externally visible, it is not a C library function. 69249259Sdim // Note that we make an exception for inline functions, which may be 70249259Sdim // declared in header files without external linkage. 71249259Sdim if (!FD->isInlined() && !FD->isExternallyVisible()) 72249259Sdim return false; 73249259Sdim 74249259Sdim if (Name.empty()) 75249259Sdim return true; 76249259Sdim 77249259Sdim StringRef FName = II->getName(); 78249259Sdim if (FName.equals(Name)) 79249259Sdim return true; 80249259Sdim 81249259Sdim if (FName.startswith("__inline") && (FName.find(Name) != StringRef::npos)) 82249259Sdim return true; 83249259Sdim 84249259Sdim if (FName.startswith("__") && FName.endswith("_chk") && 85249259Sdim FName.find(Name) != StringRef::npos) 86249259Sdim return true; 87249259Sdim 88249259Sdim return false; 89249259Sdim} 90249259Sdim 91249259SdimStringRef CheckerContext::getMacroNameOrSpelling(SourceLocation &Loc) { 92249259Sdim if (Loc.isMacroID()) 93249259Sdim return Lexer::getImmediateMacroName(Loc, getSourceManager(), 94249259Sdim getLangOpts()); 95249259Sdim SmallVector<char, 16> buf; 96249259Sdim return Lexer::getSpelling(Loc, buf, getSourceManager(), getLangOpts()); 97249259Sdim} 98249259Sdim 99249259Sdim