[clang-tools-extra] [analyzer] Add std::variant checker (PR #66481)
https://github.com/spaits updated https://github.com/llvm/llvm-project/pull/66481 From ce62d3e1924b497b3e7160579a87557119c9e35d Mon Sep 17 00:00:00 2001 From: Gabor Spaits Date: Fri, 15 Sep 2023 10:21:30 +0200 Subject: [PATCH 1/4] [analyzer] Add std::variant checker Adding a checker that checks for bad std::variant type access. --- .../clang/StaticAnalyzer/Checkers/Checkers.td | 4 + .../StaticAnalyzer/Checkers/CMakeLists.txt| 1 + .../Checkers/StdVariantChecker.cpp| 327 .../Checkers/TaggedUnionModeling.h| 104 + .../Inputs/system-header-simulator-cxx.h | 122 ++ .../diagnostics/explicit-suppression.cpp | 2 +- clang/test/Analysis/std-variant-checker.cpp | 358 ++ 7 files changed, 917 insertions(+), 1 deletion(-) create mode 100644 clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp create mode 100644 clang/lib/StaticAnalyzer/Checkers/TaggedUnionModeling.h create mode 100644 clang/test/Analysis/std-variant-checker.cpp diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td index 65c1595eb6245dd..052cf5f884f2773 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -318,6 +318,10 @@ def C11LockChecker : Checker<"C11Lock">, Dependencies<[PthreadLockBase]>, Documentation; +def StdVariantChecker : Checker<"StdVariant">, + HelpText<"Check for bad type access for std::variant.">, + Documentation; + } // end "alpha.core" //===--===// diff --git a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt index ae849f59f90d3d9..d7cb51e1a0819a8 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt +++ b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt @@ -108,6 +108,7 @@ add_clang_library(clangStaticAnalyzerCheckers SmartPtrModeling.cpp StackAddrEscapeChecker.cpp StdLibraryFunctionsChecker.cpp + StdVariantChecker.cpp STLAlgorithmModeling.cpp StreamChecker.cpp StringChecker.cpp diff --git a/clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp new file mode 100644 index 000..680c5567431bbfb --- /dev/null +++ b/clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp @@ -0,0 +1,327 @@ +//===- StdVariantChecker.cpp -*- 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 +// +//===--===// + +#include "clang/AST/Type.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 "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" +#include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Casting.h" +#include +#include + +#include "TaggedUnionModeling.h" + +using namespace clang; +using namespace ento; +using namespace tagged_union_modeling; + +REGISTER_MAP_WITH_PROGRAMSTATE(VariantHeldTypeMap, const MemRegion *, QualType) + +namespace clang { +namespace ento { +namespace tagged_union_modeling { + +// Returns the CallEvent representing the caller of the function +// It is needed because the CallEvent class does not contain enough information +// to tell who called it. Checker context is needed. +CallEventRef<> getCaller(const CallEvent &Call, const ProgramStateRef &State) { + const auto *CallLocationContext = Call.getLocationContext(); + if (!CallLocationContext || CallLocationContext->inTopFrame()) +return nullptr; + + const auto *CallStackFrameContext = CallLocationContext->getStackFrame(); + if (!CallStackFrameContext) +return nullptr; + + CallEventManager &CEMgr = State->getStateManager().getCallEventManager(); + return CEMgr.getCaller(CallStackFrameContext, State); +} + +const CXXConstructorDecl * +getConstructorDeclarationForCall(const CallEvent &Call) { + const auto *ConstructorCall = dyn_cast(&Call); + if (!ConstructorCall) +return nullptr; + + return ConstructorCall->getDecl(); +} + +bool isCopyConstructorCall(const CallEvent &Call) { + if (const CXXConstructorDecl *ConstructorDecl = + getConstructorDeclarationForCall(Call)) +return ConstructorDecl->isCopyConstructor(); + return false; +} + +bool isCopyAssignmentCall(const CallE
[clang-tools-extra] [analyzer] Add std::variant checker (PR #66481)
https://github.com/spaits updated https://github.com/llvm/llvm-project/pull/66481 From ce62d3e1924b497b3e7160579a87557119c9e35d Mon Sep 17 00:00:00 2001 From: Gabor Spaits Date: Fri, 15 Sep 2023 10:21:30 +0200 Subject: [PATCH 1/3] [analyzer] Add std::variant checker Adding a checker that checks for bad std::variant type access. --- .../clang/StaticAnalyzer/Checkers/Checkers.td | 4 + .../StaticAnalyzer/Checkers/CMakeLists.txt| 1 + .../Checkers/StdVariantChecker.cpp| 327 .../Checkers/TaggedUnionModeling.h| 104 + .../Inputs/system-header-simulator-cxx.h | 122 ++ .../diagnostics/explicit-suppression.cpp | 2 +- clang/test/Analysis/std-variant-checker.cpp | 358 ++ 7 files changed, 917 insertions(+), 1 deletion(-) create mode 100644 clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp create mode 100644 clang/lib/StaticAnalyzer/Checkers/TaggedUnionModeling.h create mode 100644 clang/test/Analysis/std-variant-checker.cpp diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td index 65c1595eb6245dd..052cf5f884f2773 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -318,6 +318,10 @@ def C11LockChecker : Checker<"C11Lock">, Dependencies<[PthreadLockBase]>, Documentation; +def StdVariantChecker : Checker<"StdVariant">, + HelpText<"Check for bad type access for std::variant.">, + Documentation; + } // end "alpha.core" //===--===// diff --git a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt index ae849f59f90d3d9..d7cb51e1a0819a8 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt +++ b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt @@ -108,6 +108,7 @@ add_clang_library(clangStaticAnalyzerCheckers SmartPtrModeling.cpp StackAddrEscapeChecker.cpp StdLibraryFunctionsChecker.cpp + StdVariantChecker.cpp STLAlgorithmModeling.cpp StreamChecker.cpp StringChecker.cpp diff --git a/clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp new file mode 100644 index 000..680c5567431bbfb --- /dev/null +++ b/clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp @@ -0,0 +1,327 @@ +//===- StdVariantChecker.cpp -*- 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 +// +//===--===// + +#include "clang/AST/Type.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 "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" +#include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Casting.h" +#include +#include + +#include "TaggedUnionModeling.h" + +using namespace clang; +using namespace ento; +using namespace tagged_union_modeling; + +REGISTER_MAP_WITH_PROGRAMSTATE(VariantHeldTypeMap, const MemRegion *, QualType) + +namespace clang { +namespace ento { +namespace tagged_union_modeling { + +// Returns the CallEvent representing the caller of the function +// It is needed because the CallEvent class does not contain enough information +// to tell who called it. Checker context is needed. +CallEventRef<> getCaller(const CallEvent &Call, const ProgramStateRef &State) { + const auto *CallLocationContext = Call.getLocationContext(); + if (!CallLocationContext || CallLocationContext->inTopFrame()) +return nullptr; + + const auto *CallStackFrameContext = CallLocationContext->getStackFrame(); + if (!CallStackFrameContext) +return nullptr; + + CallEventManager &CEMgr = State->getStateManager().getCallEventManager(); + return CEMgr.getCaller(CallStackFrameContext, State); +} + +const CXXConstructorDecl * +getConstructorDeclarationForCall(const CallEvent &Call) { + const auto *ConstructorCall = dyn_cast(&Call); + if (!ConstructorCall) +return nullptr; + + return ConstructorCall->getDecl(); +} + +bool isCopyConstructorCall(const CallEvent &Call) { + if (const CXXConstructorDecl *ConstructorDecl = + getConstructorDeclarationForCall(Call)) +return ConstructorDecl->isCopyConstructor(); + return false; +} + +bool isCopyAssignmentCall(const CallE
[clang-tools-extra] [analyzer] Add std::variant checker (PR #66481)
@@ -0,0 +1,104 @@ +//===- 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 + +namespace clang { +namespace ento { +namespace tagged_union_modeling { + +// The implementation of all these functions can be found in the file +// StdVariantChecker.cpp under the same directory as this file. +CallEventRef<> getCaller(const CallEvent &Call, CheckerContext &C); +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 by invalidating the +// corresponding custom data in the program state. +template +ProgramStateRef +removeInformationStoredForDeadInstances(const CallEvent *Call, spaits wrote: Then I will modify my function accordingly. Should I take a look at the `checkRegionChanges` callback in general and consider modifying it to take `const CallEvent &` instead of `const CallEvent *` ? Do you think that would be a good task? I think I would have time for it and I would enjoy doing it. 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
[clang-tools-extra] [analyzer] Add std::variant checker (PR #66481)
@@ -0,0 +1,104 @@ +//===- 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 + +namespace clang { +namespace ento { +namespace tagged_union_modeling { + +// The implementation of all these functions can be found in the file +// StdVariantChecker.cpp under the same directory as this file. +CallEventRef<> getCaller(const CallEvent &Call, CheckerContext &C); +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 by invalidating the +// corresponding custom data in the program state. +template +ProgramStateRef +removeInformationStoredForDeadInstances(const CallEvent *Call, steakhal wrote: I don't understand how some other API might affect this one. I thought you could always transform a reference to a pointer and the other way around using the deref and addrof operators. 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
[clang-tools-extra] [analyzer] Add std::variant checker (PR #66481)
@@ -0,0 +1,104 @@ +//===- 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 + +namespace clang { +namespace ento { +namespace tagged_union_modeling { + +// The implementation of all these functions can be found in the file +// StdVariantChecker.cpp under the same directory as this file. +CallEventRef<> getCaller(const CallEvent &Call, CheckerContext &C); +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); steakhal wrote: Then why aren't these part of the CallEvent API? 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
[clang-tools-extra] [analyzer] Add std::variant checker (PR #66481)
@@ -0,0 +1,104 @@ +//===- 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 + +namespace clang { +namespace ento { +namespace tagged_union_modeling { + +// The implementation of all these functions can be found in the file +// StdVariantChecker.cpp under the same directory as this file. +CallEventRef<> getCaller(const CallEvent &Call, CheckerContext &C); +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 by invalidating the +// corresponding custom data in the program state. +template +ProgramStateRef +removeInformationStoredForDeadInstances(const CallEvent *Call, spaits wrote: This is called from the checkRegionChanges callback. That callback has a const CallEvent * parameter and that is passed here. I can modify my function to take a const CallEvent &, but it is only called from checkRegionChanges callbacks. Should I still modify it to reference? 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
[clang-tools-extra] [analyzer] Add std::variant checker (PR #66481)
@@ -0,0 +1,104 @@ +//===- 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 steakhal wrote: Shouldn't these macros match the path of the file, as per llvm guidelines? 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
[clang-tools-extra] [analyzer] Add std::variant checker (PR #66481)
@@ -0,0 +1,327 @@ +//===- StdVariantChecker.cpp -*- 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 +// +//===--===// + +#include "clang/AST/Type.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 "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" +#include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Casting.h" +#include +#include + +#include "TaggedUnionModeling.h" + +using namespace clang; +using namespace ento; +using namespace tagged_union_modeling; + +REGISTER_MAP_WITH_PROGRAMSTATE(VariantHeldTypeMap, const MemRegion *, QualType) + +namespace clang { +namespace ento { +namespace tagged_union_modeling { + +// Returns the CallEvent representing the caller of the function +// It is needed because the CallEvent class does not contain enough information +// to tell who called it. Checker context is needed. +CallEventRef<> getCaller(const CallEvent &Call, const ProgramStateRef &State) { steakhal wrote: If this function is designed to be exposed on the API, the comment should be in the header documenting it. 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
[clang-tools-extra] [analyzer] Add std::variant checker (PR #66481)
https://github.com/steakhal requested changes to this pull request. I had a quick look once again. This this time I focused on the library boundaries and APIs. 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
[clang-tools-extra] [analyzer] Add std::variant checker (PR #66481)
@@ -0,0 +1,327 @@ +//===- StdVariantChecker.cpp -*- 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 +// +//===--===// + +#include "clang/AST/Type.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 "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" +#include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Casting.h" +#include +#include + +#include "TaggedUnionModeling.h" + +using namespace clang; +using namespace ento; +using namespace tagged_union_modeling; + +REGISTER_MAP_WITH_PROGRAMSTATE(VariantHeldTypeMap, const MemRegion *, QualType) + +namespace clang { +namespace ento { +namespace tagged_union_modeling { steakhal wrote: BTW you can now open all these together: `namespace clang::ento::... {` 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
[clang-tools-extra] [analyzer] Add std::variant checker (PR #66481)
@@ -0,0 +1,104 @@ +//===- 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 + +namespace clang { +namespace ento { +namespace tagged_union_modeling { + +// The implementation of all these functions can be found in the file +// StdVariantChecker.cpp under the same directory as this file. +CallEventRef<> getCaller(const CallEvent &Call, CheckerContext &C); +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); steakhal wrote: A lot of these if not all are implementation details, and used only from a single cpp file. I feel, these should be local (thus static) to that cpp file. 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
[clang-tools-extra] [analyzer] Add std::variant checker (PR #66481)
@@ -0,0 +1,104 @@ +//===- 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 + +namespace clang { +namespace ento { +namespace tagged_union_modeling { + +// The implementation of all these functions can be found in the file +// StdVariantChecker.cpp under the same directory as this file. +CallEventRef<> getCaller(const CallEvent &Call, CheckerContext &C); +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 by invalidating the +// corresponding custom data in the program state. +template +ProgramStateRef +removeInformationStoredForDeadInstances(const CallEvent *Call, +ProgramStateRef State, +ArrayRef Regions) { + // If we do not know anything about the call we shall not continue. + // If the call is happens within a system header it is implementation detail. + // We should not take it into consideration. + if (!Call || Call->isInSystemHeader()) +return State; + + for (const MemRegion *Region : Regions) +State = State->remove(Region); + + return State; +} + +template +void handleConstructorAndAssignment(const CallEvent &Call, CheckerContext &C, +const SVal &ThisSVal) { steakhal wrote: Why do you need this exposed in this header? It looks like an implementation detail to me. BTW SVals should be taken by value. 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
[clang-tools-extra] [analyzer] Add std::variant checker (PR #66481)
https://github.com/steakhal edited 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
[clang-tools-extra] [analyzer] Add std::variant checker (PR #66481)
spaits wrote: @steakhal we have also run the checker on multiple open source projects (a few weeks ago) and it did not crash. (It did not have any findings. There were only two C++ 17 projects and they had retrieved value from std::variant at most 20 times). Could you please take another look at the commit and give feedback, when you'll have time for it? 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
[clang-tools-extra] [analyzer] Add std::variant checker (PR #66481)
DonatNagyE wrote: > @DonatNagyE I can see you all have a lot of PRs. I have limited time, but I > think I can do two this week. Maybe one next week. In what order should I go > through the PRs? I guess, this one should be in the lucky two. The most urgent ones are https://github.com/llvm/llvm-project/pull/66207 (a "real" review) and https://github.com/llvm/llvm-project/pull/66647 (where nothing significant changed since you reviewed it last time). I hope that you can do those and this one. Moreover, I'm planning to merge the commit https://github.com/llvm/llvm-project/pull/67572 because it's just an NFC cleanup and @gamesh411 already reviewed it. 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
[clang-tools-extra] [analyzer] Add std::variant checker (PR #66481)
steakhal wrote: @DonatNagyE I can see you all have a lot of PRs. I have limited time, but I think I can do two this week. Maybe one next week. In what order should I go through the PRs? I guess, this one should be in the lucky two. 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