clang: lib/StaticAnalyzer/Core/CheckerHelpers.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
18#include
19
21
22namespace ento {
23
24
26 if (S->getBeginLoc().isMacroID())
27 return true;
28
29 if (S->getEndLoc().isMacroID())
30 return true;
31
32 for (const Stmt *Child : S->children())
34 return true;
35
36 return false;
37}
38
39
41 const DeclRefExpr *DR = dyn_cast(S);
42
43 if (DR && isa(DR->getDecl()))
44 return true;
45
46 for (const Stmt *Child : S->children())
48 return true;
49
50 return false;
51}
52
53
55 const DeclRefExpr *DR = dyn_cast(S);
56
57 if (DR)
58 if (const VarDecl *VD = dyn_cast(DR->getDecl()))
59 if (VD->isStaticLocal())
60 return true;
61
62 for (const Stmt *Child : S->children())
64 return true;
65
66 return false;
67}
68
69
71 if (isa(S))
72 return true;
73
74 for (const Stmt *Child : S->children())
76 return true;
77
78 return false;
79}
80
81
82std::pair<const clang::VarDecl *, const clang::Expr *>
84 const VarDecl *VD = nullptr;
85 const Expr *RHS = nullptr;
86
87 if (auto Assign = dyn_cast_or_null(S)) {
88 if (Assign->isAssignmentOp()) {
89
90 RHS = Assign->getRHS();
91 if (auto DE = dyn_cast_or_null(Assign->getLHS()))
92 VD = dyn_cast_or_null(DE->getDecl());
93 }
94 } else if (auto PD = dyn_cast_or_null(S)) {
95
96 assert(PD->isSingleDecl() && "We process decls one by one");
97 VD = cast(PD->getSingleDecl());
99 }
100
101 return std::make_pair(VD, RHS);
102}
103
106 if (!AttrType)
108 if (AttrType->getAttrKind() == attr::TypeNullable)
110 else if (AttrType->getAttrKind() == attr::TypeNonNull)
113}
114
117 if (!MacroII)
118 return std::nullopt;
120 if (!MI)
121 return std::nullopt;
122
123
124 std::vector FilteredTokens;
125 FilteredTokens.reserve(MI->tokens().size());
126 for (auto &T : MI->tokens())
127 if (.isOneOf(tok::l_paren, tok::r_paren))
128 FilteredTokens.push_back(T);
129
130
131 const Token &T = FilteredTokens.back();
132
133
134 if (.isLiteral() ||
.getLiteralData())
135 return std::nullopt;
136 StringRef ValueStr = StringRef(T.getLiteralData(), T.getLength());
137 llvm::APInt IntValue;
138 constexpr unsigned AutoSenseRadix = 0;
139 if (ValueStr.getAsInteger(AutoSenseRadix, IntValue))
140 return std::nullopt;
141
142
143 size_t Size = FilteredTokens.size();
144 if (Size >= 2) {
145 if (FilteredTokens[Size - 2].is(tok::minus))
146 IntValue = -IntValue;
147 }
148
149 return IntValue.getSExtValue();
150}
151
153 bool IsBinary) {
154 llvm::StringMap BinOps{
155#define BINARY_OPERATION(Name, Spelling) {Spelling, BO_##Name},
156#include "clang/AST/OperationKinds.def"
157 };
158 llvm::StringMap UnOps{
159#define UNARY_OPERATION(Name, Spelling) {Spelling, UO_##Name},
160#include "clang/AST/OperationKinds.def"
161 };
162
163 switch (OOK) {
164#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
165 case OO_##Name: \
166 if (IsBinary) { \
167 auto BinOpIt = BinOps.find(Spelling); \
168 if (BinOpIt != BinOps.end()) \
169 return OperatorKind(BinOpIt->second); \
170 else \
171 llvm_unreachable("operator was expected to be binary but is not"); \
172 } else { \
173 auto UnOpIt = UnOps.find(Spelling); \
174 if (UnOpIt != UnOps.end()) \
175 return OperatorKind(UnOpIt->second); \
176 else \
177 llvm_unreachable("operator was expected to be unary but is not"); \
178 } \
179 break;
180#include "clang/Basic/OperatorKinds.def"
181 default:
182 llvm_unreachable("unexpected operator kind");
183 }
184}
185
187 if (const auto *Ptr = PtrSVal.getAsRegion()) {
188 return State->getSVal(Ptr);
189 }
190 return std::nullopt;
191}
192
195 while (DC) {
196 if (const auto *NS = dyn_cast(DC);
197 NS && NS->isStdNamespace())
198 return true;
200 }
201 return false;
202}
203
204}
205}
Defines the clang::Preprocessor interface.
An attributed type is a type to which a type attribute has been applied.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
A reference to a declared variable, function, enum, etc.
Decl - This represents one declaration (or definition), e.g.
This represents one expression.
Encapsulates the data about a macro definition (e.g.
ArrayRef< Token > tokens() const
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
const MacroInfo * getMacroInfo(const IdentifierInfo *II) const
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
A (possibly-)qualified type.
Stmt - This represents one statement.
Token - This structure provides full information about a lexed token.
The base class of the type hierarchy.
const T * getAs() const
Member-template getAs'.
Represents a variable declaration or definition.
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
const MemRegion * getAsRegion() const
bool containsEnum(const Stmt *S)
Nullability getNullabilityAnnotation(QualType Type)
Get nullability annotation for a given type.
bool isWithinStdNamespace(const Decl *D)
Returns true if declaration D is in std namespace or any nested namespace or class scope.
bool containsStaticLocal(const Stmt *S)
std::pair< const clang::VarDecl *, const clang::Expr * > parseAssignment(const Stmt *S)
OperatorKind operationKindFromOverloadedOperator(OverloadedOperatorKind OOK, bool IsBinary)
bool containsBuiltinOffsetOf(const Stmt *S)
std::optional< SVal > getPointeeVal(SVal PtrSVal, ProgramStateRef State)
std::optional< int > tryExpandAsInteger(StringRef Macro, const Preprocessor &PP)
Try to parse the value of a defined preprocessor macro.
bool containsMacro(const Stmt *S)
The JSON file list parser is used to communicate input to InstallAPI.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
const FunctionProtoType * T