[clang] 0f2afde - [OpenACC] Fix invalid routine case where 'bind' didn't exist (#192270)

via cfe-commits cfe-commits at lists.llvm.org
Wed Apr 15 08:18:45 PDT 2026


Author: Erich Keane
Date: 2026-04-15T15:18:39Z
New Revision: 0f2afde1c2276a61435e8f9909c13f6e2208b936

URL: https://github.com/llvm/llvm-project/commit/0f2afde1c2276a61435e8f9909c13f6e2208b936
DIFF: https://github.com/llvm/llvm-project/commit/0f2afde1c2276a61435e8f9909c13f6e2208b936.diff

LOG: [OpenACC] Fix invalid routine case where 'bind' didn't exist (#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

Added: 
    

Modified: 
    clang/lib/Sema/SemaOpenACC.cpp
    clang/test/SemaOpenACC/routine-construct-clauses.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp
index 30e07d7b145af..28c46dcccc9ea 100644
--- a/clang/lib/Sema/SemaOpenACC.cpp
+++ b/clang/lib/Sema/SemaOpenACC.cpp
@@ -2416,35 +2416,38 @@ 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;
+      }
     }
   }
 

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