================
@@ -7938,46 +7986,107 @@ void SemaOpenMP::ActOnOpenMPDeclareVariantDirective(
}
}
- // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions]
- // Each argument can only appear in a single adjust_args clause for each
- // declare variant directive.
- llvm::SmallPtrSet<const VarDecl *, 4> AdjustVars;
+ // OpenMP 6.0 [5.2.1]: each parameter list item may be specified only once
+ // per directive. The subject is the item, so a range is exempt and a name
+ // does not collide with a position that resolves to the same parameter.
+ llvm::SmallPtrSet<const VarDecl *, 4> AdjustVars; // named items
+ llvm::SmallSet<uint64_t, 4> AdjustPositions; // literal positional items
- for (Expr *E : AllAdjustArgs) {
- E = E->IgnoreParenImpCasts();
- if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
- if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
- const VarDecl *CanonPVD = PVD->getCanonicalDecl();
- if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
- FD->getParamDecl(PVD->getFunctionScopeIndex())
- ->getCanonicalDecl() == CanonPVD) {
- // It's a parameter of the function, check duplicates.
- if (!AdjustVars.insert(CanonPVD).second) {
- Diag(DRE->getLocation(), diag::err_omp_adjust_arg_multiple_clauses)
- << PVD;
+ for (const OMPAdjustArgsClause &Clause : AdjustArgs) {
+ for (const OMPAdjustArgsItem &ItemInfo : Clause.Items) {
+ // OpenMP 6.0 [5.2.1]: a parameter range 'lb:ub'. A range is
+ // exempt from the duplicate restriction above — it is one item
+ // identifying one or more parameters — so nothing is recorded for
+ // dedup.
+ if (ItemInfo.Kind == OMPAdjustArgsItem::Range) {
+ if (!checkOMPAdjustArgsRange(*this, ItemInfo))
+ return;
+ continue;
+ }
+
+ assert(ItemInfo.E && "expected an adjust_args expression");
+ Expr *Item = ItemInfo.E->IgnoreParenImpCasts();
+
+ // A named parameter list item — unchanged from OpenMP 5.1.
+ if (const auto *DRE = dyn_cast<DeclRefExpr>(Item)) {
+ if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
+ const VarDecl *CanonPVD = PVD->getCanonicalDecl();
+ if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
+ FD->getParamDecl(PVD->getFunctionScopeIndex())
+ ->getCanonicalDecl() == CanonPVD) {
+ if (!AdjustVars.insert(CanonPVD).second) {
+ Diag(DRE->getLocation(),
+ diag::err_omp_adjust_arg_multiple_clauses)
+ << PVD;
+ return;
+ }
+ continue;
+ }
+ }
+ }
+
+ if (getLangOpts().OpenMP < 60) {
+ // Anything that is not a function parameter is an error before 6.0.
+ Diag(Item->getExprLoc(), diag::err_omp_param_or_this_in_clause)
+ << FD << 0;
+ return;
+ }
+
+ // OpenMP 6.0 [5.2.1]: the position of a parameter, given as a
+ // positive constant integer expression. A dependent item is skipped
+ // here and rechecked when the template is instantiated.
+ if (Item->getType()->isIntegerType()) {
----------------
alexey-bataev wrote:
```suggestion
if (Item->isTypeDependent() || Item->getType()->isIntegerType()) {
```
https://github.com/llvm/llvm-project/pull/225081
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits