Skip to content

Commit 30daa34

Browse files
committed
[CUDA][HIP] warn incompatible redeclare
nvcc warns about the following code: `void f(); __device__ void f() {}` but clang does not since clang allows device function to overload host function. Users want clang to emit similar warning to help code to be compatible with nvcc. Since this may cause regression with existing code, the warning is off by default and can be enabled by -Woffload-incompatible-redeclare. It won't cause warning in system headers, even with -Woffload-incompatible-redeclare.
1 parent f4bc70e commit 30daa34

File tree

3 files changed

+46
-14
lines changed

3 files changed

+46
-14
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8837,6 +8837,12 @@ def err_cuda_ovl_target : Error<
88378837
"cannot overload %select{__device__|__global__|__host__|__host__ __device__}2 function %3">;
88388838
def note_cuda_ovl_candidate_target_mismatch : Note<
88398839
"candidate template ignored: target attributes do not match">;
8840+
def warn_offload_incompatible_redeclare : Warning<
8841+
"incompatible host/device attribute with redeclaration: "
8842+
"new declaration is %select{__device__|__global__|__host__|__host__ __device__}0 function, "
8843+
"old declaration is %select{__device__|__global__|__host__|__host__ __device__}1 function. "
8844+
"It will cause warning with nvcc">,
8845+
InGroup<DiagGroup<"offload-incompatible-redeclare">>, DefaultIgnore;
88408846

88418847
def err_cuda_device_builtin_surftex_cls_template : Error<
88428848
"illegal device builtin %select{surface|texture}0 reference "

clang/lib/Sema/SemaCUDA.cpp

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -992,22 +992,29 @@ void Sema::checkCUDATargetOverload(FunctionDecl *NewFD,
992992
// HD/global functions "exist" in some sense on both the host and device, so
993993
// should have the same implementation on both sides.
994994
if (NewTarget != OldTarget &&
995-
((NewTarget == CFT_HostDevice &&
996-
!(LangOpts.OffloadImplicitHostDeviceTemplates &&
997-
isCUDAImplicitHostDeviceFunction(NewFD) &&
998-
OldTarget == CFT_Device)) ||
999-
(OldTarget == CFT_HostDevice &&
1000-
!(LangOpts.OffloadImplicitHostDeviceTemplates &&
1001-
isCUDAImplicitHostDeviceFunction(OldFD) &&
1002-
NewTarget == CFT_Device)) ||
1003-
(NewTarget == CFT_Global) || (OldTarget == CFT_Global)) &&
1004995
!IsOverload(NewFD, OldFD, /* UseMemberUsingDeclRules = */ false,
1005996
/* ConsiderCudaAttrs = */ false)) {
1006-
Diag(NewFD->getLocation(), diag::err_cuda_ovl_target)
1007-
<< NewTarget << NewFD->getDeclName() << OldTarget << OldFD;
1008-
Diag(OldFD->getLocation(), diag::note_previous_declaration);
1009-
NewFD->setInvalidDecl();
1010-
break;
997+
if ((NewTarget == CFT_HostDevice &&
998+
!(LangOpts.OffloadImplicitHostDeviceTemplates &&
999+
isCUDAImplicitHostDeviceFunction(NewFD) &&
1000+
OldTarget == CFT_Device)) ||
1001+
(OldTarget == CFT_HostDevice &&
1002+
!(LangOpts.OffloadImplicitHostDeviceTemplates &&
1003+
isCUDAImplicitHostDeviceFunction(OldFD) &&
1004+
NewTarget == CFT_Device)) ||
1005+
(NewTarget == CFT_Global) || (OldTarget == CFT_Global)) {
1006+
Diag(NewFD->getLocation(), diag::err_cuda_ovl_target)
1007+
<< NewTarget << NewFD->getDeclName() << OldTarget << OldFD;
1008+
Diag(OldFD->getLocation(), diag::note_previous_declaration);
1009+
NewFD->setInvalidDecl();
1010+
break;
1011+
}
1012+
if ((NewTarget == CFT_Host && OldTarget == CFT_Device) ||
1013+
(NewTarget == CFT_Device && OldTarget == CFT_Host)) {
1014+
Diag(NewFD->getLocation(), diag::warn_offload_incompatible_redeclare)
1015+
<< NewTarget << OldTarget;
1016+
Diag(OldFD->getLocation(), diag::note_previous_declaration);
1017+
}
10111018
}
10121019
}
10131020
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only \
2+
// RUN: -isystem %S/Inputs -verify %s
3+
// RUN: %clang_cc1 -triple nvptx64-nvidia-cuda -fsyntax-only \
4+
// RUN: -isystem %S/Inputs -fcuda-is-device -verify %s
5+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only \
6+
// RUN: -isystem %S/Inputs -verify=redecl -Woffload-incompatible-redeclare %s
7+
// RUN: %clang_cc1 -triple nvptx64-nvidia-cuda -fsyntax-only \
8+
// RUN: -isystem %S/Inputs -fcuda-is-device -Woffload-incompatible-redeclare -verify=redecl %s
9+
10+
// expected-no-diagnostics
11+
#include "cuda.h"
12+
13+
__device__ void f(); // redecl-note {{previous declaration is here}}
14+
15+
void f() {} // redecl-warning {{incompatible host/device attribute with redeclaration: new declaration is __host__ function, old declaration is __device__ function. It will cause warning with nvcc}}
16+
17+
void g(); // redecl-note {{previous declaration is here}}
18+
19+
__device__ void g() {} // redecl-warning {{incompatible host/device attribute with redeclaration: new declaration is __device__ function, old declaration is __host__ function. It will cause warning with nvcc}}

0 commit comments

Comments
 (0)