summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaCUDA.cpp
diff options
context:
space:
mode:
authorYaxun Liu <Yaxun.Liu@amd.com>2019-09-20 14:28:09 +0000
committerYaxun Liu <Yaxun.Liu@amd.com>2019-09-20 14:28:09 +0000
commite5d17c511fa603b557f86257b5b6f39b429f4e35 (patch)
treeab5b5e890b32f0e0440fb789d1960ab57fcf997f /clang/lib/Sema/SemaCUDA.cpp
parent4896f7243d629dfa9cce4acf2f72ca1e081a2c40 (diff)
downloadbcm5719-llvm-e5d17c511fa603b557f86257b5b6f39b429f4e35.tar.gz
bcm5719-llvm-e5d17c511fa603b557f86257b5b6f39b429f4e35.zip
[CUDA][HIP] Fix hostness of defaulted constructor
Clang does not respect the explicit device host attributes of defaulted special members. Also clang does not respect the hostness of special members determined by their first declarations. Clang also adds duplicate implicit device or host attributes in certain cases. This patch fixes that. Differential Revision: https://reviews.llvm.org/D67509 llvm-svn: 372394
Diffstat (limited to 'clang/lib/Sema/SemaCUDA.cpp')
-rw-r--r--clang/lib/Sema/SemaCUDA.cpp39
1 files changed, 27 insertions, 12 deletions
diff --git a/clang/lib/Sema/SemaCUDA.cpp b/clang/lib/Sema/SemaCUDA.cpp
index 203c09c5711..e009dcb6f16 100644
--- a/clang/lib/Sema/SemaCUDA.cpp
+++ b/clang/lib/Sema/SemaCUDA.cpp
@@ -267,6 +267,18 @@ bool Sema::inferCUDATargetForImplicitSpecialMember(CXXRecordDecl *ClassDecl,
CXXMethodDecl *MemberDecl,
bool ConstRHS,
bool Diagnose) {
+ // If the defaulted special member is defined lexically outside of its
+ // owning class, or the special member already has explicit device or host
+ // attributes, do not infer.
+ bool InClass = MemberDecl->getLexicalParent() == MemberDecl->getParent();
+ bool HasH = MemberDecl->hasAttr<CUDAHostAttr>();
+ bool HasD = MemberDecl->hasAttr<CUDADeviceAttr>();
+ bool HasExplicitAttr =
+ (HasD && !MemberDecl->getAttr<CUDADeviceAttr>()->isImplicit()) ||
+ (HasH && !MemberDecl->getAttr<CUDAHostAttr>()->isImplicit());
+ if (!InClass || HasExplicitAttr)
+ return false;
+
llvm::Optional<CUDAFunctionTarget> InferredTarget;
// We're going to invoke special member lookup; mark that these special
@@ -371,21 +383,24 @@ bool Sema::inferCUDATargetForImplicitSpecialMember(CXXRecordDecl *ClassDecl,
}
}
+
+ // If no target was inferred, mark this member as __host__ __device__;
+ // it's the least restrictive option that can be invoked from any target.
+ bool NeedsH = true, NeedsD = true;
if (InferredTarget.hasValue()) {
- if (InferredTarget.getValue() == CFT_Device) {
- MemberDecl->addAttr(CUDADeviceAttr::CreateImplicit(Context));
- } else if (InferredTarget.getValue() == CFT_Host) {
- MemberDecl->addAttr(CUDAHostAttr::CreateImplicit(Context));
- } else {
- MemberDecl->addAttr(CUDADeviceAttr::CreateImplicit(Context));
- MemberDecl->addAttr(CUDAHostAttr::CreateImplicit(Context));
- }
- } else {
- // If no target was inferred, mark this member as __host__ __device__;
- // it's the least restrictive option that can be invoked from any target.
+ if (InferredTarget.getValue() == CFT_Device)
+ NeedsH = false;
+ else if (InferredTarget.getValue() == CFT_Host)
+ NeedsD = false;
+ }
+
+ // We either setting attributes first time, or the inferred ones must match
+ // previously set ones.
+ assert(!(HasD || HasH) || (NeedsD == HasD && NeedsH == HasH));
+ if (NeedsD && !HasD)
MemberDecl->addAttr(CUDADeviceAttr::CreateImplicit(Context));
+ if (NeedsH && !HasH)
MemberDecl->addAttr(CUDAHostAttr::CreateImplicit(Context));
- }
return false;
}
OpenPOWER on IntegriCloud