Skip to content

Commit 74af2ce

Browse files
committed
[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.
1 parent 0a8ebdb commit 74af2ce

File tree

2 files changed

+113
-18
lines changed

2 files changed

+113
-18
lines changed

clang/lib/Sema/SemaOpenACC.cpp

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -630,7 +630,7 @@ namespace {
630630
// private, firstprivate, and reduction, which require certain operators to be
631631
// available.
632632
ExprResult CheckVarType(SemaOpenACC &S, OpenACCClauseKind CK, Expr *VarExpr,
633-
Expr *InnerExpr) {
633+
SourceLocation InnerLoc, QualType InnerTy) {
634634
// There is nothing to do here, only these three have these sorts of
635635
// restrictions.
636636
if (CK != OpenACCClauseKind::Private &&
@@ -639,10 +639,17 @@ ExprResult CheckVarType(SemaOpenACC &S, OpenACCClauseKind CK, Expr *VarExpr,
639639
return VarExpr;
640640

641641
// We can't test this if it isn't here, or if the type isn't clear yet.
642-
if (!InnerExpr || InnerExpr->isTypeDependent())
642+
if (InnerTy.isNull() || InnerTy->isDependentType())
643643
return VarExpr;
644644

645-
auto *RD = InnerExpr->getType()->getAsCXXRecordDecl();
645+
InnerTy = InnerTy.getUnqualifiedType();
646+
if (auto *RefTy = InnerTy->getAs<ReferenceType>())
647+
InnerTy = RefTy->getPointeeType();
648+
649+
if (auto *ArrTy = InnerTy->getAsArrayTypeUnsafe())
650+
return CheckVarType(S, CK, VarExpr, InnerLoc, ArrTy->getElementType());
651+
652+
auto *RD = InnerTy->getAsCXXRecordDecl();
646653

647654
// if this isn't a C++ record decl, we can create/copy/destroy this thing at
648655
// will without problem, so this is a success.
@@ -655,10 +662,8 @@ ExprResult CheckVarType(SemaOpenACC &S, OpenACCClauseKind CK, Expr *VarExpr,
655662
return CD->isDefaultConstructor() && !CD->isDeleted();
656663
}) != RD->ctors().end();
657664
if (!HasNonDeletedDefaultCtor && !RD->needsImplicitDefaultConstructor()) {
658-
S.Diag(InnerExpr->getBeginLoc(),
659-
clang::diag::warn_acc_var_referenced_lacks_op)
660-
<< InnerExpr->getType() << CK
661-
<< clang::diag::AccVarReferencedReason::DefCtor;
665+
S.Diag(InnerLoc, clang::diag::warn_acc_var_referenced_lacks_op)
666+
<< InnerTy << CK << clang::diag::AccVarReferencedReason::DefCtor;
662667
return ExprError();
663668
}
664669
} else if (CK == OpenACCClauseKind::FirstPrivate) {
@@ -670,31 +675,35 @@ ExprResult CheckVarType(SemaOpenACC &S, OpenACCClauseKind CK, Expr *VarExpr,
670675

671676
if (SMOR.getKind() != Sema::SpecialMemberOverloadResult::Success ||
672677
SMOR.getMethod()->isDeleted()) {
673-
S.Diag(InnerExpr->getBeginLoc(),
674-
clang::diag::warn_acc_var_referenced_lacks_op)
675-
<< InnerExpr->getType() << CK
676-
<< clang::diag::AccVarReferencedReason::CopyCtor;
678+
S.Diag(InnerLoc, clang::diag::warn_acc_var_referenced_lacks_op)
679+
<< InnerTy << CK << clang::diag::AccVarReferencedReason::CopyCtor;
677680
return ExprError();
678681
}
679682
}
680683
} else if (CK == OpenACCClauseKind::Reduction) {
681684
// TODO: OpenACC:
682-
// Reduction must have copyctor + dtor + operation in InnerExpr I think?
685+
// Reduction must have copyctor + dtor + operation in InnerTy I think?
683686
// Need to confirm when implementing this part.
684687
}
685688

686689
// All 3 things need to make sure they have a dtor.
687690
bool DestructorDeleted =
688691
RD->getDestructor() && RD->getDestructor()->isDeleted();
689692
if (DestructorDeleted && !RD->needsImplicitDestructor()) {
690-
S.Diag(InnerExpr->getBeginLoc(),
691-
clang::diag::warn_acc_var_referenced_lacks_op)
692-
<< InnerExpr->getType() << CK
693-
<< clang::diag::AccVarReferencedReason::Dtor;
693+
S.Diag(InnerLoc, clang::diag::warn_acc_var_referenced_lacks_op)
694+
<< InnerTy << CK << clang::diag::AccVarReferencedReason::Dtor;
694695
return ExprError();
695696
}
696697
return VarExpr;
697698
}
699+
700+
ExprResult CheckVarType(SemaOpenACC &S, OpenACCClauseKind CK, Expr *VarExpr,
701+
Expr *InnerExpr) {
702+
if (!InnerExpr)
703+
return VarExpr;
704+
return CheckVarType(S, CK, VarExpr, InnerExpr->getBeginLoc(),
705+
InnerExpr->getType());
706+
}
698707
} // namespace
699708

700709
ExprResult SemaOpenACC::ActOnVar(OpenACCDirectiveKind DK, OpenACCClauseKind CK,

clang/test/SemaOpenACC/private_firstprivate_reduction_required_ops.cpp

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,13 @@ struct DefaultedCtor {
1111
};
1212

1313
struct ImpledCtor {
14-
ImpledCtor() = default;
14+
ImpledCtor();
1515
};
1616

1717

1818
struct DeletedCtor {
1919
DeletedCtor() = delete;
20+
DeletedCtor(int i);
2021
};
2122

2223
struct ImpledDtor {
@@ -43,6 +44,7 @@ struct DefaultedCopy {
4344
DefaultedCopy(const DefaultedCopy&) = default;
4445
};
4546
struct UserCopy {
47+
UserCopy();
4648
UserCopy(const UserCopy&);
4749
};
4850

@@ -74,7 +76,7 @@ void private_uses(ImplicitCtorDtor &CDT, ImplDeletedCtor &IDC,
7476
#pragma acc parallel private(DefD)
7577
;
7678

77-
// expected-error@+1{{variable of type 'DeletedDtor' referenced in OpenACC 'private' clause does not have a destructor; reference has no effect}}
79+
// expected-error@+1{{variable of type 'DeletedDtor' referenced in OpenACC 'private' clause does not have a}}
7880
#pragma acc parallel private(DelD)
7981
;
8082

@@ -113,6 +115,45 @@ void inst(ImplicitCtorDtor &CDT, ImplDeletedCtor &IDC,
113115
private_templ(IDD);
114116
}
115117

118+
void private_arrays() {
119+
char *ptr;
120+
ImplicitCtorDtor CDTArr[5];
121+
ImplDeletedCtor IDCArr[5]{1,2,3,4,5};
122+
DefaultedCtor DefCArr[5];
123+
ImpledCtor ICArr[5];
124+
DeletedCtor DelCArr[5]{1,2,3,4,5};
125+
ImpledDtor IDArr[5];
126+
DefaultedDtor DefDArr[5];
127+
using DelDArrTy = DeletedDtor[5];
128+
DelDArrTy &DelDArr = *((DelDArrTy*)ptr);
129+
using IDDArrTy = ImplicitDelDtor[5];
130+
IDDArrTy &IDDArr = *((IDDArrTy*)ptr);
131+
132+
133+
#pragma acc parallel private(CDTArr)
134+
;
135+
// expected-error@+1{{variable of type 'ImplDeletedCtor' referenced in OpenACC 'private' clause does not have a default constructor; reference has no effect}}
136+
#pragma acc parallel private(IDCArr)
137+
;
138+
#pragma acc parallel private(DefCArr)
139+
;
140+
#pragma acc parallel private(ICArr)
141+
;
142+
// expected-error@+1{{variable of type 'DeletedCtor' referenced in OpenACC 'private' clause does not have a default constructor; reference has no effect}}
143+
#pragma acc parallel private(DelCArr)
144+
;
145+
#pragma acc parallel private(IDArr)
146+
;
147+
#pragma acc parallel private(DefDArr)
148+
;
149+
// expected-error@+1{{variable of type 'DeletedDtor' referenced in OpenACC 'private' clause does not have a destructor; reference has no effect}}
150+
#pragma acc parallel private(DelDArr)
151+
;
152+
// expected-error@+1{{variable of type 'ImplicitDelDtor' referenced in OpenACC 'private' clause does not have a destructor; reference has no effect}}
153+
#pragma acc parallel private(IDDArr)
154+
;
155+
}
156+
116157
void firstprivate_uses(ImplicitCtorDtor &CDT, ImplDeletedCtor &IDC,
117158
DefaultedCtor &DefC, ImpledCtor &IC, DeletedCtor &DelC,
118159
ImpledDtor &ID, DefaultedDtor &DefD, DeletedDtor &DelD,
@@ -187,3 +228,48 @@ void firstprivate_inst(ImplicitCtorDtor &CDT, ImplDeletedCtor &IDC,
187228
firstprivate_template(UDCopy);
188229
}
189230

231+
void firstprivate_arrays() {
232+
char *ptr;
233+
ImplicitCtorDtor CDTArr[5];
234+
ImplDeletedCtor IDCArr[5]{1,2,3,4,5};
235+
DefaultedCtor DefCArr[5];
236+
ImpledCtor ICArr[5];
237+
DeletedCtor DelCArr[5]{1,2,3,4,5};
238+
ImpledDtor IDArr[5];
239+
DefaultedDtor DefDArr[5];
240+
using DelDArrTy = DeletedDtor[5];
241+
DelDArrTy &DelDArr = *((DelDArrTy*)ptr);
242+
using IDDArrTy = ImplicitDelDtor[5];
243+
IDDArrTy &IDDArr = *((IDDArrTy*)ptr);
244+
DeletedCopy DelCopyArr[5]{};
245+
DefaultedCopy DefCopyArr[5]{};
246+
UserCopy UDCopyArr[5]{};
247+
248+
#pragma acc parallel firstprivate(CDTArr)
249+
;
250+
#pragma acc parallel firstprivate(IDCArr)
251+
;
252+
#pragma acc parallel firstprivate(DefCArr)
253+
;
254+
#pragma acc parallel firstprivate(ICArr)
255+
;
256+
#pragma acc parallel firstprivate(DelCArr)
257+
;
258+
#pragma acc parallel firstprivate(IDArr)
259+
;
260+
#pragma acc parallel firstprivate(DefDArr)
261+
;
262+
// expected-error@+1{{variable of type 'DeletedDtor' referenced in OpenACC 'firstprivate' clause does not have a destructor; reference has no effect}}
263+
#pragma acc parallel firstprivate(DelDArr)
264+
;
265+
// expected-error@+1{{variable of type 'ImplicitDelDtor' referenced in OpenACC 'firstprivate' clause does not have a copy constructor; reference has no effect}}
266+
#pragma acc parallel firstprivate(IDDArr)
267+
;
268+
// expected-error@+1{{variable of type 'DeletedCopy' referenced in OpenACC 'firstprivate' clause does not have a copy constructor; reference has no effect}}
269+
#pragma acc parallel firstprivate(DelCopyArr)
270+
;
271+
#pragma acc parallel firstprivate(DefCopyArr)
272+
;
273+
#pragma acc parallel firstprivate(UDCopyArr)
274+
;
275+
}

0 commit comments

Comments
 (0)