BuiltinFunctionChecker.cpp 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. //=== BuiltinFunctionChecker.cpp --------------------------------*- C++ -*-===//
  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 checker evaluates clang builtin functions.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "InternalChecks.h"
  14. #include "clang/StaticAnalyzer/PathSensitive/Checker.h"
  15. #include "clang/Basic/Builtins.h"
  16. using namespace clang;
  17. using namespace ento;
  18. namespace {
  19. class BuiltinFunctionChecker : public Checker {
  20. public:
  21. static void *getTag() { static int tag = 0; return &tag; }
  22. virtual bool evalCallExpr(CheckerContext &C, const CallExpr *CE);
  23. };
  24. }
  25. void ento::RegisterBuiltinFunctionChecker(ExprEngine &Eng) {
  26. Eng.registerCheck(new BuiltinFunctionChecker());
  27. }
  28. bool BuiltinFunctionChecker::evalCallExpr(CheckerContext &C,const CallExpr *CE){
  29. const GRState *state = C.getState();
  30. const Expr *Callee = CE->getCallee();
  31. SVal L = state->getSVal(Callee);
  32. const FunctionDecl *FD = L.getAsFunctionDecl();
  33. if (!FD)
  34. return false;
  35. unsigned id = FD->getBuiltinID();
  36. if (!id)
  37. return false;
  38. switch (id) {
  39. case Builtin::BI__builtin_expect: {
  40. // For __builtin_expect, just return the value of the subexpression.
  41. assert (CE->arg_begin() != CE->arg_end());
  42. SVal X = state->getSVal(*(CE->arg_begin()));
  43. C.generateNode(state->BindExpr(CE, X));
  44. return true;
  45. }
  46. case Builtin::BI__builtin_alloca: {
  47. // FIXME: Refactor into StoreManager itself?
  48. MemRegionManager& RM = C.getStoreManager().getRegionManager();
  49. const AllocaRegion* R =
  50. RM.getAllocaRegion(CE, C.getNodeBuilder().getCurrentBlockCount(),
  51. C.getPredecessor()->getLocationContext());
  52. // Set the extent of the region in bytes. This enables us to use the
  53. // SVal of the argument directly. If we save the extent in bits, we
  54. // cannot represent values like symbol*8.
  55. DefinedOrUnknownSVal Size =
  56. cast<DefinedOrUnknownSVal>(state->getSVal(*(CE->arg_begin())));
  57. SValBuilder& svalBuilder = C.getSValBuilder();
  58. DefinedOrUnknownSVal Extent = R->getExtent(svalBuilder);
  59. DefinedOrUnknownSVal extentMatchesSizeArg =
  60. svalBuilder.evalEQ(state, Extent, Size);
  61. state = state->assume(extentMatchesSizeArg, true);
  62. C.generateNode(state->BindExpr(CE, loc::MemRegionVal(R)));
  63. return true;
  64. }
  65. }
  66. return false;
  67. }