[clang] 74af2ce - [OpenACC] Fix 'type' checks in private/firstprivate for array types
via cfe-commits
cfe-commits at lists.llvm.org
Tue Aug 5 08:25:39 PDT 2025
Author: erichkeane
Date: 2025-08-05T08:25:34-07:00
New Revision: 74af2cec7bbd307d1dcb7f9f3cdf339d551a1f9f
URL: https://github.com/llvm/llvm-project/commit/74af2cec7bbd307d1dcb7f9f3cdf339d551a1f9f
DIFF: https://github.com/llvm/llvm-project/commit/74af2cec7bbd307d1dcb7f9f3cdf339d551a1f9f.diff
LOG: [OpenACC] Fix 'type' checks in private/firstprivate for array types
These would not give a correct initializer, but they are not possible
to generate correctly anyway, so this patch makes sure we look through
the array type to correctly diagnose these.
Added:
Modified:
clang/lib/Sema/SemaOpenACC.cpp
clang/test/SemaOpenACC/private_firstprivate_reduction_required_ops.cpp
Removed:
################################################################################
diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp
index 8212646facd86..8c6c9c70f8e2c 100644
--- a/clang/lib/Sema/SemaOpenACC.cpp
+++ b/clang/lib/Sema/SemaOpenACC.cpp
@@ -630,7 +630,7 @@ namespace {
// private, firstprivate, and reduction, which require certain operators to be
// available.
ExprResult CheckVarType(SemaOpenACC &S, OpenACCClauseKind CK, Expr *VarExpr,
- Expr *InnerExpr) {
+ SourceLocation InnerLoc, QualType InnerTy) {
// There is nothing to do here, only these three have these sorts of
// restrictions.
if (CK != OpenACCClauseKind::Private &&
@@ -639,10 +639,17 @@ ExprResult CheckVarType(SemaOpenACC &S, OpenACCClauseKind CK, Expr *VarExpr,
return VarExpr;
// We can't test this if it isn't here, or if the type isn't clear yet.
- if (!InnerExpr || InnerExpr->isTypeDependent())
+ if (InnerTy.isNull() || InnerTy->isDependentType())
return VarExpr;
- auto *RD = InnerExpr->getType()->getAsCXXRecordDecl();
+ InnerTy = InnerTy.getUnqualifiedType();
+ if (auto *RefTy = InnerTy->getAs<ReferenceType>())
+ InnerTy = RefTy->getPointeeType();
+
+ if (auto *ArrTy = InnerTy->getAsArrayTypeUnsafe())
+ return CheckVarType(S, CK, VarExpr, InnerLoc, ArrTy->getElementType());
+
+ auto *RD = InnerTy->getAsCXXRecordDecl();
// if this isn't a C++ record decl, we can create/copy/destroy this thing at
// will without problem, so this is a success.
@@ -655,10 +662,8 @@ ExprResult CheckVarType(SemaOpenACC &S, OpenACCClauseKind CK, Expr *VarExpr,
return CD->isDefaultConstructor() && !CD->isDeleted();
}) != RD->ctors().end();
if (!HasNonDeletedDefaultCtor && !RD->needsImplicitDefaultConstructor()) {
- S.Diag(InnerExpr->getBeginLoc(),
- clang::diag::warn_acc_var_referenced_lacks_op)
- << InnerExpr->getType() << CK
- << clang::diag::AccVarReferencedReason::DefCtor;
+ S.Diag(InnerLoc, clang::diag::warn_acc_var_referenced_lacks_op)
+ << InnerTy << CK << clang::diag::AccVarReferencedReason::DefCtor;
return ExprError();
}
} else if (CK == OpenACCClauseKind::FirstPrivate) {
@@ -670,16 +675,14 @@ ExprResult CheckVarType(SemaOpenACC &S, OpenACCClauseKind CK, Expr *VarExpr,
if (SMOR.getKind() != Sema::SpecialMemberOverloadResult::Success ||
SMOR.getMethod()->isDeleted()) {
- S.Diag(InnerExpr->getBeginLoc(),
- clang::diag::warn_acc_var_referenced_lacks_op)
- << InnerExpr->getType() << CK
- << clang::diag::AccVarReferencedReason::CopyCtor;
+ S.Diag(InnerLoc, clang::diag::warn_acc_var_referenced_lacks_op)
+ << InnerTy << CK << clang::diag::AccVarReferencedReason::CopyCtor;
return ExprError();
}
}
} else if (CK == OpenACCClauseKind::Reduction) {
// TODO: OpenACC:
- // Reduction must have copyctor + dtor + operation in InnerExpr I think?
+ // Reduction must have copyctor + dtor + operation in InnerTy I think?
// Need to confirm when implementing this part.
}
@@ -687,14 +690,20 @@ ExprResult CheckVarType(SemaOpenACC &S, OpenACCClauseKind CK, Expr *VarExpr,
bool DestructorDeleted =
RD->getDestructor() && RD->getDestructor()->isDeleted();
if (DestructorDeleted && !RD->needsImplicitDestructor()) {
- S.Diag(InnerExpr->getBeginLoc(),
- clang::diag::warn_acc_var_referenced_lacks_op)
- << InnerExpr->getType() << CK
- << clang::diag::AccVarReferencedReason::Dtor;
+ S.Diag(InnerLoc, clang::diag::warn_acc_var_referenced_lacks_op)
+ << InnerTy << CK << clang::diag::AccVarReferencedReason::Dtor;
return ExprError();
}
return VarExpr;
}
+
+ExprResult CheckVarType(SemaOpenACC &S, OpenACCClauseKind CK, Expr *VarExpr,
+ Expr *InnerExpr) {
+ if (!InnerExpr)
+ return VarExpr;
+ return CheckVarType(S, CK, VarExpr, InnerExpr->getBeginLoc(),
+ InnerExpr->getType());
+}
} // namespace
ExprResult SemaOpenACC::ActOnVar(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
diff --git a/clang/test/SemaOpenACC/private_firstprivate_reduction_required_ops.cpp b/clang/test/SemaOpenACC/private_firstprivate_reduction_required_ops.cpp
index ad3cb8ba5d3ff..4644bdeeacc0e 100644
--- a/clang/test/SemaOpenACC/private_firstprivate_reduction_required_ops.cpp
+++ b/clang/test/SemaOpenACC/private_firstprivate_reduction_required_ops.cpp
@@ -11,12 +11,13 @@ struct DefaultedCtor {
};
struct ImpledCtor {
- ImpledCtor() = default;
+ ImpledCtor();
};
struct DeletedCtor {
DeletedCtor() = delete;
+ DeletedCtor(int i);
};
struct ImpledDtor {
@@ -43,6 +44,7 @@ struct DefaultedCopy {
DefaultedCopy(const DefaultedCopy&) = default;
};
struct UserCopy {
+ UserCopy();
UserCopy(const UserCopy&);
};
@@ -74,7 +76,7 @@ void private_uses(ImplicitCtorDtor &CDT, ImplDeletedCtor &IDC,
#pragma acc parallel private(DefD)
;
- // expected-error at +1{{variable of type 'DeletedDtor' referenced in OpenACC 'private' clause does not have a destructor; reference has no effect}}
+ // expected-error at +1{{variable of type 'DeletedDtor' referenced in OpenACC 'private' clause does not have a}}
#pragma acc parallel private(DelD)
;
@@ -113,6 +115,45 @@ void inst(ImplicitCtorDtor &CDT, ImplDeletedCtor &IDC,
private_templ(IDD);
}
+void private_arrays() {
+ char *ptr;
+ ImplicitCtorDtor CDTArr[5];
+ ImplDeletedCtor IDCArr[5]{1,2,3,4,5};
+ DefaultedCtor DefCArr[5];
+ ImpledCtor ICArr[5];
+ DeletedCtor DelCArr[5]{1,2,3,4,5};
+ ImpledDtor IDArr[5];
+ DefaultedDtor DefDArr[5];
+ using DelDArrTy = DeletedDtor[5];
+ DelDArrTy &DelDArr = *((DelDArrTy*)ptr);
+ using IDDArrTy = ImplicitDelDtor[5];
+ IDDArrTy &IDDArr = *((IDDArrTy*)ptr);
+
+
+#pragma acc parallel private(CDTArr)
+ ;
+ // expected-error at +1{{variable of type 'ImplDeletedCtor' referenced in OpenACC 'private' clause does not have a default constructor; reference has no effect}}
+#pragma acc parallel private(IDCArr)
+ ;
+#pragma acc parallel private(DefCArr)
+ ;
+#pragma acc parallel private(ICArr)
+ ;
+ // expected-error at +1{{variable of type 'DeletedCtor' referenced in OpenACC 'private' clause does not have a default constructor; reference has no effect}}
+#pragma acc parallel private(DelCArr)
+ ;
+#pragma acc parallel private(IDArr)
+ ;
+#pragma acc parallel private(DefDArr)
+ ;
+ // expected-error at +1{{variable of type 'DeletedDtor' referenced in OpenACC 'private' clause does not have a destructor; reference has no effect}}
+#pragma acc parallel private(DelDArr)
+ ;
+ // expected-error at +1{{variable of type 'ImplicitDelDtor' referenced in OpenACC 'private' clause does not have a destructor; reference has no effect}}
+#pragma acc parallel private(IDDArr)
+ ;
+}
+
void firstprivate_uses(ImplicitCtorDtor &CDT, ImplDeletedCtor &IDC,
DefaultedCtor &DefC, ImpledCtor &IC, DeletedCtor &DelC,
ImpledDtor &ID, DefaultedDtor &DefD, DeletedDtor &DelD,
@@ -187,3 +228,48 @@ void firstprivate_inst(ImplicitCtorDtor &CDT, ImplDeletedCtor &IDC,
firstprivate_template(UDCopy);
}
+void firstprivate_arrays() {
+ char *ptr;
+ ImplicitCtorDtor CDTArr[5];
+ ImplDeletedCtor IDCArr[5]{1,2,3,4,5};
+ DefaultedCtor DefCArr[5];
+ ImpledCtor ICArr[5];
+ DeletedCtor DelCArr[5]{1,2,3,4,5};
+ ImpledDtor IDArr[5];
+ DefaultedDtor DefDArr[5];
+ using DelDArrTy = DeletedDtor[5];
+ DelDArrTy &DelDArr = *((DelDArrTy*)ptr);
+ using IDDArrTy = ImplicitDelDtor[5];
+ IDDArrTy &IDDArr = *((IDDArrTy*)ptr);
+ DeletedCopy DelCopyArr[5]{};
+ DefaultedCopy DefCopyArr[5]{};
+ UserCopy UDCopyArr[5]{};
+
+#pragma acc parallel firstprivate(CDTArr)
+ ;
+#pragma acc parallel firstprivate(IDCArr)
+ ;
+#pragma acc parallel firstprivate(DefCArr)
+ ;
+#pragma acc parallel firstprivate(ICArr)
+ ;
+#pragma acc parallel firstprivate(DelCArr)
+ ;
+#pragma acc parallel firstprivate(IDArr)
+ ;
+#pragma acc parallel firstprivate(DefDArr)
+ ;
+ // expected-error at +1{{variable of type 'DeletedDtor' referenced in OpenACC 'firstprivate' clause does not have a destructor; reference has no effect}}
+#pragma acc parallel firstprivate(DelDArr)
+ ;
+ // expected-error at +1{{variable of type 'ImplicitDelDtor' referenced in OpenACC 'firstprivate' clause does not have a copy constructor; reference has no effect}}
+#pragma acc parallel firstprivate(IDDArr)
+ ;
+ // expected-error at +1{{variable of type 'DeletedCopy' referenced in OpenACC 'firstprivate' clause does not have a copy constructor; reference has no effect}}
+#pragma acc parallel firstprivate(DelCopyArr)
+ ;
+#pragma acc parallel firstprivate(DefCopyArr)
+ ;
+#pragma acc parallel firstprivate(UDCopyArr)
+ ;
+}
More information about the cfe-commits
mailing list