ASTUtils.h 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. //=======- ASTUtis.h ---------------------------------------------*- C++ -*-==//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #ifndef LLVM_CLANG_ANALYZER_WEBKIT_ASTUTILS_H
  9. #define LLVM_CLANG_ANALYZER_WEBKIT_ASTUTILS_H
  10. #include "clang/AST/Decl.h"
  11. #include "llvm/ADT/APInt.h"
  12. #include "llvm/Support/Casting.h"
  13. #include <string>
  14. #include <utility>
  15. namespace clang {
  16. class Expr;
  17. /// This function de-facto defines a set of transformations that we consider
  18. /// safe (in heuristical sense). These transformation if passed a safe value as
  19. /// an input should provide a safe value (or an object that provides safe
  20. /// values).
  21. ///
  22. /// For more context see Static Analyzer checkers documentation - specifically
  23. /// webkit.UncountedCallArgsChecker checker. Allowed list of transformations:
  24. /// - constructors of ref-counted types (including factory methods)
  25. /// - getters of ref-counted types
  26. /// - member overloaded operators
  27. /// - casts
  28. /// - unary operators like ``&`` or ``*``
  29. ///
  30. /// If passed expression is of type uncounted pointer/reference we try to find
  31. /// the "origin" of the pointer value.
  32. /// Origin can be for example a local variable, nullptr, constant or
  33. /// this-pointer.
  34. ///
  35. /// Certain subexpression nodes represent transformations that don't affect
  36. /// where the memory address originates from. We try to traverse such
  37. /// subexpressions to get to the relevant child nodes. Whenever we encounter a
  38. /// subexpression that either can't be ignored, we don't model its semantics or
  39. /// that has multiple children we stop.
  40. ///
  41. /// \p E is an expression of uncounted pointer/reference type.
  42. /// If \p StopAtFirstRefCountedObj is true and we encounter a subexpression that
  43. /// represents ref-counted object during the traversal we return relevant
  44. /// sub-expression and true.
  45. ///
  46. /// \returns subexpression that we traversed to and if \p
  47. /// StopAtFirstRefCountedObj is true we also return whether we stopped early.
  48. std::pair<const clang::Expr *, bool>
  49. tryToFindPtrOrigin(const clang::Expr *E, bool StopAtFirstRefCountedObj);
  50. /// For \p E referring to a ref-countable/-counted pointer/reference we return
  51. /// whether it's a safe call argument. Examples: function parameter or
  52. /// this-pointer. The logic relies on the set of recursive rules we enforce for
  53. /// WebKit codebase.
  54. ///
  55. /// \returns Whether \p E is a safe call arugment.
  56. bool isASafeCallArg(const clang::Expr *E);
  57. /// \returns name of AST node or empty string.
  58. template <typename T> std::string safeGetName(const T *ASTNode) {
  59. const auto *const ND = llvm::dyn_cast_or_null<clang::NamedDecl>(ASTNode);
  60. if (!ND)
  61. return "";
  62. // In case F is for example "operator|" the getName() method below would
  63. // assert.
  64. if (!ND->getDeclName().isIdentifier())
  65. return "";
  66. return ND->getName().str();
  67. }
  68. } // namespace clang
  69. #endif