Index: clang/include/clang/StaticAnalyzer/Checkers/Checkers.td =================================================================== --- clang/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ clang/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -305,6 +305,10 @@ Dependencies<[PthreadLockBase]>, Documentation; +def StdVariantChecker : Checker<"StdVariant">, + HelpText<"Check std::variant">, + Documentation; + } // end "alpha.core" //===----------------------------------------------------------------------===// Index: clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt =================================================================== --- clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt +++ clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt @@ -107,6 +107,7 @@ SmartPtrModeling.cpp StackAddrEscapeChecker.cpp StdLibraryFunctionsChecker.cpp + StdVariantChecker.cpp STLAlgorithmModeling.cpp StreamChecker.cpp StringChecker.cpp Index: clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp =================================================================== --- /dev/null +++ clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp @@ -0,0 +1,50 @@ +//===- 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/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" + +using namespace clang; +using namespace ento; + +class StdVariantChecker : public Checker { + CallDescription VariantConstructorCall{{"std", "variant"}, 0, 0}; + BugType VariantCreated{this, "VariantCreated", "VariantCreated"}; + + public: + void checkPreCall(const CallEvent &Call, CheckerContext &C) const { + if (!isa(Call)) + return; + if (!VariantConstructorCall.matches(Call)) + return; + + ExplodedNode* ErrNode = C.generateNonFatalErrorNode(); + if (!ErrNode) + return; + llvm::SmallString<128> Str; + llvm::raw_svector_ostream OS(Str); + OS << "Variant Created"; + auto R = std::make_unique( + VariantCreated, OS.str(), ErrNode); + C.emitReport(std::move(R)); + } +}; + +bool clang::ento::shouldRegisterStdVariantChecker( + clang::ento::CheckerManager const &mgr) { + return true; +} + +void clang::ento::registerStdVariantChecker(clang::ento::CheckerManager &mgr) { + mgr.registerChecker(); +} \ No newline at end of file Index: clang/test/Analysis/Inputs/variant.h =================================================================== --- /dev/null +++ clang/test/Analysis/Inputs/variant.h @@ -0,0 +1,16 @@ +// Like the compiler, the static analyzer treats some functions differently if +// they come from a system header -- for example, it is assumed that system +// functions do not arbitrarily free() their parameters, and that some bugs +// found in system headers cannot be fixed by the user and should be +// suppressed. +#pragma clang system_header + +#ifndef VARIANT_H +#define VARIANT_H + +namespace std { + template + class variant {}; +} //end of namespace std + +#endif //VARIANT_H \ No newline at end of file Index: clang/test/Analysis/std-variant-checker.cpp =================================================================== --- /dev/null +++ clang/test/Analysis/std-variant-checker.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core.StdVariant %s -verify + +#include "Inputs/variant.h" + +void g() { + std::variant v; // expected-warning{{Variant Created [alpha.core.StdVariant]}} +} \ No newline at end of file