1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CALLEVENT_H |
16 | #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CALLEVENT_H |
17 | |
18 | #include "clang/AST/Decl.h" |
19 | #include "clang/AST/DeclBase.h" |
20 | #include "clang/AST/DeclCXX.h" |
21 | #include "clang/AST/DeclObjC.h" |
22 | #include "clang/AST/Expr.h" |
23 | #include "clang/AST/ExprCXX.h" |
24 | #include "clang/AST/ExprObjC.h" |
25 | #include "clang/AST/Stmt.h" |
26 | #include "clang/AST/Type.h" |
27 | #include "clang/Basic/IdentifierTable.h" |
28 | #include "clang/Basic/LLVM.h" |
29 | #include "clang/Basic/SourceLocation.h" |
30 | #include "clang/Basic/SourceManager.h" |
31 | #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" |
32 | #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" |
33 | #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h" |
34 | #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" |
35 | #include "llvm/ADT/ArrayRef.h" |
36 | #include "llvm/ADT/IntrusiveRefCntPtr.h" |
37 | #include "llvm/ADT/PointerIntPair.h" |
38 | #include "llvm/ADT/PointerUnion.h" |
39 | #include "llvm/ADT/STLExtras.h" |
40 | #include "llvm/ADT/SmallVector.h" |
41 | #include "llvm/ADT/StringRef.h" |
42 | #include "llvm/Support/Allocator.h" |
43 | #include "llvm/Support/Casting.h" |
44 | #include "llvm/Support/ErrorHandling.h" |
45 | #include <cassert> |
46 | #include <limits> |
47 | #include <utility> |
48 | |
49 | namespace clang { |
50 | |
51 | class LocationContext; |
52 | class ProgramPoint; |
53 | class ProgramPointTag; |
54 | class StackFrameContext; |
55 | |
56 | namespace ento { |
57 | |
58 | enum CallEventKind { |
59 | CE_Function, |
60 | CE_CXXMember, |
61 | CE_CXXMemberOperator, |
62 | CE_CXXDestructor, |
63 | CE_BEG_CXX_INSTANCE_CALLS = CE_CXXMember, |
64 | CE_END_CXX_INSTANCE_CALLS = CE_CXXDestructor, |
65 | CE_CXXConstructor, |
66 | CE_CXXAllocator, |
67 | CE_BEG_FUNCTION_CALLS = CE_Function, |
68 | CE_END_FUNCTION_CALLS = CE_CXXAllocator, |
69 | CE_Block, |
70 | CE_ObjCMessage |
71 | }; |
72 | |
73 | class CallEvent; |
74 | |
75 | |
76 | |
77 | class CallDescription { |
78 | friend CallEvent; |
79 | |
80 | mutable IdentifierInfo *II = nullptr; |
81 | mutable bool IsLookupDone = false; |
82 | |
83 | |
84 | std::vector<const char *> QualifiedName; |
85 | unsigned RequiredArgs; |
86 | |
87 | public: |
88 | const static unsigned NoArgRequirement = std::numeric_limits<unsigned>::max(); |
89 | |
90 | |
91 | |
92 | |
93 | |
94 | |
95 | |
96 | |
97 | |
98 | |
99 | |
100 | CallDescription(ArrayRef<const char *> QualifiedName, |
101 | unsigned RequiredArgs = NoArgRequirement) |
102 | : QualifiedName(QualifiedName), RequiredArgs(RequiredArgs) {} |
103 | |
104 | |
105 | StringRef getFunctionName() const { return QualifiedName.back(); } |
106 | }; |
107 | |
108 | template<typename T = CallEvent> |
109 | class CallEventRef : public IntrusiveRefCntPtr<const T> { |
110 | public: |
111 | CallEventRef(const T *Call) : IntrusiveRefCntPtr<const T>(Call) {} |
112 | CallEventRef(const CallEventRef &Orig) : IntrusiveRefCntPtr<const T>(Orig) {} |
113 | |
114 | CallEventRef<T> cloneWithState(ProgramStateRef State) const { |
115 | return this->get()->template cloneWithState<T>(State); |
116 | } |
117 | |
118 | |
119 | |
120 | template <typename SuperT> |
121 | operator CallEventRef<SuperT> () const { |
122 | return this->get(); |
123 | } |
124 | }; |
125 | |
126 | |
127 | |
128 | |
129 | |
130 | |
131 | |
132 | |
133 | class RuntimeDefinition { |
134 | |
135 | |
136 | const Decl *D = nullptr; |
137 | |
138 | |
139 | |
140 | |
141 | |
142 | const MemRegion *R = nullptr; |
143 | |
144 | public: |
145 | RuntimeDefinition() = default; |
146 | RuntimeDefinition(const Decl *InD): D(InD) {} |
147 | RuntimeDefinition(const Decl *InD, const MemRegion *InR): D(InD), R(InR) {} |
148 | |
149 | const Decl *getDecl() { return D; } |
150 | |
151 | |
152 | |
153 | |
154 | bool mayHaveOtherDefinitions() { return R != nullptr; } |
155 | |
156 | |
157 | |
158 | const MemRegion *getDispatchRegion() { return R; } |
159 | }; |
160 | |
161 | |
162 | |
163 | |
164 | |
165 | |
166 | |
167 | |
168 | |
169 | |
170 | class CallEvent { |
171 | public: |
172 | using Kind = CallEventKind; |
173 | |
174 | private: |
175 | ProgramStateRef State; |
176 | const LocationContext *LCtx; |
177 | llvm::PointerUnion<const Expr *, const Decl *> Origin; |
178 | |
179 | protected: |
180 | |
181 | const void *Data; |
182 | |
183 | |
184 | |
185 | |
186 | SourceLocation Location; |
187 | |
188 | private: |
189 | template <typename T> friend struct llvm::IntrusiveRefCntPtrInfo; |
190 | |
191 | mutable unsigned RefCount = 0; |
192 | |
193 | void Retain() const { ++RefCount; } |
194 | void Release() const; |
195 | |
196 | protected: |
197 | friend class CallEventManager; |
198 | |
199 | CallEvent(const Expr *E, ProgramStateRef state, const LocationContext *lctx) |
200 | : State(std::move(state)), LCtx(lctx), Origin(E) {} |
201 | |
202 | CallEvent(const Decl *D, ProgramStateRef state, const LocationContext *lctx) |
203 | : State(std::move(state)), LCtx(lctx), Origin(D) {} |
204 | |
205 | |
206 | CallEvent(const CallEvent &Original) |
207 | : State(Original.State), LCtx(Original.LCtx), Origin(Original.Origin), |
208 | Data(Original.Data), Location(Original.Location) {} |
209 | |
210 | |
211 | virtual void cloneTo(void *Dest) const = 0; |
212 | |
213 | |
214 | SVal getSVal(const Stmt *S) const { |
215 | return getState()->getSVal(S, getLocationContext()); |
216 | } |
217 | |
218 | using ValueList = SmallVectorImpl<SVal>; |
219 | |
220 | |
221 | |
222 | virtual void getExtraInvalidatedValues(ValueList &Values, |
223 | RegionAndSymbolInvalidationTraits *ETraits) const {} |
224 | |
225 | public: |
226 | CallEvent &operator=(const CallEvent &) = delete; |
227 | virtual ~CallEvent() = default; |
228 | |
229 | |
230 | virtual Kind getKind() const = 0; |
231 | |
232 | |
233 | |
234 | virtual const Decl *getDecl() const { |
235 | return Origin.dyn_cast<const Decl *>(); |
236 | } |
237 | |
238 | |
239 | const ProgramStateRef &getState() const { |
240 | return State; |
241 | } |
242 | |
243 | |
244 | const LocationContext *getLocationContext() const { |
245 | return LCtx; |
246 | } |
247 | |
248 | |
249 | |
250 | virtual RuntimeDefinition getRuntimeDefinition() const = 0; |
251 | |
252 | |
253 | |
254 | const Expr *getOriginExpr() const { |
255 | return Origin.dyn_cast<const Expr *>(); |
256 | } |
257 | |
258 | |
259 | |
260 | |
261 | |
262 | |
263 | virtual unsigned getNumArgs() const = 0; |
264 | |
265 | |
266 | bool () const { |
267 | const Decl *D = getDecl(); |
268 | if (!D) |
269 | return false; |
270 | |
271 | SourceLocation Loc = D->getLocation(); |
272 | if (Loc.isValid()) { |
273 | const SourceManager &SM = |
274 | getState()->getStateManager().getContext().getSourceManager(); |
275 | return SM.isInSystemHeader(D->getLocation()); |
276 | } |
277 | |
278 | |
279 | |
280 | if (const auto *FD = dyn_cast<FunctionDecl>(D)) |
281 | return FD->isOverloadedOperator() && FD->isImplicit() && FD->isGlobal(); |
282 | |
283 | return false; |
284 | } |
285 | |
286 | |
287 | |
288 | |
289 | |
290 | |
291 | bool isCalled(const CallDescription &CD) const; |
292 | |
293 | |
294 | |
295 | virtual SourceRange getSourceRange() const { |
296 | return getOriginExpr()->getSourceRange(); |
297 | } |
298 | |
299 | |
300 | virtual SVal getArgSVal(unsigned Index) const; |
301 | |
302 | |
303 | |
304 | virtual const Expr *getArgExpr(unsigned Index) const { return nullptr; } |
305 | |
306 | |
307 | |
308 | |
309 | virtual SourceRange getArgSourceRange(unsigned Index) const; |
310 | |
311 | |
312 | QualType getResultType() const; |
313 | |
314 | |
315 | |
316 | |
317 | |
318 | SVal getReturnValue() const; |
319 | |
320 | |
321 | |
322 | bool hasNonNullArgumentsWithType(bool (*Condition)(QualType)) const; |
323 | |
324 | |
325 | bool hasNonZeroCallbackArg() const; |
326 | |
327 | |
328 | bool hasVoidPointerToNonConstArg() const; |
329 | |
330 | |
331 | |
332 | |
333 | |
334 | |
335 | virtual bool argumentsMayEscape() const { |
336 | return hasNonZeroCallbackArg(); |
337 | } |
338 | |
339 | |
340 | |
341 | |
342 | |
343 | |
344 | |
345 | |
346 | |
347 | |
348 | |
349 | |
350 | |
351 | |
352 | |
353 | |
354 | |
355 | bool isGlobalCFunction(StringRef SpecificName = StringRef()) const; |
356 | |
357 | |
358 | |
359 | |
360 | |
361 | |
362 | |
363 | |
364 | const IdentifierInfo *getCalleeIdentifier() const { |
365 | const auto *ND = dyn_cast_or_null<NamedDecl>(getDecl()); |
366 | if (!ND) |
367 | return nullptr; |
368 | return ND->getIdentifier(); |
369 | } |
370 | |
371 | |
372 | ProgramPoint getProgramPoint(bool IsPreVisit = false, |
373 | const ProgramPointTag *Tag = nullptr) const; |
374 | |
375 | |
376 | |
377 | |
378 | |
379 | ProgramStateRef invalidateRegions(unsigned BlockCount, |
380 | ProgramStateRef Orig = nullptr) const; |
381 | |
382 | using FrameBindingTy = std::pair<Loc, SVal>; |
383 | using BindingsTy = SmallVectorImpl<FrameBindingTy>; |
384 | |
385 | |
386 | |
387 | virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx, |
388 | BindingsTy &Bindings) const = 0; |
389 | |
390 | |
391 | template <typename T> |
392 | CallEventRef<T> cloneWithState(ProgramStateRef NewState) const; |
393 | |
394 | |
395 | CallEventRef<> cloneWithState(ProgramStateRef NewState) const { |
396 | return cloneWithState<CallEvent>(NewState); |
397 | } |
398 | |
399 | |
400 | |
401 | static bool isCallStmt(const Stmt *S); |
402 | |
403 | |
404 | |
405 | |
406 | static QualType getDeclaredResultType(const Decl *D); |
407 | |
408 | |
409 | |
410 | |
411 | static bool isVariadic(const Decl *D); |
412 | |
413 | |
414 | |
415 | AnalysisDeclContext *getCalleeAnalysisDeclContext() const; |
416 | |
417 | |
418 | |
419 | |
420 | |
421 | const StackFrameContext *getCalleeStackFrame() const; |
422 | |
423 | |
424 | |
425 | const VarRegion *getParameterLocation(unsigned Index) const; |
426 | |
427 | |
428 | |
429 | |
430 | |
431 | |
432 | |
433 | bool isArgumentConstructedDirectly(unsigned Index) const { |
434 | |
435 | return ExprEngine::getObjectUnderConstruction( |
436 | getState(), {getOriginExpr(), Index}, getLocationContext()).hasValue(); |
437 | } |
438 | |
439 | |
440 | |
441 | |
442 | |
443 | virtual Optional<unsigned> |
444 | getAdjustedParameterIndex(unsigned ASTArgumentIndex) const { |
445 | return ASTArgumentIndex; |
446 | } |
447 | |
448 | |
449 | |
450 | |
451 | virtual unsigned getASTArgumentIndex(unsigned CallArgumentIndex) const { |
452 | return CallArgumentIndex; |
453 | } |
454 | |
455 | |
456 | private: |
457 | struct GetTypeFn { |
458 | QualType operator()(ParmVarDecl *PD) const { return PD->getType(); } |
459 | }; |
460 | |
461 | public: |
462 | |
463 | |
464 | |
465 | |
466 | |
467 | virtual ArrayRef<ParmVarDecl *> parameters() const = 0; |
468 | |
469 | using param_type_iterator = |
470 | llvm::mapped_iterator<ArrayRef<ParmVarDecl *>::iterator, GetTypeFn>; |
471 | |
472 | |
473 | |
474 | |
475 | |
476 | |
477 | param_type_iterator param_type_begin() const { |
478 | return llvm::map_iterator(parameters().begin(), GetTypeFn()); |
479 | } |
480 | |
481 | param_type_iterator param_type_end() const { |
482 | return llvm::map_iterator(parameters().end(), GetTypeFn()); |
483 | } |
484 | |
485 | |
486 | void dump(raw_ostream &Out) const; |
487 | void dump() const; |
488 | }; |
489 | |
490 | |
491 | |
492 | class AnyFunctionCall : public CallEvent { |
493 | protected: |
494 | AnyFunctionCall(const Expr *E, ProgramStateRef St, |
495 | const LocationContext *LCtx) |
496 | : CallEvent(E, St, LCtx) {} |
497 | AnyFunctionCall(const Decl *D, ProgramStateRef St, |
498 | const LocationContext *LCtx) |
499 | : CallEvent(D, St, LCtx) {} |
500 | AnyFunctionCall(const AnyFunctionCall &Other) = default; |
501 | |
502 | public: |
503 | |
504 | |
505 | const FunctionDecl *getDecl() const override { |
506 | return cast<FunctionDecl>(CallEvent::getDecl()); |
507 | } |
508 | |
509 | RuntimeDefinition getRuntimeDefinition() const override; |
510 | |
511 | bool argumentsMayEscape() const override; |
512 | |
513 | void getInitialStackFrameContents(const StackFrameContext *CalleeCtx, |
514 | BindingsTy &Bindings) const override; |
515 | |
516 | ArrayRef<ParmVarDecl *> parameters() const override; |
517 | |
518 | static bool classof(const CallEvent *CA) { |
519 | return CA->getKind() >= CE_BEG_FUNCTION_CALLS && |
520 | CA->getKind() <= CE_END_FUNCTION_CALLS; |
521 | } |
522 | }; |
523 | |
524 | |
525 | |
526 | |
527 | class SimpleFunctionCall : public AnyFunctionCall { |
528 | friend class CallEventManager; |
529 | |
530 | protected: |
531 | SimpleFunctionCall(const CallExpr *CE, ProgramStateRef St, |
532 | const LocationContext *LCtx) |
533 | : AnyFunctionCall(CE, St, LCtx) {} |
534 | SimpleFunctionCall(const SimpleFunctionCall &Other) = default; |
535 | |
536 | void cloneTo(void *Dest) const override { |
537 | new (Dest) SimpleFunctionCall(*this); |
538 | } |
539 | |
540 | public: |
541 | virtual const CallExpr *getOriginExpr() const { |
542 | return cast<CallExpr>(AnyFunctionCall::getOriginExpr()); |
543 | } |
544 | |
545 | const FunctionDecl *getDecl() const override; |
546 | |
547 | unsigned getNumArgs() const override { return getOriginExpr()->getNumArgs(); } |
548 | |
549 | const Expr *getArgExpr(unsigned Index) const override { |
550 | return getOriginExpr()->getArg(Index); |
551 | } |
552 | |
553 | Kind getKind() const override { return CE_Function; } |
554 | |
555 | static bool classof(const CallEvent *CA) { |
556 | return CA->getKind() == CE_Function; |
557 | } |
558 | }; |
559 | |
560 | |
561 | |
562 | |
563 | class BlockCall : public CallEvent { |
564 | friend class CallEventManager; |
565 | |
566 | protected: |
567 | BlockCall(const CallExpr *CE, ProgramStateRef St, |
568 | const LocationContext *LCtx) |
569 | : CallEvent(CE, St, LCtx) {} |
570 | BlockCall(const BlockCall &Other) = default; |
571 | |
572 | void cloneTo(void *Dest) const override { new (Dest) BlockCall(*this); } |
573 | |
574 | void getExtraInvalidatedValues(ValueList &Values, |
575 | RegionAndSymbolInvalidationTraits *ETraits) const override; |
576 | |
577 | public: |
578 | virtual const CallExpr *getOriginExpr() const { |
579 | return cast<CallExpr>(CallEvent::getOriginExpr()); |
580 | } |
581 | |
582 | unsigned getNumArgs() const override { return getOriginExpr()->getNumArgs(); } |
583 | |
584 | const Expr *getArgExpr(unsigned Index) const override { |
585 | return getOriginExpr()->getArg(Index); |
586 | } |
587 | |
588 | |
589 | |
590 | |
591 | const BlockDataRegion *getBlockRegion() const; |
592 | |
593 | const BlockDecl *getDecl() const override { |
594 | const BlockDataRegion *BR = getBlockRegion(); |
595 | if (!BR) |
596 | return nullptr; |
597 | return BR->getDecl(); |
598 | } |
599 | |
600 | bool isConversionFromLambda() const { |
601 | const BlockDecl *BD = getDecl(); |
602 | if (!BD) |
603 | return false; |
604 | |
605 | return BD->isConversionFromLambda(); |
606 | } |
607 | |
608 | |
609 | |
610 | const VarRegion *getRegionStoringCapturedLambda() const { |
611 | assert(isConversionFromLambda()); |
612 | const BlockDataRegion *BR = getBlockRegion(); |
613 | (0) . __assert_fail ("BR && \"Block converted from lambda must have a block region\"", "/home/seafit/code_projects/clang_source/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h", 613, __PRETTY_FUNCTION__))" file_link="../../../../../../include/assert.h.html#88" macro="true">assert(BR && "Block converted from lambda must have a block region"); |
614 | |
615 | auto I = BR->referenced_vars_begin(); |
616 | referenced_vars_end()", "/home/seafit/code_projects/clang_source/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h", 616, __PRETTY_FUNCTION__))" file_link="../../../../../../include/assert.h.html#88" macro="true">assert(I != BR->referenced_vars_end()); |
617 | |
618 | return I.getCapturedRegion(); |
619 | } |
620 | |
621 | RuntimeDefinition getRuntimeDefinition() const override { |
622 | if (!isConversionFromLambda()) |
623 | return RuntimeDefinition(getDecl()); |
624 | |
625 | |
626 | |
627 | |
628 | |
629 | |
630 | |
631 | |
632 | |
633 | |
634 | |
635 | |
636 | |
637 | |
638 | |
639 | |
640 | |
641 | |
642 | |
643 | |
644 | const VarDecl *LambdaVD = getRegionStoringCapturedLambda()->getDecl(); |
645 | const CXXRecordDecl *LambdaDecl = LambdaVD->getType()->getAsCXXRecordDecl(); |
646 | CXXMethodDecl* LambdaCallOperator = LambdaDecl->getLambdaCallOperator(); |
647 | |
648 | return RuntimeDefinition(LambdaCallOperator); |
649 | } |
650 | |
651 | bool argumentsMayEscape() const override { |
652 | return true; |
653 | } |
654 | |
655 | void getInitialStackFrameContents(const StackFrameContext *CalleeCtx, |
656 | BindingsTy &Bindings) const override; |
657 | |
658 | ArrayRef<ParmVarDecl*> parameters() const override; |
659 | |
660 | Kind getKind() const override { return CE_Block; } |
661 | |
662 | static bool classof(const CallEvent *CA) { |
663 | return CA->getKind() == CE_Block; |
664 | } |
665 | }; |
666 | |
667 | |
668 | |
669 | class CXXInstanceCall : public AnyFunctionCall { |
670 | protected: |
671 | CXXInstanceCall(const CallExpr *CE, ProgramStateRef St, |
672 | const LocationContext *LCtx) |
673 | : AnyFunctionCall(CE, St, LCtx) {} |
674 | CXXInstanceCall(const FunctionDecl *D, ProgramStateRef St, |
675 | const LocationContext *LCtx) |
676 | : AnyFunctionCall(D, St, LCtx) {} |
677 | CXXInstanceCall(const CXXInstanceCall &Other) = default; |
678 | |
679 | void getExtraInvalidatedValues(ValueList &Values, |
680 | RegionAndSymbolInvalidationTraits *ETraits) const override; |
681 | |
682 | public: |
683 | |
684 | virtual const Expr *getCXXThisExpr() const { return nullptr; } |
685 | |
686 | |
687 | virtual SVal getCXXThisVal() const; |
688 | |
689 | const FunctionDecl *getDecl() const override; |
690 | |
691 | RuntimeDefinition getRuntimeDefinition() const override; |
692 | |
693 | void getInitialStackFrameContents(const StackFrameContext *CalleeCtx, |
694 | BindingsTy &Bindings) const override; |
695 | |
696 | static bool classof(const CallEvent *CA) { |
697 | return CA->getKind() >= CE_BEG_CXX_INSTANCE_CALLS && |
698 | CA->getKind() <= CE_END_CXX_INSTANCE_CALLS; |
699 | } |
700 | }; |
701 | |
702 | |
703 | |
704 | |
705 | class CXXMemberCall : public CXXInstanceCall { |
706 | friend class CallEventManager; |
707 | |
708 | protected: |
709 | CXXMemberCall(const CXXMemberCallExpr *CE, ProgramStateRef St, |
710 | const LocationContext *LCtx) |
711 | : CXXInstanceCall(CE, St, LCtx) {} |
712 | CXXMemberCall(const CXXMemberCall &Other) = default; |
713 | |
714 | void cloneTo(void *Dest) const override { new (Dest) CXXMemberCall(*this); } |
715 | |
716 | public: |
717 | virtual const CXXMemberCallExpr *getOriginExpr() const { |
718 | return cast<CXXMemberCallExpr>(CXXInstanceCall::getOriginExpr()); |
719 | } |
720 | |
721 | unsigned getNumArgs() const override { |
722 | if (const CallExpr *CE = getOriginExpr()) |
723 | return CE->getNumArgs(); |
724 | return 0; |
725 | } |
726 | |
727 | const Expr *getArgExpr(unsigned Index) const override { |
728 | return getOriginExpr()->getArg(Index); |
729 | } |
730 | |
731 | const Expr *getCXXThisExpr() const override; |
732 | |
733 | RuntimeDefinition getRuntimeDefinition() const override; |
734 | |
735 | Kind getKind() const override { return CE_CXXMember; } |
736 | |
737 | static bool classof(const CallEvent *CA) { |
738 | return CA->getKind() == CE_CXXMember; |
739 | } |
740 | }; |
741 | |
742 | |
743 | |
744 | |
745 | |
746 | class CXXMemberOperatorCall : public CXXInstanceCall { |
747 | friend class CallEventManager; |
748 | |
749 | protected: |
750 | CXXMemberOperatorCall(const CXXOperatorCallExpr *CE, ProgramStateRef St, |
751 | const LocationContext *LCtx) |
752 | : CXXInstanceCall(CE, St, LCtx) {} |
753 | CXXMemberOperatorCall(const CXXMemberOperatorCall &Other) = default; |
754 | |
755 | void cloneTo(void *Dest) const override { |
756 | new (Dest) CXXMemberOperatorCall(*this); |
757 | } |
758 | |
759 | public: |
760 | virtual const CXXOperatorCallExpr *getOriginExpr() const { |
761 | return cast<CXXOperatorCallExpr>(CXXInstanceCall::getOriginExpr()); |
762 | } |
763 | |
764 | unsigned getNumArgs() const override { |
765 | return getOriginExpr()->getNumArgs() - 1; |
766 | } |
767 | |
768 | const Expr *getArgExpr(unsigned Index) const override { |
769 | return getOriginExpr()->getArg(Index + 1); |
770 | } |
771 | |
772 | const Expr *getCXXThisExpr() const override; |
773 | |
774 | Kind getKind() const override { return CE_CXXMemberOperator; } |
775 | |
776 | static bool classof(const CallEvent *CA) { |
777 | return CA->getKind() == CE_CXXMemberOperator; |
778 | } |
779 | |
780 | Optional<unsigned> |
781 | getAdjustedParameterIndex(unsigned ASTArgumentIndex) const override { |
782 | |
783 | |
784 | return (ASTArgumentIndex > 0) ? Optional<unsigned>(ASTArgumentIndex - 1) |
785 | : None; |
786 | } |
787 | |
788 | unsigned getASTArgumentIndex(unsigned CallArgumentIndex) const override { |
789 | |
790 | |
791 | return CallArgumentIndex + 1; |
792 | } |
793 | }; |
794 | |
795 | |
796 | |
797 | |
798 | |
799 | class CXXDestructorCall : public CXXInstanceCall { |
800 | friend class CallEventManager; |
801 | |
802 | protected: |
803 | using DtorDataTy = llvm::PointerIntPair<const MemRegion *, 1, bool>; |
804 | |
805 | |
806 | |
807 | |
808 | |
809 | |
810 | |
811 | |
812 | CXXDestructorCall(const CXXDestructorDecl *DD, const Stmt *Trigger, |
813 | const MemRegion *Target, bool IsBaseDestructor, |
814 | ProgramStateRef St, const LocationContext *LCtx) |
815 | : CXXInstanceCall(DD, St, LCtx) { |
816 | Data = DtorDataTy(Target, IsBaseDestructor).getOpaqueValue(); |
817 | Location = Trigger->getEndLoc(); |
818 | } |
819 | |
820 | CXXDestructorCall(const CXXDestructorCall &Other) = default; |
821 | |
822 | void cloneTo(void *Dest) const override {new (Dest) CXXDestructorCall(*this);} |
823 | |
824 | public: |
825 | SourceRange getSourceRange() const override { return Location; } |
826 | unsigned getNumArgs() const override { return 0; } |
827 | |
828 | RuntimeDefinition getRuntimeDefinition() const override; |
829 | |
830 | |
831 | SVal getCXXThisVal() const override; |
832 | |
833 | |
834 | bool isBaseDestructor() const { |
835 | return DtorDataTy::getFromOpaqueValue(Data).getInt(); |
836 | } |
837 | |
838 | Kind getKind() const override { return CE_CXXDestructor; } |
839 | |
840 | static bool classof(const CallEvent *CA) { |
841 | return CA->getKind() == CE_CXXDestructor; |
842 | } |
843 | }; |
844 | |
845 | |
846 | |
847 | |
848 | class CXXConstructorCall : public AnyFunctionCall { |
849 | friend class CallEventManager; |
850 | |
851 | protected: |
852 | |
853 | |
854 | |
855 | |
856 | |
857 | |
858 | |
859 | CXXConstructorCall(const CXXConstructExpr *CE, const MemRegion *Target, |
860 | ProgramStateRef St, const LocationContext *LCtx) |
861 | : AnyFunctionCall(CE, St, LCtx) { |
862 | Data = Target; |
863 | } |
864 | |
865 | CXXConstructorCall(const CXXConstructorCall &Other) = default; |
866 | |
867 | void cloneTo(void *Dest) const override { new (Dest) CXXConstructorCall(*this); } |
868 | |
869 | void getExtraInvalidatedValues(ValueList &Values, |
870 | RegionAndSymbolInvalidationTraits *ETraits) const override; |
871 | |
872 | public: |
873 | virtual const CXXConstructExpr *getOriginExpr() const { |
874 | return cast<CXXConstructExpr>(AnyFunctionCall::getOriginExpr()); |
875 | } |
876 | |
877 | const CXXConstructorDecl *getDecl() const override { |
878 | return getOriginExpr()->getConstructor(); |
879 | } |
880 | |
881 | unsigned getNumArgs() const override { return getOriginExpr()->getNumArgs(); } |
882 | |
883 | const Expr *getArgExpr(unsigned Index) const override { |
884 | return getOriginExpr()->getArg(Index); |
885 | } |
886 | |
887 | |
888 | SVal getCXXThisVal() const; |
889 | |
890 | void getInitialStackFrameContents(const StackFrameContext *CalleeCtx, |
891 | BindingsTy &Bindings) const override; |
892 | |
893 | Kind getKind() const override { return CE_CXXConstructor; } |
894 | |
895 | static bool classof(const CallEvent *CA) { |
896 | return CA->getKind() == CE_CXXConstructor; |
897 | } |
898 | }; |
899 | |
900 | |
901 | |
902 | |
903 | class CXXAllocatorCall : public AnyFunctionCall { |
904 | friend class CallEventManager; |
905 | |
906 | protected: |
907 | CXXAllocatorCall(const CXXNewExpr *E, ProgramStateRef St, |
908 | const LocationContext *LCtx) |
909 | : AnyFunctionCall(E, St, LCtx) {} |
910 | CXXAllocatorCall(const CXXAllocatorCall &Other) = default; |
911 | |
912 | void cloneTo(void *Dest) const override { new (Dest) CXXAllocatorCall(*this); } |
913 | |
914 | public: |
915 | virtual const CXXNewExpr *getOriginExpr() const { |
916 | return cast<CXXNewExpr>(AnyFunctionCall::getOriginExpr()); |
917 | } |
918 | |
919 | const FunctionDecl *getDecl() const override { |
920 | return getOriginExpr()->getOperatorNew(); |
921 | } |
922 | |
923 | |
924 | |
925 | |
926 | unsigned getNumImplicitArgs() const { |
927 | return getOriginExpr()->passAlignment() ? 2 : 1; |
928 | } |
929 | |
930 | unsigned getNumArgs() const override { |
931 | return getOriginExpr()->getNumPlacementArgs() + getNumImplicitArgs(); |
932 | } |
933 | |
934 | const Expr *getArgExpr(unsigned Index) const override { |
935 | |
936 | if (Index < getNumImplicitArgs()) |
937 | return nullptr; |
938 | return getOriginExpr()->getPlacementArg(Index - getNumImplicitArgs()); |
939 | } |
940 | |
941 | |
942 | |
943 | |
944 | |
945 | const Expr *getPlacementArgExpr(unsigned Index) const { |
946 | return getOriginExpr()->getPlacementArg(Index); |
947 | } |
948 | |
949 | Kind getKind() const override { return CE_CXXAllocator; } |
950 | |
951 | static bool classof(const CallEvent *CE) { |
952 | return CE->getKind() == CE_CXXAllocator; |
953 | } |
954 | }; |
955 | |
956 | |
957 | |
958 | |
959 | |
960 | enum ObjCMessageKind { |
961 | OCM_PropertyAccess, |
962 | OCM_Subscript, |
963 | OCM_Message |
964 | }; |
965 | |
966 | |
967 | |
968 | |
969 | class ObjCMethodCall : public CallEvent { |
970 | friend class CallEventManager; |
971 | |
972 | const PseudoObjectExpr *getContainingPseudoObjectExpr() const; |
973 | |
974 | protected: |
975 | ObjCMethodCall(const ObjCMessageExpr *Msg, ProgramStateRef St, |
976 | const LocationContext *LCtx) |
977 | : CallEvent(Msg, St, LCtx) { |
978 | Data = nullptr; |
979 | } |
980 | |
981 | ObjCMethodCall(const ObjCMethodCall &Other) = default; |
982 | |
983 | void cloneTo(void *Dest) const override { new (Dest) ObjCMethodCall(*this); } |
984 | |
985 | void getExtraInvalidatedValues(ValueList &Values, |
986 | RegionAndSymbolInvalidationTraits *ETraits) const override; |
987 | |
988 | |
989 | virtual bool canBeOverridenInSubclass(ObjCInterfaceDecl *IDecl, |
990 | Selector Sel) const; |
991 | |
992 | public: |
993 | virtual const ObjCMessageExpr *getOriginExpr() const { |
994 | return cast<ObjCMessageExpr>(CallEvent::getOriginExpr()); |
995 | } |
996 | |
997 | const ObjCMethodDecl *getDecl() const override { |
998 | return getOriginExpr()->getMethodDecl(); |
999 | } |
1000 | |
1001 | unsigned getNumArgs() const override { |
1002 | return getOriginExpr()->getNumArgs(); |
1003 | } |
1004 | |
1005 | const Expr *getArgExpr(unsigned Index) const override { |
1006 | return getOriginExpr()->getArg(Index); |
1007 | } |
1008 | |
1009 | bool isInstanceMessage() const { |
1010 | return getOriginExpr()->isInstanceMessage(); |
1011 | } |
1012 | |
1013 | ObjCMethodFamily getMethodFamily() const { |
1014 | return getOriginExpr()->getMethodFamily(); |
1015 | } |
1016 | |
1017 | Selector getSelector() const { |
1018 | return getOriginExpr()->getSelector(); |
1019 | } |
1020 | |
1021 | SourceRange getSourceRange() const override; |
1022 | |
1023 | |
1024 | SVal getReceiverSVal() const; |
1025 | |
1026 | |
1027 | SVal getSelfSVal() const; |
1028 | |
1029 | |
1030 | |
1031 | |
1032 | |
1033 | const ObjCInterfaceDecl *getReceiverInterface() const { |
1034 | return getOriginExpr()->getReceiverInterface(); |
1035 | } |
1036 | |
1037 | |
1038 | bool isReceiverSelfOrSuper() const; |
1039 | |
1040 | |
1041 | |
1042 | ObjCMessageKind getMessageKind() const; |
1043 | |
1044 | |
1045 | |
1046 | bool isSetter() const { |
1047 | switch (getMessageKind()) { |
1048 | case OCM_Message: |
1049 | llvm_unreachable("This is not a pseudo-object access!"); |
1050 | case OCM_PropertyAccess: |
1051 | return getNumArgs() > 0; |
1052 | case OCM_Subscript: |
1053 | return getNumArgs() > 1; |
1054 | } |
1055 | llvm_unreachable("Unknown message kind"); |
1056 | } |
1057 | |
1058 | |
1059 | |
1060 | |
1061 | const ObjCPropertyDecl *getAccessedProperty() const; |
1062 | |
1063 | RuntimeDefinition getRuntimeDefinition() const override; |
1064 | |
1065 | bool argumentsMayEscape() const override; |
1066 | |
1067 | void getInitialStackFrameContents(const StackFrameContext *CalleeCtx, |
1068 | BindingsTy &Bindings) const override; |
1069 | |
1070 | ArrayRef<ParmVarDecl*> parameters() const override; |
1071 | |
1072 | Kind getKind() const override { return CE_ObjCMessage; } |
1073 | |
1074 | static bool classof(const CallEvent *CA) { |
1075 | return CA->getKind() == CE_ObjCMessage; |
1076 | } |
1077 | }; |
1078 | |
1079 | |
1080 | |
1081 | |
1082 | |
1083 | |
1084 | |
1085 | |
1086 | class CallEventManager { |
1087 | friend class CallEvent; |
1088 | |
1089 | llvm::BumpPtrAllocator &Alloc; |
1090 | SmallVector<void *, 8> Cache; |
1091 | |
1092 | using CallEventTemplateTy = SimpleFunctionCall; |
1093 | |
1094 | void reclaim(const void *Memory) { |
1095 | Cache.push_back(const_cast<void *>(Memory)); |
1096 | } |
1097 | |
1098 | |
1099 | void *allocate() { |
1100 | if (Cache.empty()) |
1101 | return Alloc.Allocate<CallEventTemplateTy>(); |
1102 | else |
1103 | return Cache.pop_back_val(); |
1104 | } |
1105 | |
1106 | template <typename T, typename Arg> |
1107 | T *create(Arg A, ProgramStateRef St, const LocationContext *LCtx) { |
1108 | static_assert(sizeof(T) == sizeof(CallEventTemplateTy), |
1109 | "CallEvent subclasses are not all the same size"); |
1110 | return new (allocate()) T(A, St, LCtx); |
1111 | } |
1112 | |
1113 | template <typename T, typename Arg1, typename Arg2> |
1114 | T *create(Arg1 A1, Arg2 A2, ProgramStateRef St, const LocationContext *LCtx) { |
1115 | static_assert(sizeof(T) == sizeof(CallEventTemplateTy), |
1116 | "CallEvent subclasses are not all the same size"); |
1117 | return new (allocate()) T(A1, A2, St, LCtx); |
1118 | } |
1119 | |
1120 | template <typename T, typename Arg1, typename Arg2, typename Arg3> |
1121 | T *create(Arg1 A1, Arg2 A2, Arg3 A3, ProgramStateRef St, |
1122 | const LocationContext *LCtx) { |
1123 | static_assert(sizeof(T) == sizeof(CallEventTemplateTy), |
1124 | "CallEvent subclasses are not all the same size"); |
1125 | return new (allocate()) T(A1, A2, A3, St, LCtx); |
1126 | } |
1127 | |
1128 | template <typename T, typename Arg1, typename Arg2, typename Arg3, |
1129 | typename Arg4> |
1130 | T *create(Arg1 A1, Arg2 A2, Arg3 A3, Arg4 A4, ProgramStateRef St, |
1131 | const LocationContext *LCtx) { |
1132 | static_assert(sizeof(T) == sizeof(CallEventTemplateTy), |
1133 | "CallEvent subclasses are not all the same size"); |
1134 | return new (allocate()) T(A1, A2, A3, A4, St, LCtx); |
1135 | } |
1136 | |
1137 | public: |
1138 | CallEventManager(llvm::BumpPtrAllocator &alloc) : Alloc(alloc) {} |
1139 | |
1140 | |
1141 | CallEventRef<> |
1142 | getCaller(const StackFrameContext *CalleeCtx, ProgramStateRef State); |
1143 | |
1144 | |
1145 | |
1146 | CallEventRef<> |
1147 | getCall(const Stmt *S, ProgramStateRef State, |
1148 | const LocationContext *LC); |
1149 | |
1150 | CallEventRef<> |
1151 | getSimpleCall(const CallExpr *E, ProgramStateRef State, |
1152 | const LocationContext *LCtx); |
1153 | |
1154 | CallEventRef<ObjCMethodCall> |
1155 | getObjCMethodCall(const ObjCMessageExpr *E, ProgramStateRef State, |
1156 | const LocationContext *LCtx) { |
1157 | return create<ObjCMethodCall>(E, State, LCtx); |
1158 | } |
1159 | |
1160 | CallEventRef<CXXConstructorCall> |
1161 | getCXXConstructorCall(const CXXConstructExpr *E, const MemRegion *Target, |
1162 | ProgramStateRef State, const LocationContext *LCtx) { |
1163 | return create<CXXConstructorCall>(E, Target, State, LCtx); |
1164 | } |
1165 | |
1166 | CallEventRef<CXXDestructorCall> |
1167 | getCXXDestructorCall(const CXXDestructorDecl *DD, const Stmt *Trigger, |
1168 | const MemRegion *Target, bool IsBase, |
1169 | ProgramStateRef State, const LocationContext *LCtx) { |
1170 | return create<CXXDestructorCall>(DD, Trigger, Target, IsBase, State, LCtx); |
1171 | } |
1172 | |
1173 | CallEventRef<CXXAllocatorCall> |
1174 | getCXXAllocatorCall(const CXXNewExpr *E, ProgramStateRef State, |
1175 | const LocationContext *LCtx) { |
1176 | return create<CXXAllocatorCall>(E, State, LCtx); |
1177 | } |
1178 | }; |
1179 | |
1180 | template <typename T> |
1181 | CallEventRef<T> CallEvent::cloneWithState(ProgramStateRef NewState) const { |
1182 | (0) . __assert_fail ("isa(*this) && \"Cloning to unrelated type\"", "/home/seafit/code_projects/clang_source/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h", 1182, __PRETTY_FUNCTION__))" file_link="../../../../../../include/assert.h.html#88" macro="true">assert(isa<T>(*this) && "Cloning to unrelated type"); |
1183 | static_assert(sizeof(T) == sizeof(CallEvent), |
1184 | "Subclasses may not add fields"); |
1185 | |
1186 | if (NewState == State) |
1187 | return cast<T>(this); |
1188 | |
1189 | CallEventManager &Mgr = State->getStateManager().getCallEventManager(); |
1190 | T *Copy = static_cast<T *>(Mgr.allocate()); |
1191 | cloneTo(Copy); |
1192 | (0) . __assert_fail ("Copy->getKind() == this->getKind() && \"Bad copy\"", "/home/seafit/code_projects/clang_source/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h", 1192, __PRETTY_FUNCTION__))" file_link="../../../../../../include/assert.h.html#88" macro="true">assert(Copy->getKind() == this->getKind() && "Bad copy"); |
1193 | |
1194 | Copy->State = NewState; |
1195 | return Copy; |
1196 | } |
1197 | |
1198 | inline void CallEvent::Release() const { |
1199 | (0) . __assert_fail ("RefCount > 0 && \"Reference count is already zero.\"", "/home/seafit/code_projects/clang_source/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h", 1199, __PRETTY_FUNCTION__))" file_link="../../../../../../include/assert.h.html#88" macro="true">assert(RefCount > 0 && "Reference count is already zero."); |
1200 | --RefCount; |
1201 | |
1202 | if (RefCount > 0) |
1203 | return; |
1204 | |
1205 | CallEventManager &Mgr = State->getStateManager().getCallEventManager(); |
1206 | Mgr.reclaim(this); |
1207 | |
1208 | this->~CallEvent(); |
1209 | } |
1210 | |
1211 | } |
1212 | |
1213 | } |
1214 | |
1215 | namespace llvm { |
1216 | |
1217 | |
1218 | template<class T> struct simplify_type< clang::ento::CallEventRef<T>> { |
1219 | using SimpleType = const T *; |
1220 | |
1221 | static SimpleType |
1222 | getSimplifiedValue(clang::ento::CallEventRef<T> Val) { |
1223 | return Val.get(); |
1224 | } |
1225 | }; |
1226 | |
1227 | } |
1228 | |
1229 | #endif |
1230 | |