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