Skip to content

Commit 24cb2c1

Browse files
committed
[𝘀𝗽𝗿] initial version
Created using spr 1.3.7
2 parents 0e0ec4c + 8189b6d commit 24cb2c1

File tree

8 files changed

+1337
-1
lines changed

8 files changed

+1337
-1
lines changed

clang-tools-extra/clang-tidy/abseil/AbseilTidyModule.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "StringFindStrContainsCheck.h"
2828
#include "TimeComparisonCheck.h"
2929
#include "TimeSubtractionCheck.h"
30+
#include "UncheckedStatusOrAccessCheck.h"
3031
#include "UpgradeDurationConversionsCheck.h"
3132

3233
namespace clang::tidy {
@@ -69,6 +70,8 @@ class AbseilModule : public ClangTidyModule {
6970
"abseil-time-subtraction");
7071
CheckFactories.registerCheck<UpgradeDurationConversionsCheck>(
7172
"abseil-upgrade-duration-conversions");
73+
CheckFactories.registerCheck<UncheckedStatusOrAccessCheck>(
74+
"abseil-unchecked-statusor-access");
7275
}
7376
};
7477

clang-tools-extra/clang-tidy/abseil/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ add_clang_library(clangTidyAbseilModule STATIC
2525
TimeComparisonCheck.cpp
2626
TimeSubtractionCheck.cpp
2727
UpgradeDurationConversionsCheck.cpp
28+
UncheckedStatusOrAccessCheck.cpp
2829

2930
LINK_LIBS
3031
clangTidy
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
//===----------------------------------------------------------------------===//
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+
#include "UncheckedStatusOrAccessCheck.h"
10+
#include "clang/AST/ASTContext.h"
11+
#include "clang/ASTMatchers/ASTMatchFinder.h"
12+
#include "clang/ASTMatchers/ASTMatchers.h"
13+
#include "clang/Analysis/FlowSensitive/DataflowAnalysis.h"
14+
#include "clang/Analysis/FlowSensitive/Models/UncheckedStatusOrAccessModel.h"
15+
#include "clang/Basic/SourceLocation.h"
16+
#include "llvm/ADT/SmallVector.h"
17+
#include "llvm/Support/Error.h"
18+
19+
namespace clang::tidy::abseil {
20+
using ast_matchers::MatchFinder;
21+
using dataflow::statusor_model::UncheckedStatusOrAccessModel;
22+
using dataflow::statusor_model::UncheckedStatusOrAccessDiagnoser;
23+
24+
static constexpr llvm::StringLiteral FuncID("fun");
25+
26+
void UncheckedStatusOrAccessCheck::registerMatchers(MatchFinder *Finder) {
27+
using namespace ast_matchers;
28+
if (!getLangOpts().CPlusPlus) return;
29+
30+
auto has_statusor_call_descendant =
31+
hasDescendant(callExpr(callee(cxxMethodDecl(ofClass(hasAnyName(
32+
"absl::StatusOr", "absl::internal_statusor::OperatorBase"))))));
33+
Finder->addMatcher(functionDecl(unless(isExpansionInSystemHeader()),
34+
hasBody(has_statusor_call_descendant))
35+
.bind(FuncID),
36+
this);
37+
Finder->addMatcher(
38+
cxxConstructorDecl(hasAnyConstructorInitializer(
39+
withInitializer(has_statusor_call_descendant)))
40+
.bind(FuncID),
41+
this);
42+
}
43+
void UncheckedStatusOrAccessCheck::check(
44+
const MatchFinder::MatchResult &Result) {
45+
if (Result.SourceManager->getDiagnostics().hasUncompilableErrorOccurred())
46+
return;
47+
48+
const auto *FuncDecl = Result.Nodes.getNodeAs<FunctionDecl>(FuncID);
49+
if (FuncDecl->isTemplated())
50+
return;
51+
52+
UncheckedStatusOrAccessDiagnoser Diagnoser;
53+
if (llvm::Expected<llvm::SmallVector<SourceLocation>> Locs =
54+
dataflow::diagnoseFunction<
55+
UncheckedStatusOrAccessModel,
56+
SourceLocation>(*FuncDecl, *Result.Context, Diagnoser))
57+
for (const SourceLocation& Loc : *Locs)
58+
diag(Loc, "unchecked access to 'absl::StatusOr' value");
59+
else
60+
llvm::consumeError(Locs.takeError());
61+
}
62+
63+
} // namespace clang::tidy::abseil
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#ifndef DEVTOOLS_CYMBAL_CLANG_TIDY_RUNTIME_UPSTREAM_FRAMEWORK_UNCHECKED_STATUSOR_ACCESS_H_
2+
#define DEVTOOLS_CYMBAL_CLANG_TIDY_RUNTIME_UPSTREAM_FRAMEWORK_UNCHECKED_STATUSOR_ACCESS_H_
3+
4+
#include <optional>
5+
6+
#include "../ClangTidyCheck.h"
7+
#include "clang/ASTMatchers/ASTMatchFinder.h"
8+
9+
namespace clang::tidy::abseil {
10+
11+
// Warns when the code is unwrapping an absl::StatusOr<T> object without
12+
// assuring that it contains a value.
13+
//
14+
// For details on the dataflow analysis implemented in this check see:
15+
// http://google3/devtools/cymbal/nullability/statusor
16+
class UncheckedStatusOrAccessCheck : public ClangTidyCheck {
17+
public:
18+
using ClangTidyCheck::ClangTidyCheck;
19+
void registerMatchers(ast_matchers::MatchFinder* Finder) override;
20+
void check(const ast_matchers::MatchFinder::MatchResult& Result) override;
21+
};
22+
23+
} // namespace clang::abseil
24+
25+
#endif // DEVTOOLS_CYMBAL_CLANG_TIDY_RUNTIME_UPSTREAM_FRAMEWORK_UNCHECKED_STATUSOR_ACCESS_H_

clang/include/clang/Analysis/FlowSensitive/Models/UncheckedStatusOrAccessModel.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "clang/ASTMatchers/ASTMatchers.h"
1414
#include "clang/Analysis/CFG.h"
1515
#include "clang/Analysis/FlowSensitive/CFGMatchSwitch.h"
16+
#include "clang/Analysis/FlowSensitive/CachedConstAccessorsLattice.h"
1617
#include "clang/Analysis/FlowSensitive/DataflowAnalysis.h"
1718
#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
1819
#include "clang/Analysis/FlowSensitive/MatchSwitch.h"
@@ -69,7 +70,8 @@ struct UncheckedStatusOrAccessModelOptions {};
6970

7071
// Dataflow analysis that discovers unsafe uses of StatusOr values.
7172
class UncheckedStatusOrAccessModel
72-
: public DataflowAnalysis<UncheckedStatusOrAccessModel, NoopLattice> {
73+
: public DataflowAnalysis<UncheckedStatusOrAccessModel,
74+
CachedConstAccessorsLattice<NoopLattice>> {
7375
public:
7476
explicit UncheckedStatusOrAccessModel(ASTContext &Ctx, Environment &Env);
7577

0 commit comments

Comments
 (0)