1 //===- TaggedUnionModeling.h -------------------------------------*- C++ -*-==//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_TAGGEDUNIONMODELING_H
10 #define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_TAGGEDUNIONMODELING_H
12 #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
13 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
14 #include "clang/StaticAnalyzer/Core/Checker.h"
15 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
16 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
17 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
18 #include "llvm/ADT/FoldingSet.h"
21 namespace clang::ento::tagged_union_modeling
{
23 // The implementation of all these functions can be found in the file
24 // StdVariantChecker.cpp under the same directory as this file.
26 bool isCopyConstructorCall(const CallEvent
&Call
);
27 bool isCopyAssignmentCall(const CallEvent
&Call
);
28 bool isMoveAssignmentCall(const CallEvent
&Call
);
29 bool isMoveConstructorCall(const CallEvent
&Call
);
30 bool isStdType(const Type
*Type
, const std::string
&TypeName
);
31 bool isStdVariant(const Type
*Type
);
33 // When invalidating regions, we also have to follow that by invalidating the
34 // corresponding custom data in the program state.
35 template <class TypeMap
>
37 removeInformationStoredForDeadInstances(const CallEvent
&Call
,
38 ProgramStateRef State
,
39 ArrayRef
<const MemRegion
*> Regions
) {
40 // If we do not know anything about the call we shall not continue.
41 // If the call is happens within a system header it is implementation detail.
42 // We should not take it into consideration.
43 if (Call
.isInSystemHeader())
46 for (const MemRegion
*Region
: Regions
)
47 State
= State
->remove
<TypeMap
>(Region
);
52 template <class TypeMap
>
53 void handleConstructorAndAssignment(const CallEvent
&Call
, CheckerContext
&C
,
55 ProgramStateRef State
= Call
.getState();
60 auto ArgSVal
= Call
.getArgSVal(0);
61 const auto *ThisRegion
= ThisSVal
.getAsRegion();
62 const auto *ArgMemRegion
= ArgSVal
.getAsRegion();
64 // Make changes to the state according to type of constructor/assignment
65 bool IsCopy
= isCopyConstructorCall(Call
) || isCopyAssignmentCall(Call
);
66 bool IsMove
= isMoveConstructorCall(Call
) || isMoveAssignmentCall(Call
);
67 // First we handle copy and move operations
68 if (IsCopy
|| IsMove
) {
69 const QualType
*OtherQType
= State
->get
<TypeMap
>(ArgMemRegion
);
71 // If the argument of a copy constructor or assignment is unknown then
72 // we will not know the argument of the copied to object.
74 State
= State
->remove
<TypeMap
>(ThisRegion
);
76 // When move semantics is used we can only know that the moved from
77 // object must be in a destructible state. Other usage of the object
78 // than destruction is undefined.
80 State
= State
->remove
<TypeMap
>(ArgMemRegion
);
82 State
= State
->set
<TypeMap
>(ThisRegion
, *OtherQType
);
86 auto ArgQType
= ArgSVal
.getType(C
.getASTContext());
87 const Type
*ArgTypePtr
= ArgQType
.getTypePtr();
89 QualType WoPointer
= ArgTypePtr
->getPointeeType();
90 State
= State
->set
<TypeMap
>(ThisRegion
, WoPointer
);
93 C
.addTransition(State
);
96 } // namespace clang::ento::tagged_union_modeling
98 #endif // LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_TAGGEDUNIONMODELING_H