Skip to content

Commit d70431a

Browse files
committed
[𝘀𝗽𝗿] initial version
Created using spr 1.3.7
2 parents 01c0cb9 + 8649ed1 commit d70431a

File tree

10 files changed

+3952
-1
lines changed

10 files changed

+3952
-1
lines changed
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
//===- UncheckedStatusOrAccessModel.h -------------------------------------===//
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+
#ifndef CLANG_ANALYSIS_FLOWSENSITIVE_MODELS_UNCHECKEDSTATUSORACCESSMODEL_H
10+
#define CLANG_ANALYSIS_FLOWSENSITIVE_MODELS_UNCHECKEDSTATUSORACCESSMODEL_H
11+
12+
#include "clang/AST/Type.h"
13+
#include "clang/ASTMatchers/ASTMatchers.h"
14+
#include "clang/Analysis/CFG.h"
15+
#include "clang/Analysis/FlowSensitive/CFGMatchSwitch.h"
16+
#include "clang/Analysis/FlowSensitive/DataflowAnalysis.h"
17+
#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
18+
#include "clang/Analysis/FlowSensitive/MatchSwitch.h"
19+
#include "clang/Analysis/FlowSensitive/NoopLattice.h"
20+
#include "clang/Analysis/FlowSensitive/StorageLocation.h"
21+
#include "clang/Analysis/FlowSensitive/Value.h"
22+
#include "clang/Basic/SourceLocation.h"
23+
#include "llvm/ADT/SmallVector.h"
24+
#include "llvm/ADT/StringMap.h"
25+
#include "llvm/ADT/StringRef.h"
26+
27+
namespace clang::dataflow::statusor_model {
28+
29+
// The helper functions exported here are for use of downstream vendor
30+
// extensions of this model.
31+
32+
// Match declaration of `absl::StatusOr<T>` and bind `T` to "T".
33+
clang::ast_matchers::DeclarationMatcher statusOrClass();
34+
// Match declaration of `absl::Status`.
35+
clang::ast_matchers::DeclarationMatcher statusClass();
36+
// Match declaration of `absl::internal_statusor::OperatorBase`.
37+
clang::ast_matchers::DeclarationMatcher statusOrOperatorBaseClass();
38+
clang::ast_matchers::TypeMatcher possiblyAliasedStatusType();
39+
clang::ast_matchers::TypeMatcher possiblyAliasedStatusOrType();
40+
clang::ast_matchers::TypeMatcher statusOrType();
41+
42+
// Get RecordStorageLocation for the `Status` contained in the `StatusOr`
43+
RecordStorageLocation &locForStatus(RecordStorageLocation &StatusOrLoc);
44+
// Get the StorageLocation for the OK boolean in the `Status`
45+
StorageLocation &locForOk(RecordStorageLocation &StatusLoc);
46+
// Get the OK boolean in the `Status`, and initialize it if necessary.
47+
BoolValue &valForOk(RecordStorageLocation &StatusLoc, Environment &Env);
48+
// Get synthetic fields for the types modelled by
49+
// `UncheckedStatusOrAccessModel`.
50+
llvm::StringMap<QualType> getSyntheticFields(QualType Ty, QualType StatusType,
51+
const CXXRecordDecl &RD);
52+
53+
// Initialize the synthetic fields of the `StatusOr`.
54+
// N.B. if it is already initialized, the value gets reset.
55+
BoolValue &initializeStatusOr(RecordStorageLocation &StatusOrLoc,
56+
Environment &Env);
57+
// Initialize the synthetic fields of the `Status`.
58+
// N.B. if it is already initialized, the value gets reset.
59+
BoolValue &initializeStatus(RecordStorageLocation &StatusLoc, Environment &Env);
60+
61+
bool isRecordTypeWithName(QualType Type, llvm::StringRef TypeName);
62+
// Return true if `Type` is instantiation of `absl::StatusOr<T>`
63+
bool isStatusOrType(QualType Type);
64+
// Return true if `Type` is `absl::Status`
65+
bool isStatusType(QualType Type);
66+
67+
// Get `QualType` for `absl::Status`, or default-constructed
68+
// QualType if it does not exist.
69+
QualType findStatusType(const ASTContext &Ctx);
70+
71+
struct UncheckedStatusOrAccessModelOptions {};
72+
73+
// Dataflow analysis that discovers unsafe uses of StatusOr values.
74+
class UncheckedStatusOrAccessModel
75+
: public DataflowAnalysis<UncheckedStatusOrAccessModel, NoopLattice> {
76+
public:
77+
explicit UncheckedStatusOrAccessModel(ASTContext &Ctx, Environment &Env);
78+
79+
static Lattice initialElement() { return {}; }
80+
81+
void transfer(const CFGElement &Elt, Lattice &L, Environment &Env);
82+
83+
private:
84+
CFGMatchSwitch<TransferState<Lattice>> TransferMatchSwitch;
85+
};
86+
87+
using LatticeTransferState =
88+
TransferState<UncheckedStatusOrAccessModel::Lattice>;
89+
90+
// Extend the Builder with the transfer functions for
91+
// `UncheckedStatusOrAccessModel`. This is useful to write downstream models
92+
// that extend the model.
93+
CFGMatchSwitch<LatticeTransferState>
94+
buildTransferMatchSwitch(ASTContext &Ctx,
95+
CFGMatchSwitchBuilder<LatticeTransferState> Builder);
96+
97+
class UncheckedStatusOrAccessDiagnoser {
98+
public:
99+
explicit UncheckedStatusOrAccessDiagnoser(
100+
UncheckedStatusOrAccessModelOptions Options = {});
101+
102+
llvm::SmallVector<SourceLocation> operator()(
103+
const CFGElement &Elt, ASTContext &Ctx,
104+
const TransferStateForDiagnostics<UncheckedStatusOrAccessModel::Lattice>
105+
&State);
106+
107+
private:
108+
CFGMatchSwitch<const Environment, llvm::SmallVector<SourceLocation>>
109+
DiagnoseMatchSwitch;
110+
};
111+
112+
} // namespace clang::dataflow::statusor_model
113+
114+
#endif // CLANG_ANALYSIS_FLOWSENSITIVE_MODELS_UNCHECKEDSTATUSORACCESSMODEL_H

clang/lib/Analysis/FlowSensitive/Models/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
add_clang_library(clangAnalysisFlowSensitiveModels
22
ChromiumCheckModel.cpp
33
UncheckedOptionalAccessModel.cpp
4+
UncheckedStatusOrAccessModel.cpp
45

56
LINK_LIBS
67
clangAnalysis

0 commit comments

Comments
 (0)