[clang-tools-extra] 98550df - [clang-tidy] Add configuration option to bugprone-unchecked-optional-access check.
Yitzhak Mandelbaum via cfe-commits
cfe-commits at lists.llvm.org
Thu Dec 15 07:43:36 PST 2022
Author: Yitzhak Mandelbaum
Date: 2022-12-15T15:43:21Z
New Revision: 98550df7b7bbce0e38a1ec558287d759163c64ba
URL: https://github.com/llvm/llvm-project/commit/98550df7b7bbce0e38a1ec558287d759163c64ba
DIFF: https://github.com/llvm/llvm-project/commit/98550df7b7bbce0e38a1ec558287d759163c64ba.diff
LOG: [clang-tidy] Add configuration option to bugprone-unchecked-optional-access check.
The underlying model already supports ignoring accesses to optionals through
smart pointers. This patch exposes that option through ClangTidy's configuration
options.
Differential Revision: https://reviews.llvm.org/D140021
Added:
clang-tools-extra/test/clang-tidy/checkers/bugprone/unchecked-optional-access-ignore-smart.cpp
Modified:
clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp
clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.h
Removed:
################################################################################
diff --git a/clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp
index 7137b78640ff2..c97917ebc3e05 100644
--- a/clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp
@@ -9,18 +9,15 @@
#include "UncheckedOptionalAccessCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclTemplate.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Analysis/CFG.h"
#include "clang/Analysis/FlowSensitive/ControlFlowContext.h"
#include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h"
#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
-#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
#include "clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h"
#include "clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h"
#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/Any.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Error.h"
@@ -33,12 +30,14 @@ namespace bugprone {
using ast_matchers::MatchFinder;
using dataflow::UncheckedOptionalAccessDiagnoser;
using dataflow::UncheckedOptionalAccessModel;
+using dataflow::UncheckedOptionalAccessModelOptions;
using llvm::Optional;
static constexpr llvm::StringLiteral FuncID("fun");
static Optional<std::vector<SourceLocation>>
-analyzeFunction(const FunctionDecl &FuncDecl, ASTContext &ASTCtx) {
+analyzeFunction(const FunctionDecl &FuncDecl, ASTContext &ASTCtx,
+ UncheckedOptionalAccessModelOptions ModelOptions) {
using dataflow::ControlFlowContext;
using dataflow::DataflowAnalysisState;
using llvm::Expected;
@@ -52,7 +51,7 @@ analyzeFunction(const FunctionDecl &FuncDecl, ASTContext &ASTCtx) {
std::make_unique<dataflow::WatchedLiteralsSolver>());
dataflow::Environment Env(AnalysisContext, FuncDecl);
UncheckedOptionalAccessModel Analysis(ASTCtx);
- UncheckedOptionalAccessDiagnoser Diagnoser;
+ UncheckedOptionalAccessDiagnoser Diagnoser(ModelOptions);
std::vector<SourceLocation> Diagnostics;
Expected<std::vector<
Optional<DataflowAnalysisState<UncheckedOptionalAccessModel::Lattice>>>>
@@ -98,7 +97,7 @@ void UncheckedOptionalAccessCheck::check(
return;
if (Optional<std::vector<SourceLocation>> Errors =
- analyzeFunction(*FuncDecl, *Result.Context))
+ analyzeFunction(*FuncDecl, *Result.Context, ModelOptions))
for (const SourceLocation &Loc : *Errors)
diag(Loc, "unchecked access to optional value");
}
diff --git a/clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.h b/clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.h
index c00b0d7b14d19..ae583fd0e940f 100644
--- a/clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.h
+++ b/clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.h
@@ -11,6 +11,7 @@
#include "../ClangTidyCheck.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h"
namespace clang {
namespace tidy {
@@ -24,12 +25,21 @@ namespace bugprone {
class UncheckedOptionalAccessCheck : public ClangTidyCheck {
public:
UncheckedOptionalAccessCheck(StringRef Name, ClangTidyContext *Context)
- : ClangTidyCheck(Name, Context) {}
+ : ClangTidyCheck(Name, Context),
+ ModelOptions{
+ Options.getLocalOrGlobal("IgnoreSmartPointerDereference", false)} {}
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
return LangOpts.CPlusPlus;
}
+ void storeOptions(ClangTidyOptions::OptionMap &Opts) override {
+ Options.store(Opts, "IgnoreSmartPointerDereference",
+ ModelOptions.IgnoreSmartPointerDereference);
+ }
+
+private:
+ dataflow::UncheckedOptionalAccessModelOptions ModelOptions;
};
} // namespace bugprone
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/unchecked-optional-access-ignore-smart.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unchecked-optional-access-ignore-smart.cpp
new file mode 100644
index 0000000000000..d29153b3b7bbe
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unchecked-optional-access-ignore-smart.cpp
@@ -0,0 +1,51 @@
+// RUN: %check_clang_tidy %s bugprone-unchecked-optional-access %t -- \
+// RUN: -config="{CheckOptions: [ \
+// RUN: {key: bugprone-unchecked-optional-access.IgnoreSmartPointerDereference, value: true}]}" -- \
+// RUN: -I %S/Inputs/unchecked-optional-access
+
+#include "absl/types/optional.h"
+
+// Include some basic cases to ensure that IgnoreSmartPointerDereference doesn't
+// disable everything. Then check the relevant smart-pointer cases.
+
+void unchecked_deref_operator_access(const absl::optional<int> &opt) {
+ *opt;
+ // CHECK-MESSAGES: :[[@LINE-1]]:4: warning: unchecked access to optional value
+}
+
+void unchecked_value_access(const absl::optional<int> &opt) {
+ opt.value();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: unchecked access to optional value [bugprone-unchecked-optional-access]
+}
+
+struct Foo {
+ void foo() const {}
+};
+
+void unchecked_arrow_operator_access(const absl::optional<Foo> &opt) {
+ opt->foo();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: unchecked access to optional value
+}
+
+template <typename T>
+struct SmartPtr {
+ T& operator*() &;
+ T* operator->();
+};
+
+struct Bar {
+ absl::optional<int> opt;
+};
+
+
+void unchecked_value_access_through_smart_ptr(SmartPtr<absl::optional<int>> s) {
+ s->value();
+ (*s).value();
+
+}
+
+void unchecked_value_access_through_smart_ptr_field(SmartPtr<Bar> s) {
+ s->opt.value();
+ (*s).opt.value();
+
+}
More information about the cfe-commits
mailing list