Skip to content

Commit b4a0869

Browse files
eupharinaresistor
authored andcommitted
[CHERI_CSA] SubObjectRepresentability: enable notes with updated cheri-compressed-cap
1 parent 0527a21 commit b4a0869

File tree

2 files changed

+51
-33
lines changed

2 files changed

+51
-33
lines changed

clang/lib/StaticAnalyzer/Checkers/CHERI/SubObjectRepresentabilityChecker.cpp

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -86,23 +86,26 @@ reportExposedFields(const FieldDecl *D, ASTContext &ASTCtx, BugReporter &BR,
8686
}
8787

8888
#if 0
89-
// FIXME: CC_MORELLO is not set in cheri_compressed_cap
90-
// FIXME: other targets
91-
using Handler = CompressedCap128;
92-
Handler::cap_t getBoundedCap(uint64_t ParentSize, uint64_t Offset,
93-
uint64_t Size) {
94-
Handler::addr_t InitLength = Handler ::representable_length(ParentSize);
95-
Handler::cap_t MockCap = Handler::make_max_perms_cap(0, 0, InitLength);
96-
bool exact = Handler::setbounds(&MockCap, Offset, Offset + Size);
89+
template <typename Handler>
90+
typename Handler::cap_t getBoundedCap(uint64_t ParentSize, uint64_t Offset,
91+
uint64_t Size) {
92+
typename Handler::addr_t InitLength =
93+
Handler::representable_length(ParentSize);
94+
typename Handler::cap_t MockCap =
95+
Handler::make_max_perms_cap(0, Offset, InitLength);
96+
bool exact = Handler::setbounds(&MockCap, Size);
9797
assert(!exact);
9898
return MockCap;
9999
}
100100
#endif
101101

102-
} // namespace
102+
template <typename Handler> uint64_t getRepresentableAlignment(uint64_t Size) {
103+
return ~Handler::representable_mask(Size) + 1;
104+
}
103105

104-
std::unique_ptr<BugReport> checkField(const FieldDecl *D, AnalysisManager &mgr,
105-
BugReporter &BR, const BugType &BT) {
106+
template <llvm::CompressedCapability::CapabilityFormat Handler>
107+
std::unique_ptr<BugReport> checkFieldImpl(const FieldDecl *D, BugReporter &BR,
108+
const BugType &BT) {
106109
QualType T = D->getType();
107110

108111
ASTContext &ASTCtx = BR.getContext();
@@ -126,17 +129,15 @@ std::unique_ptr<BugReport> checkField(const FieldDecl *D, AnalysisManager &mgr,
126129
OS << " field offset is " << Offset;
127130
OS << " (aligned to " << CurAlign << ");";
128131

129-
/*
130-
* Print current bounds
131-
* TODO: use cheri_compressed_cap correctly
132-
*
132+
#if 0
133133
const RecordDecl *Parent = D->getParent();
134134
uint64_t ParentSize = ASTCtx.getTypeSize(Parent->getTypeForDecl()) / 8;
135-
auto MockCap = getBoundedCap(ParentSize, Offset, Size);
135+
typename Handler::cap_t MockCap =
136+
getBoundedCap<Handler>(ParentSize, Offset, Size);
136137
uint64_t Base = MockCap.base();
137138
uint64_t Top = MockCap.top();
138139
OS << " Current bounds: " << Base << "-" << Top;
139-
*/
140+
#endif
140141

141142
// Note that this will fire for every translation unit that uses this
142143
// class. This is suboptimal, but at least scan-build will merge
@@ -147,11 +148,9 @@ std::unique_ptr<BugReport> checkField(const FieldDecl *D, AnalysisManager &mgr,
147148
Report->setDeclWithIssue(D);
148149
Report->addRange(D->getSourceRange());
149150

150-
/*
151-
* Add exposed fields as notes
152-
* TODO: use cheri_compressed_cap correctly
151+
#if 0
153152
Report = reportExposedFields(D, ASTCtx, BR, Base, Top, std::move(Report));
154-
*/
153+
#endif
155154

156155
return Report;
157156
}
@@ -160,10 +159,27 @@ std::unique_ptr<BugReport> checkField(const FieldDecl *D, AnalysisManager &mgr,
160159
return nullptr;
161160
}
162161

162+
std::unique_ptr<BugReport> checkField(const FieldDecl *D, BugReporter &BR,
163+
const BugType &BT) {
164+
// TODO: other targets
165+
return checkFieldImpl<llvm::CompressedCapability::Cheri128>(D, BR, BT);
166+
}
167+
168+
bool supportedTarget(const ASTContext &C) {
169+
const TargetInfo &TI = C.getTargetInfo();
170+
return TI.areAllPointersCapabilities() &&
171+
TI.getTriple().isAArch64(); // morello
172+
}
173+
174+
} // namespace
175+
163176
void SubObjectRepresentabilityChecker::checkASTDecl(const RecordDecl *R,
164177
AnalysisManager &mgr,
165178
BugReporter &BR) const {
166-
if (!R->isCompleteDefinition())
179+
if (!supportedTarget(mgr.getASTContext()))
180+
return;
181+
182+
if (!R->isCompleteDefinition() || R->isDependentType())
167183
return;
168184

169185
if (!R->getLocation().isValid())
@@ -178,7 +194,7 @@ void SubObjectRepresentabilityChecker::checkASTDecl(const RecordDecl *R,
178194
*/
179195

180196
for (FieldDecl *D : R->fields()) {
181-
auto Report = checkField(D, mgr, BR, BT_1);
197+
auto Report = checkField(D, BR, BT_1);
182198
if (Report)
183199
BR.emitReport(std::move(Report));
184200
}
@@ -187,8 +203,10 @@ void SubObjectRepresentabilityChecker::checkASTDecl(const RecordDecl *R,
187203
void SubObjectRepresentabilityChecker::checkASTCodeBody(const Decl *D,
188204
AnalysisManager &mgr,
189205
BugReporter &BR) const {
190-
using namespace ast_matchers;
206+
if (!supportedTarget(mgr.getASTContext()))
207+
return;
191208

209+
using namespace ast_matchers;
192210
auto Member = memberExpr().bind("member");
193211
auto Decay =
194212
castExpr(hasCastKind(CK_ArrayToPointerDecay), has(Member)).bind("decay");
@@ -204,7 +222,7 @@ void SubObjectRepresentabilityChecker::checkASTCodeBody(const Decl *D,
204222
if (const MemberExpr *ME = Match.getNodeAs<MemberExpr>("member")) {
205223
ValueDecl *VD = ME->getMemberDecl();
206224
if (FieldDecl *FD = dyn_cast<FieldDecl>(VD)) {
207-
auto Report = checkField(FD, mgr, BR, BT_2);
225+
auto Report = checkField(FD, BR, BT_2);
208226
if (Report) {
209227
PathDiagnosticLocation LN = PathDiagnosticLocation::createBegin(
210228
CE, BR.getSourceManager(), mgr.getAnalysisDeclContext(D));
@@ -218,7 +236,7 @@ void SubObjectRepresentabilityChecker::checkASTCodeBody(const Decl *D,
218236
if (const MemberExpr *ME = Match.getNodeAs<MemberExpr>("member")) {
219237
ValueDecl *VD = ME->getMemberDecl();
220238
if (FieldDecl *FD = dyn_cast<FieldDecl>(VD)) {
221-
auto Report = checkField(FD, mgr, BR, BT_2);
239+
auto Report = checkField(FD, BR, BT_2);
222240
if (Report) {
223241
PathDiagnosticLocation LN = PathDiagnosticLocation::createBegin(
224242
UO, BR.getSourceManager(), mgr.getAnalysisDeclContext(D));

clang/test/Analysis/Checkers/CHERI/subobject-representability-morello.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ struct R1 {
1111
char a[0x3FFF]; // no warn
1212
} f1good;
1313
struct {
14-
char c;
14+
char c; // expected-note{{}}
1515
char a[0x4000]; // expected-warning{{Field 'a' of type 'char[16384]' (size 16384) requires 8 byte alignment for precise bounds; field offset is 1}}
1616
} f2bad;
1717
struct {
@@ -27,9 +27,9 @@ struct S2 {
2727
};
2828

2929
struct R2 {
30-
char x[0x50];
31-
struct S2 s2;
32-
char c;
33-
char a[0x8000]; // expected-warning{{Field 'a' of type 'char[32768]'}}
34-
char y[32];
35-
};
30+
char x[0x50]; // expected-note{{16/80}}
31+
struct S2 s2; // expected-note{{32/32 bytes exposed (may expose capability!)}}
32+
char c; // expected-note{{1}}
33+
char a[0x20000]; // expected-warning{{Field 'a' of type 'char[131072]' (size 131072) requires 64 byte alignment for precise bounds; field offset is 113 (aligned to 1); Current bounds: 64-131200}}
34+
char y[32]; // expected-note{{15/32}}
35+
};

0 commit comments

Comments
 (0)