[clang] [Clang][OpenMP] Validate prefer_type fr()/attr() arguments in append_args clause (PR #212307)

Zahira Ammarguellat via cfe-commits cfe-commits at lists.llvm.org
Wed Jul 29 07:32:57 PDT 2026


================
@@ -7842,6 +7842,47 @@ SemaOpenMP::checkOpenMPDeclareVariantFunction(SemaOpenMP::DeclGroupPtrTy DG,
   return std::make_pair(FD, cast<Expr>(DRE));
 }
 
+/// Check prefer_type fr()/attr() arguments in an OMPInteropInfo for validity.
+/// Returns true if all arguments are valid; emits a diagnostic and returns
+/// false on the first invalid argument.
+static bool checkPreferTypeArgs(SemaOpenMP &S, const OMPInteropInfo &Info) {
+  for (const OMPInteropPref &P : Info.Prefs) {
+    const Expr *E = P.Fr;
+    if (!E) {
+      assert(Info.HasPreferAttrs && "null Fr requires OMP 6.0 syntax");
+    } else if (!E->isValueDependent() && !E->isTypeDependent() &&
+               !E->isInstantiationDependent() &&
+               !E->containsUnexpandedParameterPack()) {
+      if (!E->isIntegerConstantExpr(S.getASTContext()) &&
+          !isa<StringLiteral>(E)) {
+        S.Diag(E->getExprLoc(), diag::err_omp_interop_prefer_type);
+        return false;
+      }
+    }
+    for (const Expr *A : P.Attrs) {
+      if (A->isValueDependent() || A->isTypeDependent() ||
+          A->isInstantiationDependent() || A->containsUnexpandedParameterPack())
+        continue;
+      const auto *SL = dyn_cast<StringLiteral>(A);
+      if (!SL) {
+        S.Diag(A->getExprLoc(), diag::err_omp_interop_attr_not_string);
+        return false;
+      }
+      if (!SL->getString().starts_with("ompx_")) {
+        S.Diag(A->getExprLoc(), diag::err_omp_interop_attr_missing_ompx_prefix)
+            << SL->getString();
+        return false;
+      }
+      if (SL->getString().contains(',')) {
+        S.Diag(A->getExprLoc(), diag::err_omp_interop_attr_contains_comma)
+            << SL->getString();
+        return false;
+      }
+    }
+  }
+  return true;
+}
----------------
zahiraam wrote:

Something like this?

```suggestion
static bool checkPreferTypeArgs(SemaOpenMP &S, const OMPInteropInfo &Info) {                                                                                                                                 
    auto isDependent = [](const Expr *E) {
      return E->isValueDependent() || E->isTypeDependent() ||                                                                                                                                                  
             E->isInstantiationDependent() || E->containsUnexpandedParameterPack();                                                                                                                            
    };                                                                                                                                                                                                        
    for (const OMPInteropPref &P : Info.Prefs) {                                                                                                                                                               
      const Expr *E = P.Fr;
      if (!E) {
        assert(Info.HasPreferAttrs && "null Fr requires OMP 6.0 syntax");
      } else if (!isDependent(E)) {
        if (!E->isIntegerConstantExpr(S.getASTContext()) &&
            !isa<StringLiteral>(E)) {
          S.Diag(E->getExprLoc(), diag::err_omp_interop_prefer_type);
          return false;
        }
      }
      for (const Expr *A : P.Attrs) {
        if (isDependent(A))
          continue;
        const auto *SL = dyn_cast<StringLiteral>(A);
        if (!SL) {
          S.Diag(A->getExprLoc(), diag::err_omp_interop_attr_not_string);                                                                                                                                      
          return false;                                                                                                                                                                                        
        }                                                                                                                                                                                                   
        StringRef Str = SL->getString();                                                                                                                                                                       
        if (!Str.starts_with("ompx_")) {                                                                                                                                                                       
          S.Diag(A->getExprLoc(), diag::err_omp_interop_attr_missing_ompx_prefix)                                                                                                                              
              << Str;                                                                                                                                                                                          
          return false;                                                                                                                                                                                        
        }                                                                                                                                                                                                      
        if (Str.contains(',')) {                                                                                                                                                                               
          S.Diag(A->getExprLoc(), diag::err_omp_interop_attr_contains_comma)                                                                                                                                   
              << Str;                                                                                                                                                                                          
          return false;                                                                                                                                                                                        
        }                                                                                                                                                                                                      
      }           
    }                                                                                                                                                                                                          
    return true;  
  }
```

https://github.com/llvm/llvm-project/pull/212307


More information about the cfe-commits mailing list