Skip to content

Commit 4461d77

Browse files
committed
Improve error message for clangsa safepoint error
1 parent 58fb3ad commit 4461d77

File tree

1 file changed

+44
-4
lines changed

1 file changed

+44
-4
lines changed

src/clangsa/GCChecker.cpp

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ class GCChecker
199199
static bool isGCTracked(const Expr *E);
200200
bool isGloballyRootedType(QualType Type) const;
201201
static void dumpState(const ProgramStateRef &State);
202-
static bool declHasAnnotation(const clang::Decl *D, const char *which);
202+
static const AnnotateAttr *declHasAnnotation(const clang::Decl *D, const char *which);
203203
static bool isFDAnnotatedNotSafepoint(const clang::FunctionDecl *FD, const SourceManager &SM);
204204
static const SourceManager &getSM(CheckerContext &C) { return C.getSourceManager(); }
205205
bool isSafepoint(const CallEvent &Call, CheckerContext &C) const;
@@ -251,6 +251,18 @@ class GCChecker
251251
PDP VisitNode(const ExplodedNode *N, BugReporterContext &BRC, PathSensitiveBugReport &BR) override;
252252
};
253253

254+
class SafepointBugVisitor : public BugReporterVisitor {
255+
public:
256+
SafepointBugVisitor() {}
257+
258+
void Profile(llvm::FoldingSetNodeID &ID) const override {
259+
static int X = 0;
260+
ID.AddPointer(&X);
261+
}
262+
263+
PDP VisitNode(const ExplodedNode *N, BugReporterContext &BRC, PathSensitiveBugReport &BR) override;
264+
};
265+
254266
class GCValueBugVisitor : public BugReporterVisitor {
255267
protected:
256268
SymbolRef Sym;
@@ -364,6 +376,33 @@ PDP GCChecker::GCBugVisitor::VisitNode(const ExplodedNode *N,
364376
return nullptr;
365377
}
366378

379+
PDP GCChecker::SafepointBugVisitor::VisitNode(const ExplodedNode *N,
380+
BugReporterContext &BRC, PathSensitiveBugReport &BR) {
381+
const ExplodedNode *PrevN = N->getFirstPred();
382+
unsigned NewSafepointDisabled = N->getState()->get<SafepointDisabledAt>();
383+
unsigned OldSafepointDisabled = PrevN->getState()->get<SafepointDisabledAt>();
384+
if (NewSafepointDisabled != OldSafepointDisabled) {
385+
const Decl *D = &N->getCodeDecl();
386+
const AnnotateAttr *Ann = declHasAnnotation(D, "julia_not_safepoint");
387+
PathDiagnosticLocation Pos;
388+
if (OldSafepointDisabled == (unsigned)-1) {
389+
if (Ann) {
390+
Pos = PathDiagnosticLocation{Ann->getLoc(), BRC.getSourceManager()};
391+
return MakePDP(Pos, "Tracking JL_NOT_SAFEPOINT annotation here.");
392+
} else {
393+
PathDiagnosticLocation Pos = PathDiagnosticLocation::createDeclBegin(
394+
N->getLocationContext(), BRC.getSourceManager());
395+
return MakePDP(Pos, "Tracking JL_NOT_SAFEPOINT annotation here.");
396+
}
397+
} else if (NewSafepointDisabled == (unsigned)-1) {
398+
PathDiagnosticLocation Pos = PathDiagnosticLocation::createDeclBegin(
399+
N->getLocationContext(), BRC.getSourceManager());
400+
return MakePDP(Pos, "Safepoints re-enabled here");
401+
}
402+
}
403+
return nullptr;
404+
}
405+
367406
PDP GCChecker::GCValueBugVisitor::ExplainNoPropagationFromExpr(
368407
const clang::Expr *FromWhere, const ExplodedNode *N,
369408
PathDiagnosticLocation Pos, BugReporterContext &BRC, PathSensitiveBugReport &BR) {
@@ -712,12 +751,12 @@ void GCChecker::checkEndFunction(const clang::ReturnStmt *RS,
712751
}
713752
}
714753

715-
bool GCChecker::declHasAnnotation(const clang::Decl *D, const char *which) {
754+
const AnnotateAttr *GCChecker::declHasAnnotation(const clang::Decl *D, const char *which) {
716755
for (const auto *Ann : D->specific_attrs<AnnotateAttr>()) {
717756
if (Ann->getAnnotation() == which)
718-
return true;
757+
return Ann;
719758
}
720-
return false;
759+
return nullptr;
721760
}
722761

723762
bool GCChecker::isFDAnnotatedNotSafepoint(const clang::FunctionDecl *FD, const SourceManager &SM) {
@@ -1302,6 +1341,7 @@ void GCChecker::checkPreCall(const CallEvent &Call, CheckerContext &C) const {
13021341
Report->addNote(
13031342
"Tried to call method defined here",
13041343
PathDiagnosticLocation::create(FD, C.getSourceManager()));
1344+
Report->addVisitor(make_unique<SafepointBugVisitor>());
13051345
},
13061346
C, ("Calling potential safepoint as " +
13071347
Call.getKindAsString() + " from function annotated JL_NOTSAFEPOINT").str());

0 commit comments

Comments
 (0)