llvm-project/clang/test/SemaOpenACC/routine-construct-clauses.cpp
erichkeane d47401e376 [OpenACC] Start enforcing 'device_type' clause values
Researching in prep of doing the implementation for lowering, I found
that the source of the valid identifiers list from flang is in the
frontend.  This patch adds the same list to the frontend, but does it as
a sema diagnostic, so we still parse it as an identifier/identifier-like
thing, but then diagnose it as invalid later.
2025-04-09 14:55:50 -07:00

230 lines
11 KiB
C++

// RUN: %clang_cc1 %s -fopenacc -verify
void Func();
void Func2();
#pragma acc routine(Func) worker
#pragma acc routine(Func) vector nohost
#pragma acc routine(Func) nohost seq
#pragma acc routine(Func) gang
// expected-error@+2{{OpenACC 'bind' clause cannot appear more than once on a 'routine' directive}}
// expected-note@+1{{previous clause is here}}
#pragma acc routine(Func) gang bind(a) bind(a)
// expected-error@+2{{OpenACC 'bind' clause cannot appear more than once on a 'routine' directive}}
// expected-note@+1{{previous clause is here}}
#pragma acc routine gang bind(a) bind(a)
void DupeImplName();
// Only 1 of worker, vector, seq, gang.
// expected-error@+2{{OpenACC clause 'vector' may not appear on the same construct as a 'worker' clause on a 'routine' construct}}
// expected-note@+1{{previous clause is here}}
#pragma acc routine(Func) worker vector
// expected-error@+2{{OpenACC clause 'seq' may not appear on the same construct as a 'worker' clause on a 'routine' construct}}
// expected-note@+1{{previous clause is here}}
#pragma acc routine(Func) worker seq
// expected-error@+2{{OpenACC clause 'gang' may not appear on the same construct as a 'worker' clause on a 'routine' construct}}
// expected-note@+1{{previous clause is here}}
#pragma acc routine(Func) worker gang
// expected-error@+2{{OpenACC clause 'worker' may not appear on the same construct as a 'worker' clause on a 'routine' construct}}
// expected-note@+1{{previous clause is here}}
#pragma acc routine(Func) worker worker
// expected-error@+2{{OpenACC clause 'worker' may not appear on the same construct as a 'vector' clause on a 'routine' construct}}
// expected-note@+1{{previous clause is here}}
#pragma acc routine(Func) vector worker
// expected-error@+2{{OpenACC clause 'seq' may not appear on the same construct as a 'vector' clause on a 'routine' construct}}
// expected-note@+1{{previous clause is here}}
#pragma acc routine(Func) vector seq
// expected-error@+2{{OpenACC clause 'gang' may not appear on the same construct as a 'vector' clause on a 'routine' construct}}
// expected-note@+1{{previous clause is here}}
#pragma acc routine(Func) vector gang
// expected-error@+2{{OpenACC clause 'vector' may not appear on the same construct as a 'vector' clause on a 'routine' construct}}
// expected-note@+1{{previous clause is here}}
#pragma acc routine(Func) vector vector
// expected-error@+2{{OpenACC clause 'worker' may not appear on the same construct as a 'seq' clause on a 'routine' construct}}
// expected-note@+1{{previous clause is here}}
#pragma acc routine(Func) seq worker
// expected-error@+2{{OpenACC clause 'vector' may not appear on the same construct as a 'seq' clause on a 'routine' construct}}
// expected-note@+1{{previous clause is here}}
#pragma acc routine(Func) seq vector
// expected-error@+2{{OpenACC clause 'gang' may not appear on the same construct as a 'seq' clause on a 'routine' construct}}
// expected-note@+1{{previous clause is here}}
#pragma acc routine(Func) seq gang
// expected-error@+2{{OpenACC clause 'seq' may not appear on the same construct as a 'seq' clause on a 'routine' construct}}
// expected-note@+1{{previous clause is here}}
#pragma acc routine(Func) seq seq
// expected-error@+2{{OpenACC clause 'worker' may not appear on the same construct as a 'gang' clause on a 'routine' construct}}
// expected-note@+1{{previous clause is here}}
#pragma acc routine(Func) gang worker
// expected-error@+2{{OpenACC clause 'vector' may not appear on the same construct as a 'gang' clause on a 'routine' construct}}
// expected-note@+1{{previous clause is here}}
#pragma acc routine(Func) gang vector
// expected-error@+2{{OpenACC clause 'seq' may not appear on the same construct as a 'gang' clause on a 'routine' construct}}
// expected-note@+1{{previous clause is here}}
#pragma acc routine(Func) gang seq
// expected-error@+2{{OpenACC clause 'gang' may not appear on the same construct as a 'gang' clause on a 'routine' construct}}
// expected-note@+1{{previous clause is here}}
#pragma acc routine(Func) gang gang
// expected-error@+1{{OpenACC 'routine' construct must have at least one 'gang', 'worker', 'vector' or 'seq' clause}}
#pragma acc routine(Func)
// expected-error@+1{{OpenACC 'routine' construct must have at least one 'gang', 'worker', 'vector' or 'seq' clause}}
#pragma acc routine(Func) nohost
// only the 'dim' syntax for gang is legal.
#pragma acc routine(Func) gang(dim:1)
// expected-error@+1{{'num' argument on 'gang' clause is not permitted on a 'routine' construct}}
#pragma acc routine(Func) gang(1)
// expected-error@+1{{'num' argument on 'gang' clause is not permitted on a 'routine' construct}}
#pragma acc routine(Func) gang(num:1)
// expected-error@+1{{'static' argument on 'gang' clause is not permitted on a 'routine' construct}}
#pragma acc routine(Func) gang(static:1)
// expected-error@+2{{OpenACC 'gang' clause may have at most one 'dim' argument}}
// expected-note@+1{{previous expression is here}}
#pragma acc routine(Func) gang(dim:1, dim:2)
// worker, vector, seq don't allow arguments.
// expected-error@+1{{'num' argument on 'worker' clause is not permitted on a 'routine' construct}}
#pragma acc routine(Func) worker(1)
// expected-error@+1{{'length' argument on 'vector' clause is not permitted on a 'routine' construct}}
#pragma acc routine(Func) vector(1)
// expected-error@+1{{expected identifier}}
#pragma acc routine(Func) seq(1)
int getSomeInt();
// dim must be a constant positive integer.
// expected-error@+1{{argument to 'gang' clause dimension must be a constant expression}}
#pragma acc routine(Func) gang(dim:getSomeInt())
struct HasFuncs {
static constexpr int Neg() { return -5; }
static constexpr int Zero() { return 0; }
static constexpr int One() { return 1; }
static constexpr int Two() { return 2; }
static constexpr int Three() { return 3; }
static constexpr int Four() { return 4; }
};
// 'dim' must be 1, 2, or 3.
// expected-error@+1{{argument to 'gang' clause dimension must be 1, 2, or 3: evaluated to -5}}
#pragma acc routine(Func) gang(dim:HasFuncs::Neg())
// expected-error@+1{{argument to 'gang' clause dimension must be 1, 2, or 3: evaluated to 0}}
#pragma acc routine(Func) gang(dim:HasFuncs::Zero())
#pragma acc routine(Func) gang(dim:HasFuncs::One())
#pragma acc routine(Func) gang(dim:HasFuncs::Two())
#pragma acc routine(Func) gang(dim:HasFuncs::Three())
// expected-error@+1{{argument to 'gang' clause dimension must be 1, 2, or 3: evaluated to 4}}
#pragma acc routine(Func) gang(dim:HasFuncs::Four())
template<typename T>
struct DependentT {
// expected-error@+1{{argument to 'gang' clause dimension must be 1, 2, or 3: evaluated to -5}}
#pragma acc routine(Func) gang(dim:T::Neg())
// expected-error@+1{{argument to 'gang' clause dimension must be 1, 2, or 3: evaluated to 0}}
#pragma acc routine(Func) gang(dim:T::Zero()) nohost
#pragma acc routine(Func) nohost gang(dim:T::One())
#pragma acc routine(Func) gang(dim:T::Two())
#pragma acc routine(Func) gang(dim:T::Three())
// expected-error@+1{{argument to 'gang' clause dimension must be 1, 2, or 3: evaluated to 4}}
#pragma acc routine(Func) gang(dim:T::Four())
void MemFunc();
// expected-error@+1{{argument to 'gang' clause dimension must be 1, 2, or 3: evaluated to 4}}
#pragma acc routine(MemFunc) gang(dim:T::Four())
// expected-error@+1{{argument to 'gang' clause dimension must be 1, 2, or 3: evaluated to 4}}
#pragma acc routine gang(dim:T::Four())
void MemFunc2();
};
void Inst() {
DependentT<HasFuncs> T;// expected-note{{in instantiation of}}
}
#pragma acc routine(Func) gang device_type(host)
#pragma acc routine(Func) gang dtype(multicore)
#pragma acc routine(Func) device_type(*) worker
#pragma acc routine(Func) dtype(*) worker
#pragma acc routine(Func) dtype(*) gang
#pragma acc routine(Func) device_type(*) worker
#pragma acc routine(Func) device_type(*) vector
#pragma acc routine(Func) dtype(*) seq
#pragma acc routine(Func2) seq device_type(*) bind("asdf")
void Func6();
#pragma acc routine(Func6) seq device_type(*) bind(WhateverElse)
#pragma acc routine(Func) seq dtype(*) device_type(*)
// expected-error@+2{{OpenACC clause 'nohost' may not follow a 'dtype' clause in a 'routine' construct}}
// expected-note@+1{{previous clause is here}}
#pragma acc routine(Func) seq dtype(*) nohost
// expected-error@+2{{OpenACC clause 'nohost' may not follow a 'device_type' clause in a 'routine' construct}}
// expected-note@+1{{previous clause is here}}
#pragma acc routine(Func) seq device_type(*) nohost
// 2.15: a bind clause may not bind to a routine name that has a visible bind clause.
void Func3();
#pragma acc routine(Func3) seq bind("asdf")
// OK: Doesn't have a bind
#pragma acc routine(Func3) seq
// expected-error@+2{{multiple 'routine' directives with 'bind' clauses are not permitted to refer to the same function}}
// expected-note@-4{{previous clause is here}}
#pragma acc routine(Func3) seq bind("asdf")
void Func4();
// OK: Doesn't have a bind
#pragma acc routine(Func4) seq
#pragma acc routine(Func4) seq bind("asdf")
// expected-error@+2{{multiple 'routine' directives with 'bind' clauses are not permitted to refer to the same function}}
// expected-note@-2{{previous clause is here}}
#pragma acc routine(Func4) seq bind("asdf")
void Func5();
#pragma acc routine(Func5) seq bind("asdf")
// expected-error@+2{{multiple 'routine' directives with 'bind' clauses are not permitted to refer to the same function}}
// expected-note@-2{{previous clause is here}}
#pragma acc routine(Func5) seq bind("asdf")
// OK: Doesn't have a bind
#pragma acc routine(Func5) seq
// OK, same.
#pragma acc routine bind("asdf") seq
void DupeBinds1();
#pragma acc routine bind("asdf") seq
void DupeBinds1();
#pragma acc routine bind(asdf) seq
void DupeBinds2();
#pragma acc routine bind(asdf) seq
void DupeBinds2();
#pragma acc routine bind("asdf") seq
void DupeBinds3();
// expected-error@+2{{OpenACC 'bind' clause on a declaration must bind to the same name as previous bind clauses}}
// expected-note@-3{{previous clause is here}}
#pragma acc routine bind(asdf) seq
void DupeBinds3();
void DupeBinds4();
#pragma acc routine(DupeBinds4) bind(asdf) seq
// expected-error@+2{{multiple 'routine' directives with 'bind' clauses are not permitted to refer to the same function}}
// expected-note@-2{{previous clause is here}}
#pragma acc routine bind(asdf) seq
void DupeBinds4();
void DupeBinds4b();
// expected-error@+1{{expected function or lambda declaration for 'routine' construct}}
#pragma acc routine bind(asdf) seq
#pragma acc routine(DupeBinds4b) bind(asdf) seq
void DupeBinds4b();
#pragma acc routine bind(asdf) seq
void DupeBinds5();
// expected-error@+2{{OpenACC 'bind' clause on a declaration must bind to the same name as previous bind clauses}}
// expected-note@-3{{previous clause is here}}
#pragma acc routine bind(asdfDiff) seq
void DupeBinds5();
#pragma acc routine bind("asdf") seq
void DupeBinds6();
// expected-error@+2{{OpenACC 'bind' clause on a declaration must bind to the same name as previous bind clauses}}
// expected-note@-3{{previous clause is here}}
#pragma acc routine bind("asdfDiff") seq
void DupeBinds6();