1515// ===----------------------------------------------------------------------===//
1616
1717#include " CHERIUtils.h"
18- #include " clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
1918#include " clang/AST/StmtVisitor.h"
2019#include " clang/ASTMatchers/ASTMatchFinder.h"
20+ #include " clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
2121#include " clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
2222#include " clang/StaticAnalyzer/Core/Checker.h"
2323#include " clang/StaticAnalyzer/Core/CheckerManager.h"
@@ -44,12 +44,14 @@ class SubObjectRepresentabilityChecker
4444 BugReporter &BR) const ;
4545};
4646
47- }
47+ } // namespace
4848
4949namespace {
5050
51- std::unique_ptr<BasicBugReport> reportExposedFields (const FieldDecl *D, ASTContext &ASTCtx, BugReporter &BR,
52- uint64_t Base, uint64_t Top, std::unique_ptr<BasicBugReport> Report) {
51+ std::unique_ptr<BasicBugReport>
52+ reportExposedFields (const FieldDecl *D, ASTContext &ASTCtx, BugReporter &BR,
53+ uint64_t Base, uint64_t Top,
54+ std::unique_ptr<BasicBugReport> Report) {
5355 const RecordDecl *Parent = D->getParent ();
5456 auto FI = Parent->field_begin ();
5557 while (FI != Parent->field_end () &&
@@ -86,23 +88,28 @@ std::unique_ptr<BasicBugReport> reportExposedFields(const FieldDecl *D, ASTConte
8688}
8789
8890#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);
91+ template <typename Handler>
92+ typename Handler::cap_t getBoundedCap(uint64_t ParentSize, uint64_t Offset,
93+ uint64_t Size) {
94+ typename Handler::addr_t InitLength =
95+ Handler::representable_length(ParentSize);
96+ typename Handler::cap_t MockCap =
97+ Handler::make_max_perms_cap(0, Offset , InitLength);
98+ bool exact = Handler::setbounds(&MockCap, Size);
9799 assert(!exact);
98100 return MockCap;
99101}
100102#endif
101103
102- } // namespace
104+ template <typename Handler>
105+ uint64_t getRepresentableAlignment (uint64_t Size) {
106+ return ~Handler::representable_mask (Size) + 1 ;
107+ }
103108
104- std::unique_ptr<BugReport> checkField (const FieldDecl *D, AnalysisManager &mgr,
105- BugReporter &BR, const BugType &BT) {
109+ template <llvm::CompressedCapability::CapabilityFormat Handler>
110+ std::unique_ptr<BugReport> checkFieldImpl (const FieldDecl *D,
111+ BugReporter &BR,
112+ const BugType &BT) {
106113 QualType T = D->getType ();
107114
108115 ASTContext &ASTCtx = BR.getContext ();
@@ -125,17 +132,15 @@ std::unique_ptr<BugReport> checkField(const FieldDecl *D, AnalysisManager &mgr,
125132 OS << " field offset is " << Offset;
126133 OS << " (aligned to " << CurAlign << " );" ;
127134
128- /*
129- * Print current bounds
130- * TODO: use cheri_compressed_cap correctly
131- *
135+ #if 0
132136 const RecordDecl *Parent = D->getParent();
133137 uint64_t ParentSize = ASTCtx.getTypeSize(Parent->getTypeForDecl()) / 8;
134- auto MockCap = getBoundedCap(ParentSize, Offset, Size);
138+ typename Handler::cap_t MockCap =
139+ getBoundedCap<Handler>(ParentSize, Offset, Size);
135140 uint64_t Base = MockCap.base();
136141 uint64_t Top = MockCap.top();
137142 OS << " Current bounds: " << Base << "-" << Top;
138- */
143+ # endif
139144
140145 // Note that this will fire for every translation unit that uses this
141146 // class. This is suboptimal, but at least scan-build will merge
@@ -146,11 +151,9 @@ std::unique_ptr<BugReport> checkField(const FieldDecl *D, AnalysisManager &mgr,
146151 Report->setDeclWithIssue (D);
147152 Report->addRange (D->getSourceRange ());
148153
149- /*
150- * Add exposed fields as notes
151- * TODO: use cheri_compressed_cap correctly
154+ #if 0
152155 Report = reportExposedFields(D, ASTCtx, BR, Base, Top, std::move(Report));
153- */
156+ # endif
154157
155158 return Report;
156159 }
@@ -159,10 +162,29 @@ std::unique_ptr<BugReport> checkField(const FieldDecl *D, AnalysisManager &mgr,
159162 return nullptr ;
160163}
161164
165+ std::unique_ptr<BugReport> checkField (const FieldDecl *D,
166+ BugReporter &BR,
167+ const BugType &BT) {
168+ // TODO: other targets
169+ return checkFieldImpl<llvm::CompressedCapability::Cheri128>(D, BR, BT);
170+ }
171+
172+ bool supportedTarget (const ASTContext &C) {
173+ const TargetInfo &TI = C.getTargetInfo ();
174+ return TI.areAllPointersCapabilities ()
175+ && TI.getTriple ().isAArch64 (); // morello
176+ }
177+
178+ } // namespace
179+
180+
162181void SubObjectRepresentabilityChecker::checkASTDecl (const RecordDecl *R,
163182 AnalysisManager &mgr,
164183 BugReporter &BR) const {
165- if (!R->isCompleteDefinition ())
184+ if (!supportedTarget (mgr.getASTContext ()))
185+ return ;
186+
187+ if (!R->isCompleteDefinition () || R->isDependentType ())
166188 return ;
167189
168190 if (!R->getLocation ().isValid ())
@@ -177,16 +199,19 @@ void SubObjectRepresentabilityChecker::checkASTDecl(const RecordDecl *R,
177199 */
178200
179201 for (FieldDecl *D : R->fields ()) {
180- auto Report = checkField (D, mgr, BR, BT_1);
202+ auto Report = checkField (D, BR, BT_1);
181203 if (Report)
182204 BR.emitReport (std::move (Report));
183205 }
184206}
185207
186- void SubObjectRepresentabilityChecker::checkASTCodeBody (const Decl *D, AnalysisManager &mgr,
187- BugReporter &BR) const {
188- using namespace ast_matchers ;
208+ void SubObjectRepresentabilityChecker::checkASTCodeBody (const Decl *D,
209+ AnalysisManager &mgr,
210+ BugReporter &BR) const {
211+ if (!supportedTarget (mgr.getASTContext ()))
212+ return ;
189213
214+ using namespace ast_matchers ;
190215 auto Member = memberExpr ().bind (" member" );
191216 auto Decay =
192217 castExpr (hasCastKind (CK_ArrayToPointerDecay), has (Member)).bind (" decay" );
@@ -202,7 +227,7 @@ void SubObjectRepresentabilityChecker::checkASTCodeBody(const Decl *D, AnalysisM
202227 if (const MemberExpr *ME = Match.getNodeAs <MemberExpr>(" member" )) {
203228 ValueDecl *VD = ME->getMemberDecl ();
204229 if (FieldDecl *FD = dyn_cast<FieldDecl>(VD)) {
205- auto Report = checkField (FD, mgr, BR, BT_2);
230+ auto Report = checkField (FD, BR, BT_2);
206231 if (Report) {
207232 PathDiagnosticLocation LN = PathDiagnosticLocation::createBegin (
208233 CE, BR.getSourceManager (), mgr.getAnalysisDeclContext (D));
@@ -216,7 +241,7 @@ void SubObjectRepresentabilityChecker::checkASTCodeBody(const Decl *D, AnalysisM
216241 if (const MemberExpr *ME = Match.getNodeAs <MemberExpr>(" member" )) {
217242 ValueDecl *VD = ME->getMemberDecl ();
218243 if (FieldDecl *FD = dyn_cast<FieldDecl>(VD)) {
219- auto Report = checkField (FD, mgr, BR, BT_2);
244+ auto Report = checkField (FD, BR, BT_2);
220245 if (Report) {
221246 PathDiagnosticLocation LN = PathDiagnosticLocation::createBegin (
222247 UO, BR.getSourceManager (), mgr.getAnalysisDeclContext (D));
0 commit comments