================ @@ -0,0 +1,128 @@ +//===- TaggedUnionModeling.h -------------------------------------*- C++ -*-==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKER_VARIANTLIKETYPEMODELING_H +#define LLVM_CLANG_LIB_STATICANALYZER_CHECKER_VARIANTLIKETYPEMODELING_H + +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" +#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" +#include "clang/StaticAnalyzer/Core/Checker.h" +#include "clang/StaticAnalyzer/Core/CheckerManager.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" +#include "llvm/ADT/FoldingSet.h" +#include <numeric> + +namespace clang { +namespace ento { +namespace variant_modeling { + +// The implementation of all these functions can be found in the +// StdVariantChecker.cpp file under the same directory as this file. +CallEventRef<> getCaller(const CallEvent &Call, CheckerContext &C); +const TemplateArgument &getFirstTemplateArgument(const CallEvent &Call); +bool isCopyConstructorCall(const CallEvent &Call); +bool isCopyAssignmentCall(const CallEvent &Call); +bool isMoveAssignmentCall(const CallEvent &Call); +bool isMoveConstructorCall(const CallEvent &Call); +bool isStdType(const Type *Type, const std::string &TypeName); +bool isStdVariant(const Type *Type); +bool calledFromSystemHeader(const CallEvent &Call, CheckerContext &C); + +// When invalidating regions we also have to follow that with our data +// storages in the program state. +template <class TypeMap> +ProgramStateRef +removeInformationStoredForDeadInstances(const CallEvent *Call, + ProgramStateRef State, + ArrayRef<const MemRegion *> Regions) { + // If we do not know anything about the call we shall not continue. + if (!Call) { + return State; + } + + // If the call is coming from a system header it is implementation detail. + // We should not take it into consideration. + if (Call->isInSystemHeader()) { + return State; + } + + // Remove the information we know about the invalidate region. + // It is not relevant anymore. + State = std::accumulate( + Regions.begin(), Regions.end(), State, + [](ProgramStateRef State, const MemRegion *CurrentMemRegion) { + if (State->contains<TypeMap>(CurrentMemRegion)) { + State = State->remove<TypeMap>(CurrentMemRegion); + } + return State; + }); + return State; +} + +template <class TypeMap> +void handleConstructorAndAssignment(const CallEvent &Call, CheckerContext &C, + const SVal &ThisSVal) { + ProgramStateRef State = Call.getState(); + + auto ArgSVal = Call.getArgSVal(0); + const auto *ThisRegion = ThisSVal.getAsRegion(); + const auto *ArgMemRegion = ArgSVal.getAsRegion(); + + // Make changes to the state according to type of constructor/assignment + State = [&]() { + bool IsCopy = isCopyConstructorCall(Call) || isCopyAssignmentCall(Call); + bool IsMove = isMoveConstructorCall(Call) || isMoveAssignmentCall(Call); + + // First we handle copy and move operations + if (IsCopy || IsMove) { + // If the argument of a copy constructor or assignment is unknown then + // we will not know the argument of the copied to object. + bool OtherQTypeKnown = State->contains<TypeMap>(ArgMemRegion); + + const QualType *OtherQType; + if (OtherQTypeKnown) { + OtherQType = State->get<TypeMap>(ArgMemRegion); + } else { + return State->contains<TypeMap>(ThisRegion) + ? State->remove<TypeMap>(ThisRegion) + : State; ---------------- DonatNagyE wrote:
Please check what `State->remove<TypeMap>(ThisRegion)` does when the map does not contain `ThisRegion`. Its definition is very complex template magic, but I think it's plausible that it'll just return an unchanged state and then you can simplify code like this in many locations. https://github.com/llvm/llvm-project/pull/66481 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits