Skip to content

Commit 6f3d59f

Browse files
fatfat123-archvgvassilev
authored andcommitted
Fix false positive checkpoint-loop pragma in nested blocks (issue #1799)
1 parent 21fc1a3 commit 6f3d59f

2 files changed

Lines changed: 96 additions & 14 deletions

File tree

test/Regressions/issue-1799.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// RUN: %cladclang -std=c++20 -I%S/../../include %s -o %t
2+
// RUN: %t | %filecheck_exec %s
3+
#include <cmath>
4+
#include <iostream>
5+
6+
#include "clad/Differentiator/Differentiator.h"
7+
8+
double gauss_shifted_mean(double* params, const double* obs) {
9+
double x[] = {obs[0], params[0] - params[1], params[2]};
10+
const double arg = x[0] - x[1];
11+
const double sig = x[2];
12+
return std::exp(-0.5 * arg * arg / (sig * sig));
13+
}
14+
15+
double gaussian_numeric_int(double* params) {
16+
double output = 0.0;
17+
double t6[1];
18+
{
19+
const int n = 100;
20+
const double d = 4 - -4;
21+
const double eps = d / n;
22+
#pragma clad checkpoint loop
23+
for (int i = 0; i < n; ++i) {
24+
t6[0] = -4 + eps * i;
25+
const double tmpA = gauss_shifted_mean(params, t6);
26+
t6[0] = -4 + eps * (i + 1);
27+
const double tmpB = gauss_shifted_mean(params, t6);
28+
output += (tmpA + tmpB) * 0.5 * eps;
29+
}
30+
}
31+
return output;
32+
}
33+
34+
double gauss_point(double* params, double x) {
35+
double obs[1] = {x};
36+
return gauss_shifted_mean(params, obs);
37+
}
38+
39+
double gaussian_numeric_int_no_braces(double* params) {
40+
double output = 0.0;
41+
const int n = 16;
42+
const double eps = (4 - -4) / static_cast<double>(n);
43+
#pragma clad checkpoint loop
44+
for (int i = 0; i < n; ++i)
45+
output += gauss_point(params, -4 + eps * i);
46+
return output;
47+
}
48+
49+
#pragma clad ON
50+
void gradient_request() {
51+
clad::gradient(gaussian_numeric_int, "params");
52+
clad::gradient(gaussian_numeric_int_no_braces, "params");
53+
}
54+
#pragma clad OFF
55+
56+
int main() {
57+
gradient_request();
58+
std::cout << "ok\n";
59+
// CHECK-EXEC: ok
60+
return 0;
61+
}

tools/ClangPlugin.cpp

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -239,24 +239,45 @@ void InitTimers();
239239
}
240240
}
241241

242-
static SourceLocation getAttachedLoopLoc(const FunctionDecl* FD,
243-
SourceLocation pragmaLoc,
244-
SourceManager& SM) {
245-
const auto* body = cast<CompoundStmt>(FD->getBody());
242+
class AttachedLoopStmtFinder
243+
: public RecursiveASTVisitor<AttachedLoopStmtFinder> {
244+
SourceLocation m_PragmaLoc;
245+
SourceManager& m_SM;
246+
Stmt* m_AttachedStmt = nullptr;
247+
SourceLocation m_AttachedLoopLoc;
246248

247-
const Stmt* nextStmt = nullptr;
248-
for (const Stmt* S : body->body()) {
249+
public:
250+
AttachedLoopStmtFinder(SourceLocation pragmaLoc, SourceManager& SM)
251+
: m_PragmaLoc(pragmaLoc), m_SM(SM) {}
252+
253+
bool VisitStmt(Stmt* S) {
249254
SourceLocation beginLoc = S->getBeginLoc();
250-
if (!SM.isBeforeInTranslationUnit(pragmaLoc, beginLoc))
251-
continue;
252-
nextStmt = S;
253-
break;
255+
if (!beginLoc.isValid() ||
256+
!m_SM.isBeforeInTranslationUnit(m_PragmaLoc, beginLoc))
257+
return true;
258+
259+
if (!m_AttachedStmt || m_SM.isBeforeInTranslationUnit(
260+
beginLoc, m_AttachedStmt->getBeginLoc())) {
261+
m_AttachedStmt = S;
262+
m_AttachedLoopLoc = {};
263+
if (isa<ForStmt>(S) || isa<WhileStmt>(S) || isa<DoStmt>(S))
264+
m_AttachedLoopLoc = beginLoc;
265+
}
266+
return true;
267+
}
268+
269+
[[nodiscard]] SourceLocation getAttachedLoopLoc() const {
270+
return m_AttachedLoopLoc;
254271
}
272+
};
255273

256-
if (nextStmt && (isa<ForStmt>(nextStmt) || isa<WhileStmt>(nextStmt) ||
257-
isa<DoStmt>(nextStmt)))
258-
return nextStmt->getBeginLoc();
259-
return {};
274+
static SourceLocation getAttachedLoopLoc(const FunctionDecl* FD,
275+
SourceLocation pragmaLoc,
276+
SourceManager& SM) {
277+
Stmt* body = FD->getBody();
278+
AttachedLoopStmtFinder finder(pragmaLoc, SM);
279+
finder.TraverseStmt(body);
280+
return finder.getAttachedLoopLoc();
260281
}
261282

262283
static void addCladLoopCheckpoints(ASTContext& C, DiffRequest& request) {

0 commit comments

Comments
 (0)