4 changes: 4 additions & 0 deletions clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19726,6 +19726,8 @@ Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID,
case AMDGPU::BI__builtin_amdgcn_ds_read_tr4_b64_v2i32:
case AMDGPU::BI__builtin_amdgcn_ds_read_tr8_b64_v2i32:
case AMDGPU::BI__builtin_amdgcn_ds_read_tr6_b96_v3i32:
case AMDGPU::BI__builtin_amdgcn_ds_read_tr16_b64_v4f16:
case AMDGPU::BI__builtin_amdgcn_ds_read_tr16_b64_v4bf16:
case AMDGPU::BI__builtin_amdgcn_ds_read_tr16_b64_v4i16: {
Intrinsic::ID IID;
switch (BuiltinID) {
Expand All @@ -19751,6 +19753,8 @@ Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID,
IID = Intrinsic::amdgcn_ds_read_tr6_b96;
break;
case AMDGPU::BI__builtin_amdgcn_ds_read_tr16_b64_v4i16:
case AMDGPU::BI__builtin_amdgcn_ds_read_tr16_b64_v4f16:
case AMDGPU::BI__builtin_amdgcn_ds_read_tr16_b64_v4bf16:
IID = Intrinsic::amdgcn_ds_read_tr16_b64;
break;
}
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,8 @@ static bool checkAliasedGlobal(
// mangled name.
for (const auto &[Decl, Name] : MangledDeclNames) {
if (const auto *ND = dyn_cast<NamedDecl>(Decl.getDecl())) {
if (ND->getName() == GV->getName()) {
IdentifierInfo *II = ND->getIdentifier();
if (II && II->getName() == GV->getName()) {
Diags.Report(Location, diag::note_alias_mangled_name_alternative)
<< Name
<< FixItHint::CreateReplacement(
Expand Down
40 changes: 17 additions & 23 deletions clang/lib/Sema/SemaDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11451,29 +11451,23 @@ bool Sema::CheckDeductionGuideDeclarator(Declarator &D, QualType &R,
bool MightInstantiateToSpecialization = false;
if (auto RetTST =
TSI->getTypeLoc().getAsAdjusted<TemplateSpecializationTypeLoc>()) {
const TemplateSpecializationType *TST = RetTST.getTypePtr();
while (TST && TST->isTypeAlias())
TST = TST->getAliasedType()->getAs<TemplateSpecializationType>();

if (TST) {
TemplateName SpecifiedName = TST->getTemplateName();
bool TemplateMatches = Context.hasSameTemplateName(
SpecifiedName, GuidedTemplate, /*IgnoreDeduced=*/true);

const QualifiedTemplateName *Qualifiers =
SpecifiedName.getAsQualifiedTemplateName();
assert(Qualifiers && "expected QualifiedTemplate");
bool SimplyWritten = !Qualifiers->hasTemplateKeyword() &&
Qualifiers->getQualifier() == nullptr;
if (SimplyWritten && TemplateMatches)
AcceptableReturnType = true;
else {
// This could still instantiate to the right type, unless we know it
// names the wrong class template.
auto *TD = SpecifiedName.getAsTemplateDecl();
MightInstantiateToSpecialization =
!(TD && isa<ClassTemplateDecl>(TD) && !TemplateMatches);
}
TemplateName SpecifiedName = RetTST.getTypePtr()->getTemplateName();
bool TemplateMatches = Context.hasSameTemplateName(
SpecifiedName, GuidedTemplate, /*IgnoreDeduced=*/true);

const QualifiedTemplateName *Qualifiers =
SpecifiedName.getAsQualifiedTemplateName();
assert(Qualifiers && "expected QualifiedTemplate");
bool SimplyWritten = !Qualifiers->hasTemplateKeyword() &&
Qualifiers->getQualifier() == nullptr;
if (SimplyWritten && TemplateMatches)
AcceptableReturnType = true;
else {
// This could still instantiate to the right type, unless we know it
// names the wrong class template.
auto *TD = SpecifiedName.getAsTemplateDecl();
MightInstantiateToSpecialization =
!(TD && isa<ClassTemplateDecl>(TD) && !TemplateMatches);
}
} else if (!RetTy.hasQualifiers() && RetTy->isDependentType()) {
MightInstantiateToSpecialization = true;
Expand Down
36 changes: 20 additions & 16 deletions clang/lib/Sema/SemaOpenACC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -877,10 +877,11 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitPresentClause(

OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyClause(
SemaOpenACC::OpenACCParsedClause &Clause) {
// Restrictions only properly implemented on 'compute' constructs, and
// 'compute' constructs are the only construct that can do anything with
// this yet, so skip/treat as unimplemented in this case.
if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()))
// Restrictions only properly implemented on 'compute'/'combined' constructs,
// and 'compute'/'combined' constructs are the only construct that can do
// anything with this yet, so skip/treat as unimplemented in this case.
if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()) &&
!isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind()))
return isNotImplemented();
// ActOnVar ensured that everything is a valid variable reference, so there
// really isn't anything to do here. GCC does some duplicate-finding, though
Expand All @@ -893,10 +894,11 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyClause(

OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyInClause(
SemaOpenACC::OpenACCParsedClause &Clause) {
// Restrictions only properly implemented on 'compute' constructs, and
// 'compute' constructs are the only construct that can do anything with
// this yet, so skip/treat as unimplemented in this case.
if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()))
// Restrictions only properly implemented on 'compute'/'combined' constructs,
// and 'compute'/'combined' constructs are the only construct that can do
// anything with this yet, so skip/treat as unimplemented in this case.
if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()) &&
!isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind()))
return isNotImplemented();
// ActOnVar ensured that everything is a valid variable reference, so there
// really isn't anything to do here. GCC does some duplicate-finding, though
Expand All @@ -909,10 +911,11 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyInClause(

OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyOutClause(
SemaOpenACC::OpenACCParsedClause &Clause) {
// Restrictions only properly implemented on 'compute' constructs, and
// 'compute' constructs are the only construct that can do anything with
// this yet, so skip/treat as unimplemented in this case.
if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()))
// Restrictions only properly implemented on 'compute'/'combined' constructs,
// and 'compute'/'combined' constructs are the only construct that can do
// anything with this yet, so skip/treat as unimplemented in this case.
if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()) &&
!isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind()))
return isNotImplemented();
// ActOnVar ensured that everything is a valid variable reference, so there
// really isn't anything to do here. GCC does some duplicate-finding, though
Expand All @@ -925,10 +928,11 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyOutClause(

OpenACCClause *SemaOpenACCClauseVisitor::VisitCreateClause(
SemaOpenACC::OpenACCParsedClause &Clause) {
// Restrictions only properly implemented on 'compute' constructs, and
// 'compute' constructs are the only construct that can do anything with
// this yet, so skip/treat as unimplemented in this case.
if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()))
// Restrictions only properly implemented on 'compute'/'combined' constructs,
// and 'compute'/'combined' constructs are the only construct that can do
// anything with this yet, so skip/treat as unimplemented in this case.
if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()) &&
!isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind()))
return isNotImplemented();
// ActOnVar ensured that everything is a valid variable reference, so there
// really isn't anything to do here. GCC does some duplicate-finding, though
Expand Down
11 changes: 6 additions & 5 deletions clang/lib/StaticAnalyzer/Core/CoreEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -649,14 +649,15 @@ StmtNodeBuilder::~StmtNodeBuilder() {
void BranchNodeBuilder::anchor() {}

ExplodedNode *BranchNodeBuilder::generateNode(ProgramStateRef State,
bool branch,
bool Branch,
ExplodedNode *NodePred) {
// If the branch has been marked infeasible we should not generate a node.
if (!isFeasible(branch))
const CFGBlock *Dst = Branch ? DstT : DstF;

if (!Dst)
return nullptr;

ProgramPoint Loc = BlockEdge(C.getBlock(), branch ? DstT : DstF,
NodePred->getLocationContext());
ProgramPoint Loc =
BlockEdge(C.getBlock(), Dst, NodePred->getLocationContext());
ExplodedNode *Succ = generateNodeImpl(Loc, State, NodePred);
return Succ;
}
Expand Down
37 changes: 9 additions & 28 deletions clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1647,10 +1647,8 @@ void ExprEngine::processCleanupTemporaryBranch(const CXXBindTemporaryExpr *BTE,
ProgramStateRef State = Pred->getState();
const LocationContext *LC = Pred->getLocationContext();
if (getObjectUnderConstruction(State, BTE, LC)) {
TempDtorBuilder.markInfeasible(false);
TempDtorBuilder.generateNode(State, true, Pred);
} else {
TempDtorBuilder.markInfeasible(true);
TempDtorBuilder.generateNode(State, false, Pred);
}
}
Expand Down Expand Up @@ -2770,7 +2768,6 @@ void ExprEngine::processBranch(const Stmt *Condition,
// Check for NULL conditions; e.g. "for(;;)"
if (!Condition) {
BranchNodeBuilder NullCondBldr(Pred, Dst, BldCtx, DstT, DstF);
NullCondBldr.markInfeasible(false);
NullCondBldr.generateNode(Pred->getState(), true, Pred);
return;
}
Expand All @@ -2790,40 +2787,25 @@ void ExprEngine::processBranch(const Stmt *Condition,
if (CheckersOutSet.empty())
return;

BranchNodeBuilder builder(CheckersOutSet, Dst, BldCtx, DstT, DstF);
BranchNodeBuilder Builder(CheckersOutSet, Dst, BldCtx, DstT, DstF);
for (ExplodedNode *PredN : CheckersOutSet) {
if (PredN->isSink())
continue;

ProgramStateRef PrevState = PredN->getState();

ProgramStateRef StTrue, StFalse;
ProgramStateRef StTrue = PrevState, StFalse = PrevState;
if (const auto KnownCondValueAssumption = assumeCondition(Condition, PredN))
std::tie(StTrue, StFalse) = *KnownCondValueAssumption;
else {
assert(!isa<ObjCForCollectionStmt>(Condition));
builder.generateNode(PrevState, true, PredN);
builder.generateNode(PrevState, false, PredN);
continue;
}

if (StTrue && StFalse)
assert(!isa<ObjCForCollectionStmt>(Condition));

// Process the true branch.
if (builder.isFeasible(true)) {
if (StTrue)
builder.generateNode(StTrue, true, PredN);
else
builder.markInfeasible(true);
}
if (StTrue)
Builder.generateNode(StTrue, true, PredN);

// Process the false branch.
if (builder.isFeasible(false)) {
if (StFalse)
builder.generateNode(StFalse, false, PredN);
else
builder.markInfeasible(false);
}
if (StFalse)
Builder.generateNode(StFalse, false, PredN);
}
currBldrCtx = nullptr;
}
Expand All @@ -2845,14 +2827,13 @@ void ExprEngine::processStaticInitializer(const DeclStmt *DS,
const auto *VD = cast<VarDecl>(DS->getSingleDecl());
ProgramStateRef state = Pred->getState();
bool initHasRun = state->contains<InitializedGlobalsSet>(VD);
BranchNodeBuilder builder(Pred, Dst, BuilderCtx, DstT, DstF);
BranchNodeBuilder Builder(Pred, Dst, BuilderCtx, DstT, DstF);

if (!initHasRun) {
state = state->add<InitializedGlobalsSet>(VD);
}

builder.generateNode(state, initHasRun, Pred);
builder.markInfeasible(!initHasRun);
Builder.generateNode(state, initHasRun, Pred);

currBldrCtx = nullptr;
}
Expand Down
66 changes: 66 additions & 0 deletions clang/test/AST/ByteCode/builtin-functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1064,6 +1064,72 @@ namespace ReduceMul {
static_assert(__builtin_reduce_mul((vector4ulong){~0ULL, 1, 1, 2}) == ~0ULL - 1);
}

namespace ReduceAnd {
static_assert(__builtin_reduce_and((vector4char){}) == 0);
static_assert(__builtin_reduce_and((vector4char){(char)0x11, (char)0x22, (char)0x44, (char)0x88}) == 0);
static_assert(__builtin_reduce_and((vector4short){(short)0x1111, (short)0x2222, (short)0x4444, (short)0x8888}) == 0);
static_assert(__builtin_reduce_and((vector4int){(int)0x11111111, (int)0x22222222, (int)0x44444444, (int)0x88888888}) == 0);
#if __INT_WIDTH__ == 32
static_assert(__builtin_reduce_and((vector4long){(long long)0x1111111111111111L, (long long)0x2222222222222222L, (long long)0x4444444444444444L, (long long)0x8888888888888888L}) == 0L);
static_assert(__builtin_reduce_and((vector4char){(char)-1, (char)~0x22, (char)~0x44, (char)~0x88}) == 0x11);
static_assert(__builtin_reduce_and((vector4short){(short)~0x1111, (short)-1, (short)~0x4444, (short)~0x8888}) == 0x2222);
static_assert(__builtin_reduce_and((vector4int){(int)~0x11111111, (int)~0x22222222, (int)-1, (int)~0x88888888}) == 0x44444444);
static_assert(__builtin_reduce_and((vector4long){(long long)~0x1111111111111111L, (long long)~0x2222222222222222L, (long long)~0x4444444444444444L, (long long)-1}) == 0x8888888888888888L);
static_assert(__builtin_reduce_and((vector4uint){0x11111111U, 0x22222222U, 0x44444444U, 0x88888888U}) == 0U);
static_assert(__builtin_reduce_and((vector4ulong){0x1111111111111111UL, 0x2222222222222222UL, 0x4444444444444444UL, 0x8888888888888888UL}) == 0L);
#endif
}

namespace ReduceOr {
static_assert(__builtin_reduce_or((vector4char){}) == 0);
static_assert(__builtin_reduce_or((vector4char){(char)0x11, (char)0x22, (char)0x44, (char)0x88}) == (char)0xFF);
static_assert(__builtin_reduce_or((vector4short){(short)0x1111, (short)0x2222, (short)0x4444, (short)0x8888}) == (short)0xFFFF);
static_assert(__builtin_reduce_or((vector4int){(int)0x11111111, (int)0x22222222, (int)0x44444444, (int)0x88888888}) == (int)0xFFFFFFFF);
#if __INT_WIDTH__ == 32
static_assert(__builtin_reduce_or((vector4long){(long long)0x1111111111111111L, (long long)0x2222222222222222L, (long long)0x4444444444444444L, (long long)0x8888888888888888L}) == (long long)0xFFFFFFFFFFFFFFFFL);
static_assert(__builtin_reduce_or((vector4char){(char)0, (char)0x22, (char)0x44, (char)0x88}) == ~0x11);
static_assert(__builtin_reduce_or((vector4short){(short)0x1111, (short)0, (short)0x4444, (short)0x8888}) == ~0x2222);
static_assert(__builtin_reduce_or((vector4int){(int)0x11111111, (int)0x22222222, (int)0, (int)0x88888888}) == ~0x44444444);
static_assert(__builtin_reduce_or((vector4long){(long long)0x1111111111111111L, (long long)0x2222222222222222L, (long long)0x4444444444444444L, (long long)0}) == ~0x8888888888888888L);
static_assert(__builtin_reduce_or((vector4uint){0x11111111U, 0x22222222U, 0x44444444U, 0x88888888U}) == 0xFFFFFFFFU);
static_assert(__builtin_reduce_or((vector4ulong){0x1111111111111111UL, 0x2222222222222222UL, 0x4444444444444444UL, 0x8888888888888888UL}) == 0xFFFFFFFFFFFFFFFFL);
#endif
}

namespace ReduceXor {
static_assert(__builtin_reduce_xor((vector4char){}) == 0);
static_assert(__builtin_reduce_xor((vector4char){(char)0x11, (char)0x22, (char)0x44, (char)0x88}) == (char)0xFF);
static_assert(__builtin_reduce_xor((vector4short){(short)0x1111, (short)0x2222, (short)0x4444, (short)0x8888}) == (short)0xFFFF);
#if __INT_WIDTH__ == 32
static_assert(__builtin_reduce_xor((vector4int){(int)0x11111111, (int)0x22222222, (int)0x44444444, (int)0x88888888}) == (int)0xFFFFFFFF);
static_assert(__builtin_reduce_xor((vector4long){(long long)0x1111111111111111L, (long long)0x2222222222222222L, (long long)0x4444444444444444L, (long long)0x8888888888888888L}) == (long long)0xFFFFFFFFFFFFFFFFL);
static_assert(__builtin_reduce_xor((vector4uint){0x11111111U, 0x22222222U, 0x44444444U, 0x88888888U}) == 0xFFFFFFFFU);
static_assert(__builtin_reduce_xor((vector4ulong){0x1111111111111111UL, 0x2222222222222222UL, 0x4444444444444444UL, 0x8888888888888888UL}) == 0xFFFFFFFFFFFFFFFFUL);
#endif
}

namespace ElementwisePopcount {
static_assert(__builtin_reduce_add(__builtin_elementwise_popcount((vector4int){1, 2, 3, 4})) == 5);
#if __INT_WIDTH__ == 32
static_assert(__builtin_reduce_add(__builtin_elementwise_popcount((vector4int){0, 0xF0F0, ~0, ~0xF0F0})) == 16 * sizeof(int));
#endif
static_assert(__builtin_reduce_add(__builtin_elementwise_popcount((vector4long){1L, 2L, 3L, 4L})) == 5L);
static_assert(__builtin_reduce_add(__builtin_elementwise_popcount((vector4long){0L, 0xF0F0L, ~0L, ~0xF0F0L})) == 16 * sizeof(long long));
static_assert(__builtin_reduce_add(__builtin_elementwise_popcount((vector4uint){1U, 2U, 3U, 4U})) == 5U);
static_assert(__builtin_reduce_add(__builtin_elementwise_popcount((vector4uint){0U, 0xF0F0U, ~0U, ~0xF0F0U})) == 16 * sizeof(int));
static_assert(__builtin_reduce_add(__builtin_elementwise_popcount((vector4ulong){1UL, 2UL, 3UL, 4UL})) == 5UL);
static_assert(__builtin_reduce_add(__builtin_elementwise_popcount((vector4ulong){0ULL, 0xF0F0ULL, ~0ULL, ~0xF0F0ULL})) == 16 * sizeof(unsigned long long));
static_assert(__builtin_elementwise_popcount(0) == 0);
static_assert(__builtin_elementwise_popcount(0xF0F0) == 8);
static_assert(__builtin_elementwise_popcount(~0) == 8 * sizeof(int));
static_assert(__builtin_elementwise_popcount(0U) == 0);
static_assert(__builtin_elementwise_popcount(0xF0F0U) == 8);
static_assert(__builtin_elementwise_popcount(~0U) == 8 * sizeof(int));
static_assert(__builtin_elementwise_popcount(0L) == 0);
static_assert(__builtin_elementwise_popcount(0xF0F0L) == 8);
static_assert(__builtin_elementwise_popcount(~0LL) == 8 * sizeof(long long));
}

namespace BuiltinMemcpy {
constexpr int simple() {
int a = 12;
Expand Down
15 changes: 15 additions & 0 deletions clang/test/AST/ast-print-openacc-combined-construct.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,4 +170,19 @@ void foo() {
#pragma acc parallel loop no_create(i, array[1], array, array[1:2]) present(i, array[1], array, array[1:2])
for(int i = 0;i<5;++i);

// CHECK: #pragma acc parallel loop copy(i, array[1], array, array[1:2]) pcopy(i, array[1], array, array[1:2]) present_or_copy(i, array[1], array, array[1:2])
#pragma acc parallel loop copy(i, array[1], array, array[1:2]) pcopy(i, array[1], array, array[1:2]) present_or_copy(i, array[1], array, array[1:2])
for(int i = 0;i<5;++i);

// CHECK: #pragma acc parallel loop copyin(i, array[1], array, array[1:2]) pcopyin(readonly: i, array[1], array, array[1:2]) present_or_copyin(i, array[1], array, array[1:2])
#pragma acc parallel loop copyin(i, array[1], array, array[1:2]) pcopyin(readonly:i, array[1], array, array[1:2]) present_or_copyin(i, array[1], array, array[1:2])
for(int i = 0;i<5;++i);

// CHECK: #pragma acc parallel loop copyout(i, array[1], array, array[1:2]) pcopyout(zero: i, array[1], array, array[1:2]) present_or_copyout(i, array[1], array, array[1:2])
#pragma acc parallel loop copyout(i, array[1], array, array[1:2]) pcopyout(zero: i, array[1], array, array[1:2]) present_or_copyout(i, array[1], array, array[1:2])
for(int i = 0;i<5;++i);

// CHECK: #pragma acc parallel loop create(i, array[1], array, array[1:2]) pcreate(zero: i, array[1], array, array[1:2]) present_or_create(i, array[1], array, array[1:2])
#pragma acc parallel loop create(i, array[1], array, array[1:2]) pcreate(zero: i, array[1], array, array[1:2]) present_or_create(i, array[1], array, array[1:2])
for(int i = 0;i<5;++i);
}
10 changes: 1 addition & 9 deletions clang/test/CXX/temp/temp.deduct.guide/p3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ template<template<typename> typename TT> struct E { // expected-note 2{{template
};

A(int) -> int; // expected-error {{deduced type 'int' of deduction guide is not a specialization of template 'A'}}
template <typename T> A(T)->B<T>;
template <typename T> A(T)->B<T>; // expected-error {{deduced type 'B<T>' (aka 'A<T>') of deduction guide is not written as a specialization of template 'A'}}
template<typename T> A(T*) -> const A<T>; // expected-error {{deduced type 'const A<T>' of deduction guide is not a specialization of template 'A'}}

// A deduction-guide shall be declared in the same scope as the corresponding
Expand Down Expand Up @@ -71,11 +71,3 @@ namespace WrongScope {
Local(int) -> Local<int>; // expected-error {{expected}}
}
}

namespace GH54909 {
template <class T> struct A {};
struct B {};

template <typename T> using C = B;
template <typename T> A() -> C<T>; // expected-error {{deduced type 'C<T>' (aka 'GH54909::B') of deduction guide is not a specialization of template 'A'}}
}
3 changes: 3 additions & 0 deletions clang/test/CodeGen/alias.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ __attribute__((unused, alias("resolver"), deprecated("hahahaha, isn't C great?")
void func();
// expected-error@-2 {{alias must point to a defined variable or function}}
// expected-note@-3 {{must refer to its mangled name}}

void *operator new(unsigned long) __attribute__((alias("A"))); // expected-error {{alias must point to a defined variable or function}} \
// expected-note {{the function or variable specified in an alias must refer to its mangled name}}
#endif

// CHECK: @_ZN4libc4log2Ed ={{.*}} alias double (double), ptr @log2
Expand Down
23 changes: 23 additions & 0 deletions clang/test/CodeGenOpenCL/builtins-amdgcn-gfx950-read-tr.cl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
typedef int v2i __attribute__((ext_vector_type(2)));
typedef int v3i __attribute__((ext_vector_type(3)));
typedef short v4s __attribute__((ext_vector_type(4)));
typedef half v4h __attribute__((ext_vector_type(4)));
typedef __bf16 v4y __attribute__((ext_vector_type(4)));

// GFX950-LABEL: define dso_local <2 x i32> @test_amdgcn_ds_read_b64_tr_b4_v2i32(
// GFX950-SAME: ptr addrspace(3) nocapture noundef readonly [[INPTR:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
Expand Down Expand Up @@ -48,3 +50,24 @@ v4s test_amdgcn_ds_read_b64_tr_b16_v2i16(local v4s* inptr)
{
return __builtin_amdgcn_ds_read_tr16_b64_v4i16(inptr);
}

// GFX950-LABEL: define dso_local <4 x half> @test_amdgcn_ds_read_b64_tr_b16_v2f16(
// GFX950-SAME: ptr addrspace(3) nocapture noundef readonly [[INPTR:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
// GFX950-NEXT: entry:
// GFX950-NEXT: [[TMP0:%.*]] = tail call <4 x half> @llvm.amdgcn.ds.read.tr16.b64.v4f16(ptr addrspace(3) [[INPTR]])
// GFX950-NEXT: ret <4 x half> [[TMP0]]
//
v4h test_amdgcn_ds_read_b64_tr_b16_v2f16(local v4h* inptr)
{
return __builtin_amdgcn_ds_read_tr16_b64_v4f16(inptr);
}

// GFX950-LABEL: define dso_local <4 x bfloat> @test_amdgcn_ds_read_b64_tr_b16_v2bf16(
// GFX950-SAME: ptr addrspace(3) nocapture noundef readonly [[INPTR:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
// GFX950-NEXT: entry:
// GFX950-NEXT: [[TMP0:%.*]] = tail call <4 x bfloat> @llvm.amdgcn.ds.read.tr16.b64.v4bf16(ptr addrspace(3) [[INPTR]])
// GFX950-NEXT: ret <4 x bfloat> [[TMP0]]
v4y test_amdgcn_ds_read_b64_tr_b16_v2bf16(local v4y* inptr)
{
return __builtin_amdgcn_ds_read_tr16_b64_v4bf16(inptr);
}
240 changes: 48 additions & 192 deletions clang/test/SemaOpenACC/combined-construct-auto_seq_independent-clauses.c

Large diffs are not rendered by default.

99 changes: 99 additions & 0 deletions clang/test/SemaOpenACC/combined-construct-copy-ast.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// RUN: %clang_cc1 %s -fopenacc -Wno-openacc-deprecated-clause-alias -ast-dump | FileCheck %s

// Test this with PCH.
// RUN: %clang_cc1 %s -fopenacc -Wno-openacc-deprecated-clause-alias -emit-pch -o %t %s
// RUN: %clang_cc1 %s -fopenacc -Wno-openacc-deprecated-clause-alias -include-pch %t -ast-dump-all | FileCheck %s

#ifndef PCH_HELPER
#define PCH_HELPER

int Global;
short GlobalArray[5];
void NormalUses(float *PointerParam) {
// CHECK: FunctionDecl{{.*}}NormalUses
// CHECK: ParmVarDecl
// CHECK-NEXT: CompoundStmt

#pragma acc parallel loop copy(GlobalArray) pcopy(PointerParam[Global]) present_or_copy(Global)
for (unsigned i = 0; i < 5; ++i);
// CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
// CHECK-NEXT: copy clause
// CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]'
// CHECK-NEXT: pcopy clause
// CHECK-NEXT: ArraySubscriptExpr{{.*}}'float' lvalue
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'float *' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}}'PointerParam' 'float *'
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int'
// CHECK-NEXT: present_or_copy clause
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int'
// CHECK-NEXT: ForStmt
// CHECK:NullStmt
}

template<auto &NTTP, typename T, typename U>
void TemplUses(T t, U u) {
// CHECK-NEXT: FunctionTemplateDecl
// CHECK-NEXT: NonTypeTemplateParmDecl {{.*}}referenced 'auto &' depth 0 index 0 NTTP
// CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 1 T
// CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 2 U
// CHECK-NEXT: FunctionDecl{{.*}} TemplUses 'void (T, U)'
// CHECK-NEXT: ParmVarDecl{{.*}} referenced t 'T'
// CHECK-NEXT: ParmVarDecl{{.*}} referenced u 'U'
// CHECK-NEXT: CompoundStmt

#pragma acc parallel loop copy(t) pcopy(NTTP, u) present_or_copy(u[0:t])
for (unsigned i = 0; i < 5; ++i);
// CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
// CHECK-NEXT: copy clause
// CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T'
// CHECK-NEXT: pcopy clause
// CHECK-NEXT: DeclRefExpr{{.*}}'auto' lvalue NonTypeTemplateParm{{.*}} 'NTTP' 'auto &'
// CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
// CHECK-NEXT: present_or_copy clause
// CHECK-NEXT: ArraySectionExpr
// CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
// CHECK-NEXT: IntegerLiteral{{.*}} 'int' 0
// CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T'
// CHECK-NEXT: ForStmt
// CHECK:NullStmt

// Check the instantiated versions of the above.
// CHECK-NEXT: FunctionDecl{{.*}} used TemplUses 'void (int, int *)' implicit_instantiation
// CHECK-NEXT: TemplateArgument decl
// CHECK-NEXT: Var{{.*}} 'CEVar' 'const unsigned int'
// CHECK-NEXT: TemplateArgument type 'int'
// CHECK-NEXT: BuiltinType{{.*}} 'int'
// CHECK-NEXT: TemplateArgument type 'int *'
// CHECK-NEXT: PointerType{{.*}} 'int *'
// CHECK-NEXT: BuiltinType{{.*}} 'int'
// CHECK-NEXT: ParmVarDecl{{.*}} used t 'int'
// CHECK-NEXT: ParmVarDecl{{.*}} used u 'int *'
// CHECK-NEXT: CompoundStmt

// #pragma acc parallel copy(t) pcopy(NTTP, u) present_or_copy(u[0:t])
// CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
// CHECK-NEXT: copy clause
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int'
// CHECK-NEXT: pcopy clause
// CHECK-NEXT: SubstNonTypeTemplateParmExpr{{.*}}'const unsigned int' lvalue
// CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} referenced 'auto &' depth 0 index 0 NTTP
// CHECK-NEXT: DeclRefExpr{{.*}}'const unsigned int' lvalue Var{{.*}} 'CEVar' 'const unsigned int'
// CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *'
// CHECK-NEXT: present_or_copy clause
// CHECK-NEXT: ArraySectionExpr
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'int *' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *'
// CHECK-NEXT: IntegerLiteral{{.*}} 'int' 0
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int'
// CHECK-NEXT: ForStmt
// CHECK:NullStmt
}

void Inst() {
static constexpr unsigned CEVar = 1;
int i;
TemplUses<CEVar>(i, &i);
}
#endif
72 changes: 72 additions & 0 deletions clang/test/SemaOpenACC/combined-construct-copy-clause.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// RUN: %clang_cc1 %s -fopenacc -verify

typedef struct IsComplete {
struct S { int A; } CompositeMember;
int ScalarMember;
float ArrayMember[5];
void *PointerMember;
} Complete;
void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete CompositeParam) {
int LocalInt;
short *LocalPointer;
float LocalArray[5];
Complete LocalComposite;
// Check Appertainment:
#pragma acc parallel loop copy(LocalInt)
for(int i = 0; i < 5; ++i);
#pragma acc serial loop copy(LocalInt)
for(int i = 0; i < 5; ++i);
#pragma acc kernels loop copy(LocalInt)
for(int i = 0; i < 5; ++i);

// expected-warning@+1{{OpenACC clause name 'pcopy' is a deprecated clause name and is now an alias for 'copy'}}
#pragma acc parallel loop pcopy(LocalInt)
for(int i = 0; i < 5; ++i);

// expected-warning@+1{{OpenACC clause name 'present_or_copy' is a deprecated clause name and is now an alias for 'copy'}}
#pragma acc parallel loop present_or_copy(LocalInt)
for(int i = 0; i < 5; ++i);

// Valid cases:
#pragma acc parallel loop copy(LocalInt, LocalPointer, LocalArray)
for(int i = 0; i < 5; ++i);
#pragma acc parallel loop copy(LocalArray[2:1])
for(int i = 0; i < 5; ++i);

#pragma acc parallel loop copy(LocalComposite.ScalarMember, LocalComposite.ScalarMember)
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop copy(1 + IntParam)
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop copy(+IntParam)
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
#pragma acc parallel loop copy(PointerParam[2:])
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
#pragma acc parallel loop copy(ArrayParam[2:5])
for(int i = 0; i < 5; ++i);

// expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop copy((float*)ArrayParam[2:5])
for(int i = 0; i < 5; ++i);
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop copy((float)ArrayParam[2])
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC 'copy' clause is not valid on 'loop' directive}}
#pragma acc loop copy(LocalInt)
for(int i = 5; i < 10;++i);
// expected-error@+1{{OpenACC 'pcopy' clause is not valid on 'loop' directive}}
#pragma acc loop pcopy(LocalInt)
for(int i = 5; i < 10;++i);
// expected-error@+1{{OpenACC 'present_or_copy' clause is not valid on 'loop' directive}}
#pragma acc loop present_or_copy(LocalInt)
for(int i = 5; i < 10;++i);
}
112 changes: 112 additions & 0 deletions clang/test/SemaOpenACC/combined-construct-copy-clause.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// RUN: %clang_cc1 %s -fopenacc -verify

enum SomeE{};
typedef struct IsComplete {
struct S { int A; } CompositeMember;
int ScalarMember;
float ArrayMember[5];
SomeE EnumMember;
char *PointerMember;
} Complete;

void uses(int IntParam, char *PointerParam, float ArrayParam[5], Complete CompositeParam, int &IntParamRef) {
int LocalInt;
char *LocalPointer;
float LocalArray[5];
// Check Appertainment:
#pragma acc parallel loop copy(LocalInt)
for(int i = 0; i < 5; ++i);
#pragma acc serial loop copy(LocalInt)
for(int i = 0; i < 5; ++i);
#pragma acc kernels loop copy(LocalInt)
for(int i = 0; i < 5; ++i);

// Valid cases:
#pragma acc parallel loop copy(LocalInt, LocalPointer, LocalArray)
for(int i = 0; i < 5; ++i);
#pragma acc parallel loop copy(LocalArray[2:1])
for(int i = 0; i < 5; ++i);

Complete LocalComposite2;
#pragma acc parallel loop copy(LocalComposite2.ScalarMember, LocalComposite2.ScalarMember)
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop copy(1 + IntParam)
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop copy(+IntParam)
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
#pragma acc parallel loop copy(PointerParam[2:])
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
#pragma acc parallel loop copy(ArrayParam[2:5])
for(int i = 0; i < 5; ++i);

// expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop copy((float*)ArrayParam[2:5])
for(int i = 0; i < 5; ++i);
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop copy((float)ArrayParam[2])
for(int i = 0; i < 5; ++i);
}

template<typename T, unsigned I, typename V>
void TemplUses(T t, T (&arrayT)[I], V TemplComp) {
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop copy(+t)
for(int i = 0; i < 5; ++i);

// NTTP's are only valid if it is a reference to something.
// expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
// expected-note@#TEMPL_USES_INST{{in instantiation of}}
#pragma acc parallel loop copy(I)
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop copy(t, I)
for(int i = 0; i < 5; ++i);

#pragma acc parallel loop copy(arrayT)
for(int i = 0; i < 5; ++i);

#pragma acc parallel loop copy(TemplComp)
for(int i = 0; i < 5; ++i);

#pragma acc parallel loop copy(TemplComp.PointerMember[5])
for(int i = 0; i < 5; ++i);
int *Pointer;
#pragma acc parallel loop copy(Pointer[:I])
for(int i = 0; i < 5; ++i);
#pragma acc parallel loop copy(Pointer[:t])
for(int i = 0; i < 5; ++i);
// expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
#pragma acc parallel loop copy(Pointer[1:])
for(int i = 0; i < 5; ++i);
}

template<unsigned I, auto &NTTP_REF>
void NTTP() {
// NTTP's are only valid if it is a reference to something.
// expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
// expected-note@#NTTP_INST{{in instantiation of}}
#pragma acc parallel loop copy(I)
for(int i = 0; i < 5; ++i);

#pragma acc parallel loop copy(NTTP_REF)
for(int i = 0; i < 5; ++i);
}

void Inst() {
static constexpr int NTTP_REFed = 1;
int i;
int Arr[5];
Complete C;
TemplUses(i, Arr, C); // #TEMPL_USES_INST
NTTP<5, NTTP_REFed>(); // #NTTP_INST
}
99 changes: 99 additions & 0 deletions clang/test/SemaOpenACC/combined-construct-copyin-ast.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// RUN: %clang_cc1 %s -fopenacc -Wno-openacc-deprecated-clause-alias -ast-dump | FileCheck %s

// Test this with PCH.
// RUN: %clang_cc1 %s -fopenacc -Wno-openacc-deprecated-clause-alias -emit-pch -o %t %s
// RUN: %clang_cc1 %s -fopenacc -Wno-openacc-deprecated-clause-alias -include-pch %t -ast-dump-all | FileCheck %s

#ifndef PCH_HELPER
#define PCH_HELPER

int Global;
short GlobalArray[5];
void NormalUses(float *PointerParam) {
// CHECK: FunctionDecl{{.*}}NormalUses
// CHECK: ParmVarDecl
// CHECK-NEXT: CompoundStmt

#pragma acc parallel loop copyin(GlobalArray) pcopyin(readonly:PointerParam[Global]) present_or_copyin(Global)
for (unsigned i = 0; i < 5; ++i);
// CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
// CHECK-NEXT: copyin clause
// CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]'
// CHECK-NEXT: pcopyin clause : readonly
// CHECK-NEXT: ArraySubscriptExpr{{.*}}'float' lvalue
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'float *' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}}'PointerParam' 'float *'
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int'
// CHECK-NEXT: present_or_copyin clause
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int'
// CHECK-NEXT: ForStmt
// CHECK: NullStmt
}

template<auto &NTTP, typename T, typename U>
void TemplUses(T t, U u) {
// CHECK-NEXT: FunctionTemplateDecl
// CHECK-NEXT: NonTypeTemplateParmDecl {{.*}}referenced 'auto &' depth 0 index 0 NTTP
// CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 1 T
// CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 2 U
// CHECK-NEXT: FunctionDecl{{.*}} TemplUses 'void (T, U)'
// CHECK-NEXT: ParmVarDecl{{.*}} referenced t 'T'
// CHECK-NEXT: ParmVarDecl{{.*}} referenced u 'U'
// CHECK-NEXT: CompoundStmt

#pragma acc parallel loop copyin(t) pcopyin(readonly: NTTP, u) present_or_copyin(u[0:t])
for (unsigned i = 0; i < 5; ++i);
// CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
// CHECK-NEXT: copyin clause
// CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T'
// CHECK-NEXT: pcopyin clause : readonly
// CHECK-NEXT: DeclRefExpr{{.*}}'auto' lvalue NonTypeTemplateParm{{.*}} 'NTTP' 'auto &'
// CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
// CHECK-NEXT: present_or_copyin clause
// CHECK-NEXT: ArraySectionExpr
// CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
// CHECK-NEXT: IntegerLiteral{{.*}} 'int' 0
// CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T'
// CHECK-NEXT: ForStmt
// CHECK: NullStmt

// Check the instantiated versions of the above.
// CHECK-NEXT: FunctionDecl{{.*}} used TemplUses 'void (int, int *)' implicit_instantiation
// CHECK-NEXT: TemplateArgument decl
// CHECK-NEXT: Var{{.*}} 'CEVar' 'const unsigned int'
// CHECK-NEXT: TemplateArgument type 'int'
// CHECK-NEXT: BuiltinType{{.*}} 'int'
// CHECK-NEXT: TemplateArgument type 'int *'
// CHECK-NEXT: PointerType{{.*}} 'int *'
// CHECK-NEXT: BuiltinType{{.*}} 'int'
// CHECK-NEXT: ParmVarDecl{{.*}} used t 'int'
// CHECK-NEXT: ParmVarDecl{{.*}} used u 'int *'
// CHECK-NEXT: CompoundStmt

// #pragma acc parallel copyin(t) pcopyin(readonly: NTTP, u) present_or_copyin(u[0:t])
// CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
// CHECK-NEXT: copyin clause
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int'
// CHECK-NEXT: pcopyin clause : readonly
// CHECK-NEXT: SubstNonTypeTemplateParmExpr{{.*}}'const unsigned int' lvalue
// CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} referenced 'auto &' depth 0 index 0 NTTP
// CHECK-NEXT: DeclRefExpr{{.*}}'const unsigned int' lvalue Var{{.*}} 'CEVar' 'const unsigned int'
// CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *'
// CHECK-NEXT: present_or_copyin clause
// CHECK-NEXT: ArraySectionExpr
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'int *' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *'
// CHECK-NEXT: IntegerLiteral{{.*}} 'int' 0
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int'
// CHECK-NEXT: ForStmt
// CHECK: NullStmt
}

void Inst() {
static constexpr unsigned CEVar = 1;
int i;
TemplUses<CEVar>(i, &i);
}
#endif
78 changes: 78 additions & 0 deletions clang/test/SemaOpenACC/combined-construct-copyin-clause.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// RUN: %clang_cc1 %s -fopenacc -verify

typedef struct IsComplete {
struct S { int A; } CompositeMember;
int ScalarMember;
float ArrayMember[5];
void *PointerMember;
} Complete;
void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete CompositeParam) {
int LocalInt;
short *LocalPointer;
float LocalArray[5];
Complete LocalComposite;
// Check Appertainment:
#pragma acc parallel loop copyin(LocalInt)
for(int i = 0; i < 5; ++i);
#pragma acc serial loop copyin(LocalInt)
for(int i = 0; i < 5; ++i);
#pragma acc kernels loop copyin(LocalInt)
for(int i = 0; i < 5; ++i);

// expected-warning@+1{{OpenACC clause name 'pcopyin' is a deprecated clause name and is now an alias for 'copyin'}}
#pragma acc parallel loop pcopyin(LocalInt)
for(int i = 0; i < 5; ++i);

// expected-warning@+1{{OpenACC clause name 'present_or_copyin' is a deprecated clause name and is now an alias for 'copyin'}}
#pragma acc parallel loop present_or_copyin(LocalInt)
for(int i = 0; i < 5; ++i);

// Valid cases:
#pragma acc parallel loop copyin(LocalInt, LocalPointer, LocalArray)
for(int i = 0; i < 5; ++i);
#pragma acc parallel loop copyin(LocalArray[2:1])
for(int i = 0; i < 5; ++i);
#pragma acc parallel loop copyin(readonly:LocalArray[2:1])
for(int i = 0; i < 5; ++i);

#pragma acc parallel loop copyin(LocalComposite.ScalarMember, LocalComposite.ScalarMember)
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop copyin(1 + IntParam)
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop copyin(+IntParam)
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
#pragma acc parallel loop copyin(PointerParam[2:])
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
#pragma acc parallel loop copyin(ArrayParam[2:5])
for(int i = 0; i < 5; ++i);

// expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop copyin((float*)ArrayParam[2:5])
for(int i = 0; i < 5; ++i);
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop copyin((float)ArrayParam[2])
for(int i = 0; i < 5; ++i);
// expected-error@+2{{invalid tag 'invalid' on 'copyin' clause}}
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop copyin(invalid:(float)ArrayParam[2])
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC 'copyin' clause is not valid on 'loop' directive}}
#pragma acc loop copyin(LocalInt)
for(int i = 5; i < 10;++i);
// expected-error@+1{{OpenACC 'pcopyin' clause is not valid on 'loop' directive}}
#pragma acc loop pcopyin(LocalInt)
for(int i = 5; i < 10;++i);
// expected-error@+1{{OpenACC 'present_or_copyin' clause is not valid on 'loop' directive}}
#pragma acc loop present_or_copyin(LocalInt)
for(int i = 5; i < 10;++i);
}
112 changes: 112 additions & 0 deletions clang/test/SemaOpenACC/combined-construct-copyin-clause.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// RUN: %clang_cc1 %s -fopenacc -verify

enum SomeE{};
typedef struct IsComplete {
struct S { int A; } CompositeMember;
int ScalarMember;
float ArrayMember[5];
SomeE EnumMember;
char *PointerMember;
} Complete;

void uses(int IntParam, char *PointerParam, float ArrayParam[5], Complete CompositeParam, int &IntParamRef) {
int LocalInt;
char *LocalPointer;
float LocalArray[5];
// Check Appertainment:
#pragma acc parallel loop copyin(LocalInt)
for(int i = 0; i < 5; ++i);
#pragma acc serial loop copyin(LocalInt)
for(int i = 0; i < 5; ++i);
#pragma acc kernels loop copyin(LocalInt)
for(int i = 0; i < 5; ++i);

// Valid cases:
#pragma acc parallel loop copyin(LocalInt, LocalPointer, LocalArray)
for(int i = 0; i < 5; ++i);
#pragma acc parallel loop copyin(LocalArray[2:1])
for(int i = 0; i < 5; ++i);

Complete LocalComposite2;
#pragma acc parallel loop copyin(LocalComposite2.ScalarMember, LocalComposite2.ScalarMember)
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop copyin(1 + IntParam)
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop copyin(+IntParam)
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
#pragma acc parallel loop copyin(PointerParam[2:])
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
#pragma acc parallel loop copyin(ArrayParam[2:5])
for(int i = 0; i < 5; ++i);

// expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop copyin((float*)ArrayParam[2:5])
for(int i = 0; i < 5; ++i);
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop copyin((float)ArrayParam[2])
for(int i = 0; i < 5; ++i);
}

template<typename T, unsigned I, typename V>
void TemplUses(T t, T (&arrayT)[I], V TemplComp) {
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop copyin(+t)
for(int i = 0; i < 5; ++i);

// NTTP's are only valid if it is a reference to something.
// expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
// expected-note@#TEMPL_USES_INST{{in instantiation of}}
#pragma acc parallel loop copyin(I)
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop copyin(t, I)
for(int i = 0; i < 5; ++i);

#pragma acc parallel loop copyin(arrayT)
for(int i = 0; i < 5; ++i);

#pragma acc parallel loop copyin(TemplComp)
for(int i = 0; i < 5; ++i);

#pragma acc parallel loop copyin(TemplComp.PointerMember[5])
for(int i = 0; i < 5; ++i);
int *Pointer;
#pragma acc parallel loop copyin(Pointer[:I])
for(int i = 0; i < 5; ++i);
#pragma acc parallel loop copyin(Pointer[:t])
for(int i = 0; i < 5; ++i);
// expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
#pragma acc parallel loop copyin(Pointer[1:])
for(int i = 0; i < 5; ++i);
}

template<unsigned I, auto &NTTP_REF>
void NTTP() {
// NTTP's are only valid if it is a reference to something.
// expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
// expected-note@#NTTP_INST{{in instantiation of}}
#pragma acc parallel loop copyin(I)
for(int i = 0; i < 5; ++i);

#pragma acc parallel loop copyin(NTTP_REF)
for(int i = 0; i < 5; ++i);
}

void Inst() {
static constexpr int NTTP_REFed = 1;
int i;
int Arr[5];
Complete C;
TemplUses(i, Arr, C); // #TEMPL_USES_INST
NTTP<5, NTTP_REFed>(); // #NTTP_INST
}
99 changes: 99 additions & 0 deletions clang/test/SemaOpenACC/combined-construct-copyout-ast.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// RUN: %clang_cc1 %s -fopenacc -Wno-openacc-deprecated-clause-alias -ast-dump | FileCheck %s

// Test this with PCH.
// RUN: %clang_cc1 %s -fopenacc -Wno-openacc-deprecated-clause-alias -emit-pch -o %t %s
// RUN: %clang_cc1 %s -fopenacc -Wno-openacc-deprecated-clause-alias -include-pch %t -ast-dump-all | FileCheck %s

#ifndef PCH_HELPER
#define PCH_HELPER

int Global;
short GlobalArray[5];
void NormalUses(float *PointerParam) {
// CHECK: FunctionDecl{{.*}}NormalUses
// CHECK: ParmVarDecl
// CHECK-NEXT: CompoundStmt

#pragma acc parallel loop copyout(GlobalArray) pcopyout(zero:PointerParam[Global]) present_or_copyout(Global)
for (unsigned i = 0; i < 5; ++i);
// CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
// CHECK-NEXT: copyout clause
// CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]'
// CHECK-NEXT: pcopyout clause : zero
// CHECK-NEXT: ArraySubscriptExpr{{.*}}'float' lvalue
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'float *' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}}'PointerParam' 'float *'
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int'
// CHECK-NEXT: present_or_copyout clause
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int'
// CHECK-NEXT: For
// CHECK: NullStmt
}

template<auto &NTTP, typename T, typename U>
void TemplUses(T t, U u) {
// CHECK-NEXT: FunctionTemplateDecl
// CHECK-NEXT: NonTypeTemplateParmDecl {{.*}}referenced 'auto &' depth 0 index 0 NTTP
// CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 1 T
// CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 2 U
// CHECK-NEXT: FunctionDecl{{.*}} TemplUses 'void (T, U)'
// CHECK-NEXT: ParmVarDecl{{.*}} referenced t 'T'
// CHECK-NEXT: ParmVarDecl{{.*}} referenced u 'U'
// CHECK-NEXT: CompoundStmt

#pragma acc parallel loop copyout(t) pcopyout(zero: NTTP, u) present_or_copyout(u[0:t])
for (unsigned i = 0; i < 5; ++i);
// CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
// CHECK-NEXT: copyout clause
// CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T'
// CHECK-NEXT: pcopyout clause : zero
// CHECK-NEXT: DeclRefExpr{{.*}}'auto' lvalue NonTypeTemplateParm{{.*}} 'NTTP' 'auto &'
// CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
// CHECK-NEXT: present_or_copyout clause
// CHECK-NEXT: ArraySectionExpr
// CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
// CHECK-NEXT: IntegerLiteral{{.*}} 'int' 0
// CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T'
// CHECK-NEXT: ForStmt
// CHECK: NullStmt

// Check the instantiated versions of the above.
// CHECK-NEXT: FunctionDecl{{.*}} used TemplUses 'void (int, int *)' implicit_instantiation
// CHECK-NEXT: TemplateArgument decl
// CHECK-NEXT: Var{{.*}} 'CEVar' 'const unsigned int'
// CHECK-NEXT: TemplateArgument type 'int'
// CHECK-NEXT: BuiltinType{{.*}} 'int'
// CHECK-NEXT: TemplateArgument type 'int *'
// CHECK-NEXT: PointerType{{.*}} 'int *'
// CHECK-NEXT: BuiltinType{{.*}} 'int'
// CHECK-NEXT: ParmVarDecl{{.*}} used t 'int'
// CHECK-NEXT: ParmVarDecl{{.*}} used u 'int *'
// CHECK-NEXT: CompoundStmt

// #pragma acc parallel copyout(t) pcopyout(zero: NTTP, u) present_or_copyout(u[0:t])
// CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
// CHECK-NEXT: copyout clause
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int'
// CHECK-NEXT: pcopyout clause : zero
// CHECK-NEXT: SubstNonTypeTemplateParmExpr{{.*}}'const unsigned int' lvalue
// CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} referenced 'auto &' depth 0 index 0 NTTP
// CHECK-NEXT: DeclRefExpr{{.*}}'const unsigned int' lvalue Var{{.*}} 'CEVar' 'const unsigned int'
// CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *'
// CHECK-NEXT: present_or_copyout clause
// CHECK-NEXT: ArraySectionExpr
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'int *' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *'
// CHECK-NEXT: IntegerLiteral{{.*}} 'int' 0
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int'
// CHECK-NEXT: ForStmt
// CHECK: NullStmt
}

void Inst() {
static constexpr unsigned CEVar = 1;
int i;
TemplUses<CEVar>(i, &i);
}
#endif
78 changes: 78 additions & 0 deletions clang/test/SemaOpenACC/combined-construct-copyout-clause.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// RUN: %clang_cc1 %s -fopenacc -verify

typedef struct IsComplete {
struct S { int A; } CompositeMember;
int ScalarMember;
float ArrayMember[5];
void *PointerMember;
} Complete;
void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete CompositeParam) {
int LocalInt;
short *LocalPointer;
float LocalArray[5];
Complete LocalComposite;
// Check Appertainment:
#pragma acc parallel loop copyout(LocalInt)
for(int i = 0; i < 5; ++i);
#pragma acc serial loop copyout(LocalInt)
for(int i = 0; i < 5; ++i);
#pragma acc kernels loop copyout(LocalInt)
for(int i = 0; i < 5; ++i);

// expected-warning@+1{{OpenACC clause name 'pcopyout' is a deprecated clause name and is now an alias for 'copyout'}}
#pragma acc parallel loop pcopyout(LocalInt)
for(int i = 0; i < 5; ++i);

// expected-warning@+1{{OpenACC clause name 'present_or_copyout' is a deprecated clause name and is now an alias for 'copyout'}}
#pragma acc parallel loop present_or_copyout(LocalInt)
for(int i = 0; i < 5; ++i);

// Valid cases:
#pragma acc parallel loop copyout(LocalInt, LocalPointer, LocalArray)
for(int i = 0; i < 5; ++i);
#pragma acc parallel loop copyout(LocalArray[2:1])
for(int i = 0; i < 5; ++i);
#pragma acc parallel loop copyout(zero:LocalArray[2:1])
for(int i = 0; i < 5; ++i);

#pragma acc parallel loop copyout(LocalComposite.ScalarMember, LocalComposite.ScalarMember)
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop copyout(1 + IntParam)
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop copyout(+IntParam)
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
#pragma acc parallel loop copyout(PointerParam[2:])
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
#pragma acc parallel loop copyout(ArrayParam[2:5])
for(int i = 0; i < 5; ++i);

// expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop copyout((float*)ArrayParam[2:5])
for(int i = 0; i < 5; ++i);
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop copyout((float)ArrayParam[2])
for(int i = 0; i < 5; ++i);
// expected-error@+2{{invalid tag 'invalid' on 'copyout' clause}}
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop copyout(invalid:(float)ArrayParam[2])
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC 'copyout' clause is not valid on 'loop' directive}}
#pragma acc loop copyout(LocalInt)
for(int i = 0; i < 6;++i);
// expected-error@+1{{OpenACC 'pcopyout' clause is not valid on 'loop' directive}}
#pragma acc loop pcopyout(LocalInt)
for(int i = 0; i < 6;++i);
// expected-error@+1{{OpenACC 'present_or_copyout' clause is not valid on 'loop' directive}}
#pragma acc loop present_or_copyout(LocalInt)
for(int i = 0; i < 6;++i);
}
112 changes: 112 additions & 0 deletions clang/test/SemaOpenACC/combined-construct-copyout-clause.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// RUN: %clang_cc1 %s -fopenacc -verify

enum SomeE{};
typedef struct IsComplete {
struct S { int A; } CompositeMember;
int ScalarMember;
float ArrayMember[5];
SomeE EnumMember;
char *PointerMember;
} Complete;

void uses(int IntParam, char *PointerParam, float ArrayParam[5], Complete CompositeParam, int &IntParamRef) {
int LocalInt;
char *LocalPointer;
float LocalArray[5];
// Check Appertainment:
#pragma acc parallel loop copyout(LocalInt)
for(int i = 0; i < 5; ++i);
#pragma acc serial loop copyout(LocalInt)
for(int i = 0; i < 5; ++i);
#pragma acc kernels loop copyout(LocalInt)
for(int i = 0; i < 5; ++i);

// Valid cases:
#pragma acc parallel loop copyout(LocalInt, LocalPointer, LocalArray)
for(int i = 0; i < 5; ++i);
#pragma acc parallel loop copyout(LocalArray[2:1])
for(int i = 0; i < 5; ++i);

Complete LocalComposite2;
#pragma acc parallel loop copyout(LocalComposite2.ScalarMember, LocalComposite2.ScalarMember)
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop copyout(1 + IntParam)
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop copyout(+IntParam)
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
#pragma acc parallel loop copyout(PointerParam[2:])
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
#pragma acc parallel loop copyout(ArrayParam[2:5])
for(int i = 0; i < 5; ++i);

// expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop copyout((float*)ArrayParam[2:5])
for(int i = 0; i < 5; ++i);
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop copyout((float)ArrayParam[2])
for(int i = 0; i < 5; ++i);
}

template<typename T, unsigned I, typename V>
void TemplUses(T t, T (&arrayT)[I], V TemplComp) {
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop copyout(+t)
for(int i = 0; i < 5; ++i);

// NTTP's are only valid if it is a reference to something.
// expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
// expected-note@#TEMPL_USES_INST{{in instantiation of}}
#pragma acc parallel loop copyout(I)
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop copyout(t, I)
for(int i = 0; i < 5; ++i);

#pragma acc parallel loop copyout(arrayT)
for(int i = 0; i < 5; ++i);

#pragma acc parallel loop copyout(TemplComp)
for(int i = 0; i < 5; ++i);

#pragma acc parallel loop copyout(TemplComp.PointerMember[5])
for(int i = 0; i < 5; ++i);
int *Pointer;
#pragma acc parallel loop copyout(Pointer[:I])
for(int i = 0; i < 5; ++i);
#pragma acc parallel loop copyout(Pointer[:t])
for(int i = 0; i < 5; ++i);
// expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
#pragma acc parallel loop copyout(Pointer[1:])
for(int i = 0; i < 5; ++i);
}

template<unsigned I, auto &NTTP_REF>
void NTTP() {
// NTTP's are only valid if it is a reference to something.
// expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
// expected-note@#NTTP_INST{{in instantiation of}}
#pragma acc parallel loop copyout(I)
for(int i = 0; i < 5; ++i);

#pragma acc parallel loop copyout(NTTP_REF)
for(int i = 0; i < 5; ++i);
}

void Inst() {
static constexpr int NTTP_REFed = 1;
int i;
int Arr[5];
Complete C;
TemplUses(i, Arr, C); // #TEMPL_USES_INST
NTTP<5, NTTP_REFed>(); // #NTTP_INST
}
99 changes: 99 additions & 0 deletions clang/test/SemaOpenACC/combined-construct-create-ast.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// RUN: %clang_cc1 %s -fopenacc -Wno-openacc-deprecated-clause-alias -ast-dump | FileCheck %s

// Test this with PCH.
// RUN: %clang_cc1 %s -fopenacc -Wno-openacc-deprecated-clause-alias -emit-pch -o %t %s
// RUN: %clang_cc1 %s -fopenacc -Wno-openacc-deprecated-clause-alias -include-pch %t -ast-dump-all | FileCheck %s

#ifndef PCH_HELPER
#define PCH_HELPER

int Global;
short GlobalArray[5];
void NormalUses(float *PointerParam) {
// CHECK: FunctionDecl{{.*}}NormalUses
// CHECK: ParmVarDecl
// CHECK-NEXT: CompoundStmt

#pragma acc parallel loop create(GlobalArray) pcreate(zero:PointerParam[Global]) present_or_create(Global)
for (unsigned i = 0; i < 5; ++i);
// CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
// CHECK-NEXT: create clause
// CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]'
// CHECK-NEXT: pcreate clause : zero
// CHECK-NEXT: ArraySubscriptExpr{{.*}}'float' lvalue
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'float *' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}}'PointerParam' 'float *'
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int'
// CHECK-NEXT: present_or_create clause
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int'
// CHECK-NEXT: ForStmt
// CHECK: NullStmt
}

template<auto &NTTP, typename T, typename U>
void TemplUses(T t, U u) {
// CHECK-NEXT: FunctionTemplateDecl
// CHECK-NEXT: NonTypeTemplateParmDecl {{.*}}referenced 'auto &' depth 0 index 0 NTTP
// CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 1 T
// CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 2 U
// CHECK-NEXT: FunctionDecl{{.*}} TemplUses 'void (T, U)'
// CHECK-NEXT: ParmVarDecl{{.*}} referenced t 'T'
// CHECK-NEXT: ParmVarDecl{{.*}} referenced u 'U'
// CHECK-NEXT: CompoundStmt

#pragma acc parallel loop create(t) pcreate(zero: NTTP, u) present_or_create(u[0:t])
for (unsigned i = 0; i < 5; ++i);
// CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
// CHECK-NEXT: create clause
// CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T'
// CHECK-NEXT: pcreate clause : zero
// CHECK-NEXT: DeclRefExpr{{.*}}'auto' lvalue NonTypeTemplateParm{{.*}} 'NTTP' 'auto &'
// CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
// CHECK-NEXT: present_or_create clause
// CHECK-NEXT: ArraySectionExpr
// CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U'
// CHECK-NEXT: IntegerLiteral{{.*}} 'int' 0
// CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T'
// CHECK-NEXT: ForStmt
// CHECK: NullStmt

// Check the instantiated versions of the above.
// CHECK-NEXT: FunctionDecl{{.*}} used TemplUses 'void (int, int *)' implicit_instantiation
// CHECK-NEXT: TemplateArgument decl
// CHECK-NEXT: Var{{.*}} 'CEVar' 'const unsigned int'
// CHECK-NEXT: TemplateArgument type 'int'
// CHECK-NEXT: BuiltinType{{.*}} 'int'
// CHECK-NEXT: TemplateArgument type 'int *'
// CHECK-NEXT: PointerType{{.*}} 'int *'
// CHECK-NEXT: BuiltinType{{.*}} 'int'
// CHECK-NEXT: ParmVarDecl{{.*}} used t 'int'
// CHECK-NEXT: ParmVarDecl{{.*}} used u 'int *'
// CHECK-NEXT: CompoundStmt

// #pragma acc parallel create(t) pcreate(zero: NTTP, u) present_or_create(u[0:t])
// CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
// CHECK-NEXT: create clause
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int'
// CHECK-NEXT: pcreate clause : zero
// CHECK-NEXT: SubstNonTypeTemplateParmExpr{{.*}}'const unsigned int' lvalue
// CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} referenced 'auto &' depth 0 index 0 NTTP
// CHECK-NEXT: DeclRefExpr{{.*}}'const unsigned int' lvalue Var{{.*}} 'CEVar' 'const unsigned int'
// CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *'
// CHECK-NEXT: present_or_create clause
// CHECK-NEXT: ArraySectionExpr
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'int *' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *'
// CHECK-NEXT: IntegerLiteral{{.*}} 'int' 0
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int'
// CHECK-NEXT: ForStmt
// CHECK: NullStmt
}

void Inst() {
static constexpr unsigned CEVar = 1;
int i;
TemplUses<CEVar>(i, &i);
}
#endif
78 changes: 78 additions & 0 deletions clang/test/SemaOpenACC/combined-construct-create-clause.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// RUN: %clang_cc1 %s -fopenacc -verify

typedef struct IsComplete {
struct S { int A; } CompositeMember;
int ScalarMember;
float ArrayMember[5];
void *PointerMember;
} Complete;
void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete CompositeParam) {
int LocalInt;
short *LocalPointer;
float LocalArray[5];
Complete LocalComposite;
// Check Appertainment:
#pragma acc parallel loop create(LocalInt)
for(int i = 0; i < 5; ++i);
#pragma acc serial loop create(LocalInt)
for(int i = 0; i < 5; ++i);
#pragma acc kernels loop create(LocalInt)
for(int i = 0; i < 5; ++i);

// expected-warning@+1{{OpenACC clause name 'pcreate' is a deprecated clause name and is now an alias for 'create'}}
#pragma acc parallel loop pcreate(LocalInt)
for(int i = 0; i < 5; ++i);

// expected-warning@+1{{OpenACC clause name 'present_or_create' is a deprecated clause name and is now an alias for 'create'}}
#pragma acc parallel loop present_or_create(LocalInt)
for(int i = 0; i < 5; ++i);

// Valid cases:
#pragma acc parallel loop create(LocalInt, LocalPointer, LocalArray)
for(int i = 0; i < 5; ++i);
#pragma acc parallel loop create(LocalArray[2:1])
for(int i = 0; i < 5; ++i);
#pragma acc parallel loop create(zero:LocalArray[2:1])
for(int i = 0; i < 5; ++i);

#pragma acc parallel loop create(LocalComposite.ScalarMember, LocalComposite.ScalarMember)
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop create(1 + IntParam)
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop create(+IntParam)
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
#pragma acc parallel loop create(PointerParam[2:])
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
#pragma acc parallel loop create(ArrayParam[2:5])
for(int i = 0; i < 5; ++i);

// expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop create((float*)ArrayParam[2:5])
for(int i = 0; i < 5; ++i);
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop create((float)ArrayParam[2])
for(int i = 0; i < 5; ++i);
// expected-error@+2{{invalid tag 'invalid' on 'create' clause}}
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop create(invalid:(float)ArrayParam[2])
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC 'create' clause is not valid on 'loop' directive}}
#pragma acc loop create(LocalInt)
for(int i = 5; i < 10;++i);
// expected-error@+1{{OpenACC 'pcreate' clause is not valid on 'loop' directive}}
#pragma acc loop pcreate(LocalInt)
for(int i = 5; i < 10;++i);
// expected-error@+1{{OpenACC 'present_or_create' clause is not valid on 'loop' directive}}
#pragma acc loop present_or_create(LocalInt)
for(int i = 5; i < 10;++i);
}
113 changes: 113 additions & 0 deletions clang/test/SemaOpenACC/combined-construct-create-clause.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@

// RUN: %clang_cc1 %s -fopenacc -verify

enum SomeE{};
typedef struct IsComplete {
struct S { int A; } CompositeMember;
int ScalarMember;
float ArrayMember[5];
SomeE EnumMember;
char *PointerMember;
} Complete;

void uses(int IntParam, char *PointerParam, float ArrayParam[5], Complete CompositeParam, int &IntParamRef) {
int LocalInt;
char *LocalPointer;
float LocalArray[5];
// Check Appertainment:
#pragma acc parallel loop create(LocalInt)
for(int i = 0; i < 5; ++i);
#pragma acc serial loop create(LocalInt)
for(int i = 0; i < 5; ++i);
#pragma acc kernels loop create(LocalInt)
for(int i = 0; i < 5; ++i);

// Valid cases:
#pragma acc parallel loop create(LocalInt, LocalPointer, LocalArray)
for(int i = 0; i < 5; ++i);
#pragma acc parallel loop create(LocalArray[2:1])
for(int i = 0; i < 5; ++i);

Complete LocalComposite2;
#pragma acc parallel loop create(LocalComposite2.ScalarMember, LocalComposite2.ScalarMember)
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop create(1 + IntParam)
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop create(+IntParam)
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
#pragma acc parallel loop create(PointerParam[2:])
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
#pragma acc parallel loop create(ArrayParam[2:5])
for(int i = 0; i < 5; ++i);

// expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop create((float*)ArrayParam[2:5])
for(int i = 0; i < 5; ++i);
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop create((float)ArrayParam[2])
for(int i = 0; i < 5; ++i);
}

template<typename T, unsigned I, typename V>
void TemplUses(T t, T (&arrayT)[I], V TemplComp) {
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop create(+t)
for(int i = 0; i < 5; ++i);

// NTTP's are only valid if it is a reference to something.
// expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
// expected-note@#TEMPL_USES_INST{{in instantiation of}}
#pragma acc parallel loop create(I)
for(int i = 0; i < 5; ++i);

// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc parallel loop create(t, I)
for(int i = 0; i < 5; ++i);

#pragma acc parallel loop create(arrayT)
for(int i = 0; i < 5; ++i);

#pragma acc parallel loop create(TemplComp)
for(int i = 0; i < 5; ++i);

#pragma acc parallel loop create(TemplComp.PointerMember[5])
for(int i = 0; i < 5; ++i);
int *Pointer;
#pragma acc parallel loop create(Pointer[:I])
for(int i = 0; i < 5; ++i);
#pragma acc parallel loop create(Pointer[:t])
for(int i = 0; i < 5; ++i);
// expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
#pragma acc parallel loop create(Pointer[1:])
for(int i = 0; i < 5; ++i);
}

template<unsigned I, auto &NTTP_REF>
void NTTP() {
// NTTP's are only valid if it is a reference to something.
// expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
// expected-note@#NTTP_INST{{in instantiation of}}
#pragma acc parallel loop create(I)
for(int i = 0; i < 5; ++i);

#pragma acc parallel loop create(NTTP_REF)
for(int i = 0; i < 5; ++i);
}

void Inst() {
static constexpr int NTTP_REFed = 1;
int i;
int Arr[5];
Complete C;
TemplUses(i, Arr, C); // #TEMPL_USES_INST
NTTP<5, NTTP_REFed>(); // #NTTP_INST
}
2 changes: 0 additions & 2 deletions clang/test/SemaOpenACC/combined-construct-default-clause.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,11 @@ void SingleOnly() {

int i;

// expected-warning@+3{{OpenACC clause 'copy' not yet implemented}}
// expected-error@+2{{OpenACC 'default' clause cannot appear more than once on a 'kernels loop' directive}}
// expected-note@+1{{previous clause is here}}
#pragma acc kernels loop self default(present) present(i) default(none) copy(i)
for(int i = 5; i < 10;++i);

// expected-warning@+3{{OpenACC clause 'copy' not yet implemented}}
// expected-error@+2{{OpenACC 'default' clause cannot appear more than once on a 'parallel loop' directive}}
// expected-note@+1{{previous clause is here}}
#pragma acc parallel loop self default(present) private(i) default(none) copy(i)
Expand Down
3 changes: 0 additions & 3 deletions clang/test/SemaOpenACC/combined-construct-default-clause.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,16 @@ void SingleOnly() {
#pragma acc parallel loop default(present) async default(none)
for (unsigned I = 0; I < 5; ++I);

// expected-warning@+3{{OpenACC clause 'copy' not yet implemented, clause ignored}}
// expected-error@+2{{OpenACC 'default' clause cannot appear more than once on a 'serial loop' directive}}
// expected-note@+1{{previous clause is here}}
#pragma acc serial loop async default(present) copy(i) default(none) self
for (unsigned I = 0; I < 5; ++I);

// expected-warning@+3{{OpenACC clause 'copy' not yet implemented, clause ignored}}
// expected-error@+2{{OpenACC 'default' clause cannot appear more than once on a 'kernels loop' directive}}
// expected-note@+1{{previous clause is here}}
#pragma acc kernels loop async default(present) copy(i) default(none) self
for (unsigned I = 0; I < 5; ++I);

// expected-warning@+2{{OpenACC clause 'copy' not yet implemented, clause ignored}}
// expected-error@+1{{expected '('}}
#pragma acc parallel loop async default(none) copy(i) default self
for (unsigned I = 0; I < 5; ++I);
Expand Down
9 changes: 4 additions & 5 deletions clang/test/SemaOpenACC/compute-construct-default-clause.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,16 @@ void SingleOnly() {
#pragma acc kernels self default(present) present(i) default(none) copy(i)
while(0);

// expected-warning@+3{{OpenACC clause 'copy' not yet implemented}}
// expected-error@+2{{OpenACC 'default' clause cannot appear more than once on a 'parallel loop' directive}}
// expected-error@+2{{OpenACC 'default' clause cannot appear more than once on a 'parallel' directive}}
// expected-note@+1{{previous clause is here}}
#pragma acc parallel loop self default(present) private(i) default(none) copy(i)
#pragma acc parallel self default(present) private(i) default(none) copy(i)
for(int i = 0; i < 5; ++i);

// expected-error@+1{{expected '('}}
#pragma acc serial loop self default private(i) default(none) if(i)
#pragma acc serial self default private(i) default(none) if(i)
for(int i = 0; i < 5; ++i);

#pragma acc kernels loop default(none)
#pragma acc kernels default(none)
for(int i = 0; i < 5; ++i);

// expected-warning@+2{{OpenACC construct 'data' not yet implemented}}
Expand Down
492 changes: 233 additions & 259 deletions clang/utils/TableGen/SveEmitter.cpp

Large diffs are not rendered by default.

10 changes: 6 additions & 4 deletions compiler-rt/cmake/base-config-ix.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,15 @@ else()
set(COMPILER_RT_TEST_CXX_COMPILER ${CMAKE_CXX_COMPILER} CACHE PATH "C++ Compiler to use for testing")
endif()

if("${COMPILER_RT_TEST_COMPILER}" MATCHES "clang[+]*$")
get_filename_component(_test_compiler_name "${COMPILER_RT_TEST_COMPILER}" NAME)
if("${COMPILER_RT_TEST_COMPILER}" STREQUAL "${CMAKE_C_COMPILER}")
set(COMPILER_RT_TEST_COMPILER_ID "${CMAKE_C_COMPILER_ID}")
elseif("${_test_compiler_name}" MATCHES "clang.*")
set(COMPILER_RT_TEST_COMPILER_ID Clang)
elseif("${COMPILER_RT_TEST_COMPILER}" MATCHES "clang.*.exe$")
set(COMPILER_RT_TEST_COMPILER_ID Clang)
elseif("${COMPILER_RT_TEST_COMPILER}" MATCHES "cl.exe$")
elseif("${_test_compiler_name}" MATCHES "cl.exe$")
set(COMPILER_RT_TEST_COMPILER_ID MSVC)
else()
message(STATUS "Unknown compiler ${COMPILER_RT_TEST_COMPILER}, assuming GNU")
set(COMPILER_RT_TEST_COMPILER_ID GNU)
endif()

Expand Down
39 changes: 39 additions & 0 deletions compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -815,6 +815,43 @@ INTERCEPTOR(int, mkfifo, const char *pathname, mode_t mode) {
return REAL(mkfifo)(pathname, mode);
}

#if SANITIZER_APPLE
#define INT_TYPE_SYSCALL int
#else
#define INT_TYPE_SYSCALL long
#endif

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
INTERCEPTOR(INT_TYPE_SYSCALL, syscall, INT_TYPE_SYSCALL number, ...) {
__rtsan_notify_intercepted_call("syscall");

va_list args;
va_start(args, number);

// the goal is to pick something large enough to hold all syscall args
// see fcntl for more discussion and why we always pull all 6 args
using arg_type = unsigned long;
arg_type arg1 = va_arg(args, arg_type);
arg_type arg2 = va_arg(args, arg_type);
arg_type arg3 = va_arg(args, arg_type);
arg_type arg4 = va_arg(args, arg_type);
arg_type arg5 = va_arg(args, arg_type);
arg_type arg6 = va_arg(args, arg_type);

// these are various examples of things that COULD be passed
static_assert(sizeof(arg_type) >= sizeof(off_t));
static_assert(sizeof(arg_type) >= sizeof(struct flock *));
static_assert(sizeof(arg_type) >= sizeof(const char *));
static_assert(sizeof(arg_type) >= sizeof(int));
static_assert(sizeof(arg_type) >= sizeof(unsigned long));

va_end(args);

return REAL(syscall)(number, arg1, arg2, arg3, arg4, arg5, arg6);
}
#pragma clang diagnostic pop

// Preinit
void __rtsan::InitializeInterceptors() {
INTERCEPT_FUNCTION(calloc);
Expand Down Expand Up @@ -918,6 +955,8 @@ void __rtsan::InitializeInterceptors() {

INTERCEPT_FUNCTION(pipe);
INTERCEPT_FUNCTION(mkfifo);

INTERCEPT_FUNCTION(syscall);
}

#endif // SANITIZER_POSIX
17 changes: 17 additions & 0 deletions compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/uio.h>

Expand Down Expand Up @@ -1090,4 +1091,20 @@ TEST(TestRtsanInterceptors, PipeDiesWhenRealtime) {
ExpectNonRealtimeSurvival(Func);
}

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
TEST(TestRtsanInterceptors, SyscallDiesWhenRealtime) {
auto Func = []() { syscall(SYS_getpid); };
ExpectRealtimeDeath(Func, "syscall");
ExpectNonRealtimeSurvival(Func);
}

TEST(TestRtsanInterceptors, GetPidReturnsSame) {
int pid = syscall(SYS_getpid);
EXPECT_THAT(pid, Ne(-1));

EXPECT_THAT(getpid(), Eq(pid));
}
#pragma clang diagnostic pop

#endif // SANITIZER_POSIX
2 changes: 1 addition & 1 deletion compiler-rt/test/builtins/Unit/atomic_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ typedef uint64_t maxuint_t;

#define LEN(array) (sizeof(array) / sizeof(array[0]))

__attribute__((aligned(16))) static const char data[] = {
__attribute__((aligned(16))) static char data[] = {
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
Expand Down
23 changes: 11 additions & 12 deletions compiler-rt/test/builtins/Unit/extendhfxf2_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,59 +7,58 @@

#include "fp_test.h"

#if __LDBL_MANT_DIG__ == 64 && defined(__x86_64__) && \
defined(COMPILER_RT_HAS_FLOAT16)
#if HAS_80_BIT_LONG_DOUBLE

xf_float __extendhfxf2(TYPE_FP16 f);

int test_extendhfxf2(TYPE_FP16 a, uint64_t expectedHi, uint64_t expectedLo) {
int test_extendhfxf2(TYPE_FP16 a, uint16_t expectedHi, uint64_t expectedLo) {
xf_float x = __extendhfxf2(a);
int ret = compareResultF80(x, expectedHi, expectedLo);
if (ret) {
printf("error in test__extendhfxf2(%#.4x) = %.20Lf, "
"expected %.20Lf\n",
toRep16(a), x, F80FromRep128(expectedHi, expectedLo));
toRep16(a), x, F80FromRep80(expectedHi, expectedLo));
}
return ret;
}

int main() {
// Small positive value
if (test_extendhfxf2(fromRep16(0x2e66), UINT64_C(0x3ffb),
if (test_extendhfxf2(fromRep16(0x2e66), UINT16_C(0x3ffb),
UINT64_C(0xccc0000000000000)))
return 1;

// Small negative value
if (test_extendhfxf2(fromRep16(0xae66), UINT64_C(0xbffb),
if (test_extendhfxf2(fromRep16(0xae66), UINT16_C(0xbffb),
UINT64_C(0xccc0000000000000)))
return 1;

// Zero
if (test_extendhfxf2(fromRep16(0), UINT64_C(0x0), UINT64_C(0x0)))
if (test_extendhfxf2(fromRep16(0), UINT16_C(0x0), UINT64_C(0x0)))
return 1;

// Smallest positive non-zero value
if (test_extendhfxf2(fromRep16(0x0100), UINT64_C(0x3fef),
if (test_extendhfxf2(fromRep16(0x0100), UINT16_C(0x3fef),
UINT64_C(0x8000000000000000)))
return 1;

// Smallest negative non-zero value
if (test_extendhfxf2(fromRep16(0x8100), UINT64_C(0xbfef),
if (test_extendhfxf2(fromRep16(0x8100), UINT16_C(0xbfef),
UINT64_C(0x8000000000000000)))
return 1;

// Positive infinity
if (test_extendhfxf2(makeInf16(), UINT64_C(0x7fff),
if (test_extendhfxf2(makeInf16(), UINT16_C(0x7fff),
UINT64_C(0x8000000000000000)))
return 1;

// Negative infinity
if (test_extendhfxf2(makeNegativeInf16(), UINT64_C(0xffff),
if (test_extendhfxf2(makeNegativeInf16(), UINT16_C(0xffff),
UINT64_C(0x8000000000000000)))
return 1;

// NaN
if (test_extendhfxf2(makeQNaN16(), UINT64_C(0x7fff),
if (test_extendhfxf2(makeQNaN16(), UINT16_C(0x7fff),
UINT64_C(0xc000000000000000)))
return 1;

Expand Down
60 changes: 33 additions & 27 deletions compiler-rt/test/builtins/Unit/fp_test.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include "int_types.h"

Expand Down Expand Up @@ -230,44 +231,49 @@ static inline double makeQNaN64(void)
return fromRep64(0x7ff8000000000000UL);
}

#if __LDBL_MANT_DIG__ == 64 && defined(__x86_64__)
static inline long double F80FromRep128(uint64_t hi, uint64_t lo) {
__uint128_t x = ((__uint128_t)hi << 64) + lo;
long double ret;
memcpy(&ret, &x, 16);
return ret;
#if HAS_80_BIT_LONG_DOUBLE
static inline xf_float F80FromRep80(uint16_t hi, uint64_t lo) {
uqwords bits;
bits.high.all = hi;
bits.low.all = lo;
xf_float ret;
static_assert(sizeof(xf_float) <= sizeof(uqwords), "wrong representation");
memcpy(&ret, &bits, sizeof(ret));
return ret;
}

static inline __uint128_t F80ToRep128(long double x) {
__uint128_t ret;
memcpy(&ret, &x, 16);
return ret;
static inline uqwords F80ToRep80(xf_float x) {
uqwords ret;
memset(&ret, 0, sizeof(ret));
memcpy(&ret, &x, sizeof(x));
// Any bits beyond the first 16 in high are undefined.
ret.high.all = (uint16_t)ret.high.all;
return ret;
}

static inline int compareResultF80(long double result, uint64_t expectedHi,
static inline int compareResultF80(xf_float result, uint16_t expectedHi,
uint64_t expectedLo) {
__uint128_t rep = F80ToRep128(result);
// F80 occupies the lower 80 bits of __uint128_t.
uint64_t hi = (rep >> 64) & ((1UL << (80 - 64)) - 1);
uint64_t lo = rep;
return !(hi == expectedHi && lo == expectedLo);
uqwords rep = F80ToRep80(result);
// F80 high occupies the lower 16 bits of high.
assert((uint64_t)(uint16_t)rep.high.all == rep.high.all);
return !(rep.high.all == expectedHi && rep.low.all == expectedLo);
}

static inline long double makeQNaN80(void) {
return F80FromRep128(0x7fffUL, 0xc000000000000000UL);
static inline xf_float makeQNaN80(void) {
return F80FromRep80(0x7fffu, 0xc000000000000000UL);
}

static inline long double makeNaN80(uint64_t rand) {
return F80FromRep128(0x7fffUL,
0x8000000000000000 | (rand & 0x3fffffffffffffff));
static inline xf_float makeNaN80(uint64_t rand) {
return F80FromRep80(0x7fffu,
0x8000000000000000 | (rand & 0x3fffffffffffffff));
}

static inline long double makeInf80(void) {
return F80FromRep128(0x7fffUL, 0x8000000000000000UL);
static inline xf_float makeInf80(void) {
return F80FromRep80(0x7fffu, 0x8000000000000000UL);
}

static inline long double makeNegativeInf80(void) {
return F80FromRep128(0xffffUL, 0x8000000000000000UL);
static inline xf_float makeNegativeInf80(void) {
return F80FromRep80(0xffffu, 0x8000000000000000UL);
}
#endif

Expand Down
78 changes: 78 additions & 0 deletions compiler-rt/test/rtsan/syscall.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// RUN: %clangxx -fsanitize=realtime %s -o %t
// RUN: %env_rtsan_opts="halt_on_error=false" %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK-RTSAN,CHECK

// RUN: %clangxx %s -o %t
// RUN: %run %t 2>&1 | FileCheck %s

// UNSUPPORTED: ios

// Intent: Ensure the `syscall` call behaves in the same way with/without the
// sanitizer disabled

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>

const char *GetTemporaryFilePath() { return "/tmp/rtsan_syscall_test.txt"; }

void custom_assert(bool condition, const char *message) {
if (!condition) {
fprintf(stderr, "ASSERTION FAILED: %s\n", message);
exit(1);
}
}

class ScopedFileCleanup {
public:
[[nodiscard]] ScopedFileCleanup() = default;
~ScopedFileCleanup() {
if (access(GetTemporaryFilePath(), F_OK) != -1)
unlink(GetTemporaryFilePath());
}
};

// Apple has deprecated `syscall`, ignore that error
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
int main() [[clang::nonblocking]] {
ScopedFileCleanup cleanup;

{
int fd = syscall(SYS_openat, AT_FDCWD, GetTemporaryFilePath(),
O_CREAT | O_WRONLY, 0644);

custom_assert(fd != -1, "Failed to open file - write");

int written = syscall(SYS_write, fd, "Hello, world!", 13);
custom_assert(written == 13, "Failed to write to file");

custom_assert(syscall(SYS_close, fd) == 0, "Failed to close file - write");
}

{
int fd = syscall(SYS_openat, AT_FDCWD, GetTemporaryFilePath(), O_RDONLY);
custom_assert(fd != -1, "Failed to open file - read");

char buffer[13];
int read = syscall(SYS_read, fd, buffer, 13);
custom_assert(read == 13, "Failed to read from file");

custom_assert(memcmp(buffer, "Hello, world!", 13) == 0,
"Read data does not match written data");

custom_assert(syscall(SYS_close, fd) == 0, "Failed to close file - read");
}

unlink(GetTemporaryFilePath());
printf("DONE\n");
}
#pragma clang diagnostic pop

// CHECK-NOT: ASSERTION FAILED
// CHECK-RTSAN-COUNT-6: Intercepted call to real-time unsafe function `syscall`

// CHECK: DONE
17 changes: 9 additions & 8 deletions flang/examples/FeatureList/FeatureList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ struct NodeVisitor {
READ_FEATURE(OmpDeclareTargetWithClause)
READ_FEATURE(OmpDeclareTargetWithList)
READ_FEATURE(OmpDefaultClause)
READ_FEATURE(OmpDefaultClause::Type)
READ_FEATURE(OmpDefaultClause::DataSharingAttribute)
READ_FEATURE(OmpDefaultmapClause)
READ_FEATURE(OmpDefaultmapClause::ImplicitBehavior)
READ_FEATURE(OmpVariableCategory::Value)
Expand Down Expand Up @@ -508,25 +508,26 @@ struct NodeVisitor {
READ_FEATURE(OmpOrderModifier)
READ_FEATURE(OmpOrderModifier::Value)
READ_FEATURE(OmpProcBindClause)
READ_FEATURE(OmpProcBindClause::Type)
READ_FEATURE(OmpProcBindClause::AffinityPolicy)
READ_FEATURE(OmpReductionClause)
READ_FEATURE(OmpInReductionClause)
READ_FEATURE(OmpReductionCombiner)
READ_FEATURE(OmpReductionCombiner::FunctionCombiner)
READ_FEATURE(OmpReductionInitializerClause)
READ_FEATURE(OmpReductionIdentifier)
READ_FEATURE(OmpAllocateClause)
READ_FEATURE(OmpAllocateClause::AllocateModifier)
READ_FEATURE(OmpAllocateClause::AllocateModifier::Allocator)
READ_FEATURE(OmpAllocateClause::AllocateModifier::ComplexModifier)
READ_FEATURE(OmpAllocateClause::AllocateModifier::Align)
READ_FEATURE(OmpAllocateClause::Modifier)
READ_FEATURE(OmpAllocatorSimpleModifier)
READ_FEATURE(OmpAllocatorComplexModifier)
READ_FEATURE(OmpAlignModifier)
READ_FEATURE(OmpScheduleClause)
READ_FEATURE(OmpScheduleClause::Kind)
READ_FEATURE(OmpScheduleClause::Modifier)
READ_FEATURE(OmpDeviceModifier)
READ_FEATURE(OmpDeviceClause)
READ_FEATURE(OmpDeviceClause::DeviceModifier)
READ_FEATURE(OmpDeviceClause::Modifier)
READ_FEATURE(OmpDeviceTypeClause)
READ_FEATURE(OmpDeviceTypeClause::Type)
READ_FEATURE(OmpDeviceTypeClause::DeviceTypeDescription)
READ_FEATURE(OmpChunkModifier)
READ_FEATURE(OmpChunkModifier::Value)
READ_FEATURE(OmpOrderingModifier)
Expand Down
8 changes: 5 additions & 3 deletions flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,15 +190,17 @@ void OpenMPCounterVisitor::PostConstructsCommon() {
delete curConstruct;
}

void OpenMPCounterVisitor::Post(const OmpProcBindClause::Type &c) {
void OpenMPCounterVisitor::Post(const OmpProcBindClause::AffinityPolicy &c) {
clauseDetails +=
"type=" + std::string{OmpProcBindClause::EnumToString(c)} + ";";
}
void OpenMPCounterVisitor::Post(const OmpDefaultClause::Type &c) {
void OpenMPCounterVisitor::Post(
const OmpDefaultClause::DataSharingAttribute &c) {
clauseDetails +=
"type=" + std::string{OmpDefaultClause::EnumToString(c)} + ";";
}
void OpenMPCounterVisitor::Post(const OmpDeviceTypeClause::Type &c) {
void OpenMPCounterVisitor::Post(
const OmpDeviceTypeClause::DeviceTypeDescription &c) {
clauseDetails +=
"type=" + std::string{OmpDeviceTypeClause::EnumToString(c)} + ";";
}
Expand Down
6 changes: 3 additions & 3 deletions flang/examples/FlangOmpReport/FlangOmpReportVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,11 @@ struct OpenMPCounterVisitor {
void Post(const OpenMPConstruct &);
void PostConstructsCommon();

void Post(const OmpProcBindClause::Type &c);
void Post(const OmpDefaultClause::Type &c);
void Post(const OmpProcBindClause::AffinityPolicy &c);
void Post(const OmpDefaultClause::DataSharingAttribute &c);
void Post(const OmpDefaultmapClause::ImplicitBehavior &c);
void Post(const OmpVariableCategory::Value &c);
void Post(const OmpDeviceTypeClause::Type &c);
void Post(const OmpDeviceTypeClause::DeviceTypeDescription &c);
void Post(const OmpChunkModifier::Value &c);
void Post(const OmpLinearModifier::Value &c);
void Post(const OmpOrderingModifier::Value &c);
Expand Down
10 changes: 1 addition & 9 deletions flang/include/flang/Optimizer/CodeGen/Target.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,15 +133,7 @@ class CodeGenSpecifics {

/// Type representation of a `boxchar<n>` type argument when passed by value.
/// An argument value may need to be passed as a (safe) reference argument.
///
/// A function that returns a `boxchar<n>` type value must already have
/// converted that return value to a parameter decorated with the 'sret'
/// Attribute (https://llvm.org/docs/LangRef.html#parameter-attributes).
/// This requirement is in keeping with Fortran semantics, which require the
/// caller to allocate the space for the return CHARACTER value and pass
/// a pointer and the length of that space (a boxchar) to the called function.
virtual Marshalling boxcharArgumentType(mlir::Type eleTy,
bool sret = false) const = 0;
virtual Marshalling boxcharArgumentType(mlir::Type eleTy) const = 0;

// Compute ABI rules for an integer argument of the given mlir::IntegerType
// \p argTy. Note that this methods is supposed to be called for
Expand Down
25 changes: 16 additions & 9 deletions flang/include/flang/Parser/dump-parse-tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -484,11 +484,16 @@ class ParseTreeDumper {
NODE(parser, OmpIteratorSpecifier)
NODE(parser, OmpIterator)
NODE(parser, OmpAffinityClause)
NODE(OmpAffinityClause, Modifier)
NODE(parser, OmpAlignment)
NODE(parser, OmpAlignedClause)
NODE(OmpAlignedClause, Modifier)
NODE(parser, OmpAtomic)
NODE(parser, OmpAtomicCapture)
NODE(OmpAtomicCapture, Stmt1)
NODE(OmpAtomicCapture, Stmt2)
NODE(parser, OmpAtomicCompare)
NODE(parser, OmpAtomicCompareIfStmt)
NODE(parser, OmpAtomicRead)
NODE(parser, OmpAtomicUpdate)
NODE(parser, OmpAtomicWrite)
Expand All @@ -513,7 +518,7 @@ class ParseTreeDumper {
NODE(parser, OmpDeclareTargetWithList)
NODE(parser, OmpDeclareMapperSpecifier)
NODE(parser, OmpDefaultClause)
NODE_ENUM(OmpDefaultClause, Type)
NODE_ENUM(OmpDefaultClause, DataSharingAttribute)
NODE(parser, OmpVariableCategory)
NODE_ENUM(OmpVariableCategory, Value)
NODE(parser, OmpDefaultmapClause)
Expand Down Expand Up @@ -573,9 +578,9 @@ class ParseTreeDumper {
NODE(parser, OmpNumTasksClause)
NODE_ENUM(OmpNumTasksClause, Prescriptiveness)
NODE(parser, OmpBindClause)
NODE_ENUM(OmpBindClause, Type)
NODE_ENUM(OmpBindClause, Binding)
NODE(parser, OmpProcBindClause)
NODE_ENUM(OmpProcBindClause, Type)
NODE_ENUM(OmpProcBindClause, AffinityPolicy)
NODE(parser, OmpReductionModifier)
NODE_ENUM(OmpReductionModifier, Value)
NODE(parser, OmpReductionClause)
Expand All @@ -586,17 +591,19 @@ class ParseTreeDumper {
NODE(parser, OmpReductionInitializerClause)
NODE(parser, OmpReductionIdentifier)
NODE(parser, OmpAllocateClause)
NODE(OmpAllocateClause, AllocateModifier)
NODE(OmpAllocateClause::AllocateModifier, Allocator)
NODE(OmpAllocateClause::AllocateModifier, ComplexModifier)
NODE(OmpAllocateClause::AllocateModifier, Align)
NODE(OmpAllocateClause, Modifier)
NODE(parser, OmpAlignModifier)
NODE(parser, OmpAllocatorComplexModifier)
NODE(parser, OmpAllocatorSimpleModifier)
NODE(parser, OmpScheduleClause)
NODE(OmpScheduleClause, Modifier)
NODE_ENUM(OmpScheduleClause, Kind)
NODE(parser, OmpDeviceClause)
NODE_ENUM(OmpDeviceClause, DeviceModifier)
NODE(OmpDeviceClause, Modifier)
NODE(parser, OmpDeviceModifier)
NODE_ENUM(OmpDeviceModifier, Value)
NODE(parser, OmpDeviceTypeClause)
NODE_ENUM(OmpDeviceTypeClause, Type)
NODE_ENUM(OmpDeviceTypeClause, DeviceTypeDescription)
NODE(parser, OmpUpdateClause)
NODE(parser, OmpChunkModifier)
NODE_ENUM(OmpChunkModifier, Value)
Expand Down
Loading