Skip to content

Commit

Permalink
[CUDA][HIP] warn incompatible redeclare
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
yxsamliu committed Jan 8, 2024
1 parent f4bc70e commit 30daa34
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 14 deletions.
6 changes: 6 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -8837,6 +8837,12 @@ def err_cuda_ovl_target : Error<
"cannot overload %select{__device__|__global__|__host__|__host__ __device__}2 function %3">;
def note_cuda_ovl_candidate_target_mismatch : Note<
"candidate template ignored: target attributes do not match">;
def warn_offload_incompatible_redeclare : Warning<
"incompatible host/device attribute with redeclaration: "
"new declaration is %select{__device__|__global__|__host__|__host__ __device__}0 function, "
"old declaration is %select{__device__|__global__|__host__|__host__ __device__}1 function. "
"It will cause warning with nvcc">,
InGroup<DiagGroup<"offload-incompatible-redeclare">>, DefaultIgnore;

def err_cuda_device_builtin_surftex_cls_template : Error<
"illegal device builtin %select{surface|texture}0 reference "
Expand Down
35 changes: 21 additions & 14 deletions clang/lib/Sema/SemaCUDA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -992,22 +992,29 @@ void Sema::checkCUDATargetOverload(FunctionDecl *NewFD,
// HD/global functions "exist" in some sense on both the host and device, so
// should have the same implementation on both sides.
if (NewTarget != OldTarget &&
((NewTarget == CFT_HostDevice &&
!(LangOpts.OffloadImplicitHostDeviceTemplates &&
isCUDAImplicitHostDeviceFunction(NewFD) &&
OldTarget == CFT_Device)) ||
(OldTarget == CFT_HostDevice &&
!(LangOpts.OffloadImplicitHostDeviceTemplates &&
isCUDAImplicitHostDeviceFunction(OldFD) &&
NewTarget == CFT_Device)) ||
(NewTarget == CFT_Global) || (OldTarget == CFT_Global)) &&
!IsOverload(NewFD, OldFD, /* UseMemberUsingDeclRules = */ false,
/* ConsiderCudaAttrs = */ false)) {
Diag(NewFD->getLocation(), diag::err_cuda_ovl_target)
<< NewTarget << NewFD->getDeclName() << OldTarget << OldFD;
Diag(OldFD->getLocation(), diag::note_previous_declaration);
NewFD->setInvalidDecl();
break;
if ((NewTarget == CFT_HostDevice &&
!(LangOpts.OffloadImplicitHostDeviceTemplates &&
isCUDAImplicitHostDeviceFunction(NewFD) &&
OldTarget == CFT_Device)) ||
(OldTarget == CFT_HostDevice &&
!(LangOpts.OffloadImplicitHostDeviceTemplates &&
isCUDAImplicitHostDeviceFunction(OldFD) &&
NewTarget == CFT_Device)) ||
(NewTarget == CFT_Global) || (OldTarget == CFT_Global)) {
Diag(NewFD->getLocation(), diag::err_cuda_ovl_target)
<< NewTarget << NewFD->getDeclName() << OldTarget << OldFD;
Diag(OldFD->getLocation(), diag::note_previous_declaration);
NewFD->setInvalidDecl();
break;
}
if ((NewTarget == CFT_Host && OldTarget == CFT_Device) ||
(NewTarget == CFT_Device && OldTarget == CFT_Host)) {
Diag(NewFD->getLocation(), diag::warn_offload_incompatible_redeclare)
<< NewTarget << OldTarget;
Diag(OldFD->getLocation(), diag::note_previous_declaration);
}
}
}
}
Expand Down
19 changes: 19 additions & 0 deletions clang/test/SemaCUDA/function-redclare.cu
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only \
// RUN: -isystem %S/Inputs -verify %s
// RUN: %clang_cc1 -triple nvptx64-nvidia-cuda -fsyntax-only \
// RUN: -isystem %S/Inputs -fcuda-is-device -verify %s
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only \
// RUN: -isystem %S/Inputs -verify=redecl -Woffload-incompatible-redeclare %s
// RUN: %clang_cc1 -triple nvptx64-nvidia-cuda -fsyntax-only \
// RUN: -isystem %S/Inputs -fcuda-is-device -Woffload-incompatible-redeclare -verify=redecl %s

// expected-no-diagnostics
#include "cuda.h"

__device__ void f(); // redecl-note {{previous declaration is here}}

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}}

void g(); // redecl-note {{previous declaration is here}}

__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 comments on commit 30daa34

Please sign in to comment.