1 //== CheckerHelpers.h - Helper functions for checkers ------------*- 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 // This file defines various utilities used by checkers. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CHECKERHELPERS_H 14 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CHECKERHELPERS_H 15 16 #include "ProgramState_Fwd.h" 17 #include "SVals.h" 18 #include "clang/AST/OperationKinds.h" 19 #include "clang/AST/Stmt.h" 20 #include "clang/Basic/OperatorKinds.h" 21 #include <optional> 22 #include <tuple> 23 24 namespace clang { 25 26 class Expr; 27 class VarDecl; 28 class QualType; 29 class Preprocessor; 30 31 namespace ento { 32 33 bool containsMacro(const Stmt *S); 34 bool containsEnum(const Stmt *S); 35 bool containsStaticLocal(const Stmt *S); 36 bool containsBuiltinOffsetOf(const Stmt *S); 37 template <class T> bool containsStmt(const Stmt *S) { 38 if (isa<T>(S)) 39 return true; 40 41 for (const Stmt *Child : S->children()) 42 if (Child && containsStmt<T>(Child)) 43 return true; 44 45 return false; 46 } 47 48 std::pair<const clang::VarDecl *, const clang::Expr *> 49 parseAssignment(const Stmt *S); 50 51 // Do not reorder! The getMostNullable method relies on the order. 52 // Optimization: Most pointers expected to be unspecified. When a symbol has an 53 // unspecified or nonnull type non of the rules would indicate any problem for 54 // that symbol. For this reason only nullable and contradicted nullability are 55 // stored for a symbol. When a symbol is already contradicted, it can not be 56 // casted back to nullable. 57 enum class Nullability : char { 58 Contradicted, // Tracked nullability is contradicted by an explicit cast. Do 59 // not report any nullability related issue for this symbol. 60 // This nullability is propagated aggressively to avoid false 61 // positive results. See the comment on getMostNullable method. 62 Nullable, 63 Unspecified, 64 Nonnull 65 }; 66 67 /// Get nullability annotation for a given type. 68 Nullability getNullabilityAnnotation(QualType Type); 69 70 /// Try to parse the value of a defined preprocessor macro. We can only parse 71 /// simple expressions that consist of an optional minus sign token and then a 72 /// token for an integer. If we cannot parse the value then std::nullopt is 73 /// returned. 74 std::optional<int> tryExpandAsInteger(StringRef Macro, const Preprocessor &PP); 75 76 class OperatorKind { 77 union { 78 BinaryOperatorKind Bin; 79 UnaryOperatorKind Un; 80 } Op; 81 bool IsBinary; 82 83 public: 84 explicit OperatorKind(BinaryOperatorKind Bin) : Op{Bin}, IsBinary{true} {} 85 explicit OperatorKind(UnaryOperatorKind Un) : IsBinary{false} { Op.Un = Un; } 86 bool IsBinaryOp() const { return IsBinary; } 87 88 BinaryOperatorKind GetBinaryOpUnsafe() const { 89 assert(IsBinary && "cannot get binary operator - we have a unary operator"); 90 return Op.Bin; 91 } 92 93 std::optional<BinaryOperatorKind> GetBinaryOp() const { 94 if (IsBinary) 95 return Op.Bin; 96 return {}; 97 } 98 99 UnaryOperatorKind GetUnaryOpUnsafe() const { 100 assert(!IsBinary && 101 "cannot get unary operator - we have a binary operator"); 102 return Op.Un; 103 } 104 105 std::optional<UnaryOperatorKind> GetUnaryOp() const { 106 if (!IsBinary) 107 return Op.Un; 108 return {}; 109 } 110 }; 111 112 OperatorKind operationKindFromOverloadedOperator(OverloadedOperatorKind OOK, 113 bool IsBinary); 114 115 std::optional<SVal> getPointeeVal(SVal PtrSVal, ProgramStateRef State); 116 117 /// Returns true if declaration \p D is in std namespace or any nested namespace 118 /// or class scope. 119 bool isWithinStdNamespace(const Decl *D); 120 121 } // namespace ento 122 123 } // namespace clang 124 125 #endif 126