[clang] [OpenACC] Fix invalid routine case where 'bind' didn't exist (PR #192270)
Erich Keane via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 15 07:52:11 PDT 2026
https://github.com/erichkeane created https://github.com/llvm/llvm-project/pull/192270
For some reason I'd failed to check the result of `find_if` and just assumed that the `bind` clause must exist! Looking through my other tests, I've validated every other combination other than this one for some reason.
Fixes: #192245
>From ace1bf3c63568344b88b2514d9cd178a35975e65 Mon Sep 17 00:00:00 2001
From: erichkeane <ekeane at nvidia.com>
Date: Wed, 15 Apr 2026 07:25:31 -0700
Subject: [PATCH] [OpenACC] Fix invalid routine case where 'bind' didn't exist
For some reason I'd failed to check the result of `find_if` and just
assumed that the `bind` clause must exist! Looking through my other
tests, I've validated every other combination other than this one for
some reason.
Fixes: #192245
---
clang/lib/Sema/SemaOpenACC.cpp | 59 ++++++++++---------
.../SemaOpenACC/routine-construct-clauses.cpp | 11 ++++
2 files changed, 42 insertions(+), 28 deletions(-)
diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp
index 30e07d7b145af..b8ffc01c753f7 100644
--- a/clang/lib/Sema/SemaOpenACC.cpp
+++ b/clang/lib/Sema/SemaOpenACC.cpp
@@ -2416,37 +2416,40 @@ void SemaOpenACC::CheckRoutineDecl(SourceLocation DirLoc,
}
auto BindItr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCBindClause>);
- for (auto *A : NextParsedFDecl->attrs()) {
- // OpenACC 3.3 2.15:
- // If a procedure has a bind clause on both the declaration and definition
- // than they both must bind to the same name.
- if (auto *RA = dyn_cast<OpenACCRoutineDeclAttr>(A)) {
- auto OtherBindItr =
- llvm::find_if(RA->Clauses, llvm::IsaPred<OpenACCBindClause>);
- if (OtherBindItr != RA->Clauses.end() &&
- (*cast<OpenACCBindClause>(*BindItr)) !=
- (*cast<OpenACCBindClause>(*OtherBindItr))) {
- Diag((*BindItr)->getBeginLoc(), diag::err_acc_duplicate_unnamed_bind);
- Diag((*OtherBindItr)->getEndLoc(), diag::note_acc_previous_clause_here)
- << (*BindItr)->getClauseKind();
- return;
+ if (BindItr != Clauses.end()) {
+ for (auto *A : NextParsedFDecl->attrs()) {
+ // OpenACC 3.3 2.15:
+ // If a procedure has a bind clause on both the declaration and definition
+ // than they both must bind to the same name.
+ if (auto *RA = dyn_cast<OpenACCRoutineDeclAttr>(A)) {
+ auto OtherBindItr =
+ llvm::find_if(RA->Clauses, llvm::IsaPred<OpenACCBindClause>);
+ if (OtherBindItr != RA->Clauses.end() &&
+ (*cast<OpenACCBindClause>(*BindItr)) !=
+ (*cast<OpenACCBindClause>(*OtherBindItr))) {
+ Diag((*BindItr)->getBeginLoc(), diag::err_acc_duplicate_unnamed_bind);
+ Diag((*OtherBindItr)->getEndLoc(),
+ diag::note_acc_previous_clause_here)
+ << (*BindItr)->getClauseKind();
+ return;
+ }
}
- }
- // OpenACC 3.3 2.15:
- // A bind clause may not bind to a routine name that has a visible bind
- // clause.
- // We take the combo of these two 2.15 restrictions to mean that the
- // 'declaration'/'definition' quote is an exception to this. So we're going
- // to disallow mixing of the two types entirely.
- if (auto *RA = dyn_cast<OpenACCRoutineAnnotAttr>(A);
- RA && RA->getRange().getEnd().isValid()) {
- Diag((*BindItr)->getBeginLoc(), diag::err_acc_duplicate_bind);
- Diag(RA->getRange().getEnd(), diag::note_acc_previous_clause_here)
- << "bind";
- return;
+ // OpenACC 3.3 2.15:
+ // A bind clause may not bind to a routine name that has a visible bind
+ // clause.
+ // We take the combo of these two 2.15 restrictions to mean that the
+ // 'declaration'/'definition' quote is an exception to this. So we're
+ // going to disallow mixing of the two types entirely.
+ if (auto *RA = dyn_cast<OpenACCRoutineAnnotAttr>(A);
+ RA && RA->getRange().getEnd().isValid()) {
+ Diag((*BindItr)->getBeginLoc(), diag::err_acc_duplicate_bind);
+ Diag(RA->getRange().getEnd(), diag::note_acc_previous_clause_here)
+ << "bind";
+ return;
+ }
}
- }
+ }
CreateRoutineDeclAttr(*this, DirLoc, Clauses, NextParsedFDecl);
}
diff --git a/clang/test/SemaOpenACC/routine-construct-clauses.cpp b/clang/test/SemaOpenACC/routine-construct-clauses.cpp
index 91f233537e4ca..4c7152861afc1 100644
--- a/clang/test/SemaOpenACC/routine-construct-clauses.cpp
+++ b/clang/test/SemaOpenACC/routine-construct-clauses.cpp
@@ -803,3 +803,14 @@ namespace OtherDupes {
#pragma acc routine device_type(nvidia) vector device_type(acc_device_nvidia)
void Func3();
}
+
+namespace GH192245 {
+ // These are fine, but we were assuming a bind-clause during checking that
+ // didnt' exist in the Func1 case.
+#pragma acc routine seq
+#pragma acc routine seq bind("asdf")
+ void Func1();
+#pragma acc routine seq bind("asdf")
+#pragma acc routine seq
+ void Func2();
+}
More information about the cfe-commits
mailing list