1 //===- TaggedUnionModeling.h -------------------------------------*- 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 #ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_TAGGEDUNIONMODELING_H 10 #define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_TAGGEDUNIONMODELING_H 11 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" 19 #include <numeric> 20 21 namespace clang::ento::tagged_union_modeling { 22 23 // The implementation of all these functions can be found in the file 24 // StdVariantChecker.cpp under the same directory as this file. 25 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); 32 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> 36 ProgramStateRef 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()) 44 return State; 45 46 for (const MemRegion *Region : Regions) 47 State = State->remove<TypeMap>(Region); 48 49 return State; 50 } 51 52 template <class TypeMap> 53 void handleConstructorAndAssignment(const CallEvent &Call, CheckerContext &C, 54 SVal ThisSVal) { 55 ProgramStateRef State = Call.getState(); 56 57 if (!State) 58 return; 59 60 auto ArgSVal = Call.getArgSVal(0); 61 const auto *ThisRegion = ThisSVal.getAsRegion(); 62 const auto *ArgMemRegion = ArgSVal.getAsRegion(); 63 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); 70 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. 73 if (!OtherQType) { 74 State = State->remove<TypeMap>(ThisRegion); 75 } else { 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. 79 if (IsMove) 80 State = State->remove<TypeMap>(ArgMemRegion); 81 82 State = State->set<TypeMap>(ThisRegion, *OtherQType); 83 } 84 } else { 85 // Value constructor 86 auto ArgQType = ArgSVal.getType(C.getASTContext()); 87 const Type *ArgTypePtr = ArgQType.getTypePtr(); 88 89 QualType WoPointer = ArgTypePtr->getPointeeType(); 90 State = State->set<TypeMap>(ThisRegion, WoPointer); 91 } 92 93 C.addTransition(State); 94 } 95 96 } // namespace clang::ento::tagged_union_modeling 97 98 #endif // LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_TAGGEDUNIONMODELING_H 99