/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.h
Line | Count | Source (jump to first uncovered line) |
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 | | |
9 | | #ifndef LLVM_CLANG_ANALYZER_WEBKIT_ASTUTILS_H |
10 | | #define LLVM_CLANG_ANALYZER_WEBKIT_ASTUTILS_H |
11 | | |
12 | | #include "clang/AST/Decl.h" |
13 | | #include "llvm/ADT/APInt.h" |
14 | | #include "llvm/Support/Casting.h" |
15 | | |
16 | | #include <string> |
17 | | #include <utility> |
18 | | |
19 | | namespace clang { |
20 | | class Expr; |
21 | | |
22 | | /// This function de-facto defines a set of transformations that we consider |
23 | | /// safe (in heuristical sense). These transformation if passed a safe value as |
24 | | /// an input should provide a safe value (or an object that provides safe |
25 | | /// values). |
26 | | /// |
27 | | /// For more context see Static Analyzer checkers documentation - specifically |
28 | | /// webkit.UncountedCallArgsChecker checker. Allowed list of transformations: |
29 | | /// - constructors of ref-counted types (including factory methods) |
30 | | /// - getters of ref-counted types |
31 | | /// - member overloaded operators |
32 | | /// - casts |
33 | | /// - unary operators like ``&`` or ``*`` |
34 | | /// |
35 | | /// If passed expression is of type uncounted pointer/reference we try to find |
36 | | /// the "origin" of the pointer value. |
37 | | /// Origin can be for example a local variable, nullptr, constant or |
38 | | /// this-pointer. |
39 | | /// |
40 | | /// Certain subexpression nodes represent transformations that don't affect |
41 | | /// where the memory address originates from. We try to traverse such |
42 | | /// subexpressions to get to the relevant child nodes. Whenever we encounter a |
43 | | /// subexpression that either can't be ignored, we don't model its semantics or |
44 | | /// that has multiple children we stop. |
45 | | /// |
46 | | /// \p E is an expression of uncounted pointer/reference type. |
47 | | /// If \p StopAtFirstRefCountedObj is true and we encounter a subexpression that |
48 | | /// represents ref-counted object during the traversal we return relevant |
49 | | /// sub-expression and true. |
50 | | /// |
51 | | /// \returns subexpression that we traversed to and if \p |
52 | | /// StopAtFirstRefCountedObj is true we also return whether we stopped early. |
53 | | std::pair<const clang::Expr *, bool> |
54 | | tryToFindPtrOrigin(const clang::Expr *E, bool StopAtFirstRefCountedObj); |
55 | | |
56 | | /// For \p E referring to a ref-countable/-counted pointer/reference we return |
57 | | /// whether it's a safe call argument. Examples: function parameter or |
58 | | /// this-pointer. The logic relies on the set of recursive rules we enforce for |
59 | | /// WebKit codebase. |
60 | | /// |
61 | | /// \returns Whether \p E is a safe call arugment. |
62 | | bool isASafeCallArg(const clang::Expr *E); |
63 | | |
64 | | /// \returns name of AST node or empty string. |
65 | 413 | template <typename T> std::string safeGetName(const T *ASTNode) { |
66 | 413 | const auto *const ND = llvm::dyn_cast_or_null<clang::NamedDecl>(ASTNode); |
67 | 413 | if (!ND) |
68 | 0 | return ""; |
69 | | |
70 | | // In case F is for example "operator|" the getName() method below would |
71 | | // assert. |
72 | 413 | if (!ND->getDeclName().isIdentifier()) |
73 | 26 | return ""; |
74 | | |
75 | 387 | return ND->getName().str(); |
76 | 413 | } std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > clang::safeGetName<clang::CXXMethodDecl>(clang::CXXMethodDecl const*) Line | Count | Source | 65 | 173 | template <typename T> std::string safeGetName(const T *ASTNode) { | 66 | 173 | const auto *const ND = llvm::dyn_cast_or_null<clang::NamedDecl>(ASTNode); | 67 | 173 | if (!ND) | 68 | 0 | return ""; | 69 | | | 70 | | // In case F is for example "operator|" the getName() method below would | 71 | | // assert. | 72 | 173 | if (!ND->getDeclName().isIdentifier()) | 73 | 7 | return ""; | 74 | | | 75 | 166 | return ND->getName().str(); | 76 | 173 | } |
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > clang::safeGetName<clang::FunctionDecl>(clang::FunctionDecl const*) Line | Count | Source | 65 | 195 | template <typename T> std::string safeGetName(const T *ASTNode) { | 66 | 195 | const auto *const ND = llvm::dyn_cast_or_null<clang::NamedDecl>(ASTNode); | 67 | 195 | if (!ND) | 68 | 0 | return ""; | 69 | | | 70 | | // In case F is for example "operator|" the getName() method below would | 71 | | // assert. | 72 | 195 | if (!ND->getDeclName().isIdentifier()) | 73 | 19 | return ""; | 74 | | | 75 | 176 | return ND->getName().str(); | 76 | 195 | } |
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > clang::safeGetName<clang::ParmVarDecl>(clang::ParmVarDecl const*) Line | Count | Source | 65 | 18 | template <typename T> std::string safeGetName(const T *ASTNode) { | 66 | 18 | const auto *const ND = llvm::dyn_cast_or_null<clang::NamedDecl>(ASTNode); | 67 | 18 | if (!ND) | 68 | 0 | return ""; | 69 | | | 70 | | // In case F is for example "operator|" the getName() method below would | 71 | | // assert. | 72 | 18 | if (!ND->getDeclName().isIdentifier()) | 73 | 0 | return ""; | 74 | | | 75 | 18 | return ND->getName().str(); | 76 | 18 | } |
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > clang::safeGetName<clang::CXXRecordDecl>(clang::CXXRecordDecl const*) Line | Count | Source | 65 | 27 | template <typename T> std::string safeGetName(const T *ASTNode) { | 66 | 27 | const auto *const ND = llvm::dyn_cast_or_null<clang::NamedDecl>(ASTNode); | 67 | 27 | if (!ND) | 68 | 0 | return ""; | 69 | | | 70 | | // In case F is for example "operator|" the getName() method below would | 71 | | // assert. | 72 | 27 | if (!ND->getDeclName().isIdentifier()) | 73 | 0 | return ""; | 74 | | | 75 | 27 | return ND->getName().str(); | 76 | 27 | } |
|
77 | | |
78 | | } // namespace clang |
79 | | |
80 | | #endif |