[clang] 4e0b68c - [OpenACC] Implement warning restrictions for 'firstprivate'
via cfe-commits
cfe-commits at lists.llvm.org
Mon Aug 4 11:42:38 PDT 2025
Author: erichkeane
Date: 2025-08-04T11:42:33-07:00
New Revision: 4e0b68cef0bdf0d806cd778fbf0b7ddd80b44b4d
URL: https://github.com/llvm/llvm-project/commit/4e0b68cef0bdf0d806cd778fbf0b7ddd80b44b4d
DIFF: https://github.com/llvm/llvm-project/commit/4e0b68cef0bdf0d806cd778fbf0b7ddd80b44b4d.diff
LOG: [OpenACC] Implement warning restrictions for 'firstprivate'
'firstprivate' can't be generated unless we have a copy constructor, so
this patch implements the restriction as a warning, and prevents the
item from being added to the AST.
Added:
Modified:
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/include/clang/Sema/SemaOpenACC.h
clang/lib/Sema/SemaOpenACC.cpp
clang/test/SemaOpenACC/private_firstprivate_reduction_required_ops.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 0ba06d6f2dee3..9ce142e7b37cc 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -13531,7 +13531,8 @@ def err_acc_device_type_multiple_archs
def warn_acc_var_referenced_lacks_op
: Warning<"variable of type %0 referenced in OpenACC '%1' clause does not "
"have a %enum_select<AccVarReferencedReason>{%DefCtor{default "
- "constructor}|%Dtor{destructor}}2; reference has no effect">,
+ "constructor}|%CopyCtor{copy constructor}|%Dtor{destructor}}2; "
+ "reference has no effect">,
InGroup<DiagGroup<"openacc-var-lacks-operation">>,
DefaultError;
diff --git a/clang/include/clang/Sema/SemaOpenACC.h b/clang/include/clang/Sema/SemaOpenACC.h
index f51045d26e23b..e9e4e6c2b380c 100644
--- a/clang/include/clang/Sema/SemaOpenACC.h
+++ b/clang/include/clang/Sema/SemaOpenACC.h
@@ -176,10 +176,6 @@ class SemaOpenACC : public SemaBase {
void checkFor();
- // void checkRangeFor(); ?? ERICH
- // const ValueDecl *checkInit();
- // void checkCond(const ValueDecl *Init);
- // void checkInc(const ValueDecl *Init);
public:
// Checking for non-instantiation version of a Range-for.
ForStmtBeginChecker(SemaOpenACC &SemaRef, SourceLocation ForLoc,
diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp
index 8f32817aec48f..8212646facd86 100644
--- a/clang/lib/Sema/SemaOpenACC.cpp
+++ b/clang/lib/Sema/SemaOpenACC.cpp
@@ -642,21 +642,13 @@ ExprResult CheckVarType(SemaOpenACC &S, OpenACCClauseKind CK, Expr *VarExpr,
if (!InnerExpr || InnerExpr->isTypeDependent())
return VarExpr;
- const auto *RD = InnerExpr->getType()->getAsCXXRecordDecl();
+ auto *RD = InnerExpr->getType()->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.
if (!RD)
return VarExpr;
- // TODO: OpenACC:
- // Private must have default ctor + dtor in InnerExpr
- // FirstPrivate must have copyctor + dtor in InnerExpr
- // Reduction must have copyctor + dtor + operation in InnerExpr
-
- // TODO OpenACC: It isn't clear what the requirements are for default
- // constructor/copy constructor are for First private and reduction, but
- // private requires a default constructor.
if (CK == OpenACCClauseKind::Private) {
bool HasNonDeletedDefaultCtor =
llvm::find_if(RD->ctors(), [](const CXXConstructorDecl *CD) {
@@ -669,6 +661,26 @@ ExprResult CheckVarType(SemaOpenACC &S, OpenACCClauseKind CK, Expr *VarExpr,
<< clang::diag::AccVarReferencedReason::DefCtor;
return ExprError();
}
+ } else if (CK == OpenACCClauseKind::FirstPrivate) {
+ if (!RD->hasSimpleCopyConstructor()) {
+ Sema::SpecialMemberOverloadResult SMOR = S.SemaRef.LookupSpecialMember(
+ RD, CXXSpecialMemberKind::CopyConstructor, /*ConstArg=*/true,
+ /*VolatileArg=*/false, /*RValueThis=*/false, /*ConstThis=*/false,
+ /*VolatileThis=*/false);
+
+ 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;
+ return ExprError();
+ }
+ }
+ } else if (CK == OpenACCClauseKind::Reduction) {
+ // TODO: OpenACC:
+ // Reduction must have copyctor + dtor + operation in InnerExpr I think?
+ // Need to confirm when implementing this part.
}
// All 3 things need to make sure they have a dtor.
diff --git a/clang/test/SemaOpenACC/private_firstprivate_reduction_required_ops.cpp b/clang/test/SemaOpenACC/private_firstprivate_reduction_required_ops.cpp
index e0aee123fe754..ad3cb8ba5d3ff 100644
--- a/clang/test/SemaOpenACC/private_firstprivate_reduction_required_ops.cpp
+++ b/clang/test/SemaOpenACC/private_firstprivate_reduction_required_ops.cpp
@@ -35,6 +35,17 @@ struct ImplicitDelDtor {
DeletedDtor d;
};
+struct DeletedCopy {
+ DeletedCopy(const DeletedCopy&) = delete;
+};
+
+struct DefaultedCopy {
+ DefaultedCopy(const DefaultedCopy&) = default;
+};
+struct UserCopy {
+ UserCopy(const UserCopy&);
+};
+
void private_uses(ImplicitCtorDtor &CDT, ImplDeletedCtor &IDC,
DefaultedCtor &DefC, ImpledCtor &IC, DeletedCtor &DelC,
ImpledDtor &ID, DefaultedDtor &DefD, DeletedDtor &DelD,
@@ -101,3 +112,78 @@ void inst(ImplicitCtorDtor &CDT, ImplDeletedCtor &IDC,
// expected-note at +1{{in instantiation}}
private_templ(IDD);
}
+
+void firstprivate_uses(ImplicitCtorDtor &CDT, ImplDeletedCtor &IDC,
+ DefaultedCtor &DefC, ImpledCtor &IC, DeletedCtor &DelC,
+ ImpledDtor &ID, DefaultedDtor &DefD, DeletedDtor &DelD,
+ ImplicitDelDtor &IDD, DeletedCopy &DelCopy,
+ DefaultedCopy &DefCopy, UserCopy &UDCopy) {
+#pragma acc parallel firstprivate(CDT)
+ ;
+
+#pragma acc parallel firstprivate(IDC)
+ ;
+
+#pragma acc parallel firstprivate(DefC)
+ ;
+
+#pragma acc parallel firstprivate(IC)
+ ;
+
+#pragma acc parallel firstprivate(DelC)
+ ;
+
+#pragma acc parallel firstprivate(ID)
+ ;
+
+#pragma acc parallel firstprivate(DefD)
+ ;
+
+ // 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(DelD)
+ ;
+
+ // 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(IDD)
+ ;
+
+ // 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(DelCopy)
+ ;
+#pragma acc parallel firstprivate(DefCopy)
+ ;
+#pragma acc parallel firstprivate(UDCopy)
+ ;
+}
+
+template<typename T>
+void firstprivate_template(T& t) {
+#pragma acc parallel firstprivate(t) // #FIRSTPRIV
+ ;
+}
+
+void firstprivate_inst(ImplicitCtorDtor &CDT, ImplDeletedCtor &IDC,
+ DefaultedCtor &DefC, ImpledCtor &IC, DeletedCtor &DelC,
+ ImpledDtor &ID, DefaultedDtor &DefD, DeletedDtor &DelD,
+ ImplicitDelDtor &IDD, DeletedCopy &DelCopy,
+ DefaultedCopy &DefCopy, UserCopy &UDCopy) {
+ firstprivate_template(CDT);
+ firstprivate_template(IDC);
+ firstprivate_template(DefC);
+ firstprivate_template(IC);
+ firstprivate_template(DelC);
+ firstprivate_template(ID);
+ firstprivate_template(DefD);
+ // expected-error@#FIRSTPRIV{{variable of type 'DeletedDtor' referenced in OpenACC 'firstprivate' clause does not have a destructor; reference has no effect}}
+ // expected-note at +1{{in instantiation}}
+ firstprivate_template(DelD);
+ // expected-error@#FIRSTPRIV{{variable of type 'ImplicitDelDtor' referenced in OpenACC 'firstprivate' clause does not have a copy constructor; reference has no effect}}
+ // expected-note at +1{{in instantiation}}
+ firstprivate_template(IDD);
+ // expected-error@#FIRSTPRIV{{variable of type 'DeletedCopy' referenced in OpenACC 'firstprivate' clause does not have a copy constructor; reference has no effect}}
+ // expected-note at +1{{in instantiation}}
+ firstprivate_template(DelCopy);
+ firstprivate_template(DefCopy);
+ firstprivate_template(UDCopy);
+}
+
More information about the cfe-commits
mailing list