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