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@+1{{variable of type 'DeletedDtor' referenced in OpenACC 'private' clause does not have a destructor; reference has no effect}} + // expected-error@+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@+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@+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@+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@+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@+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@+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@+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) + ; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits