Skip to content

Commit 27313b6

Browse files
committed
Revert "[CUDA][HIP] Fix overloading resolution in global variable initializer"
This reverts commit de0df63. It was reverted due to regression in HIP unit test on Windows: In file included from C:\hip-tests\catch\unit\graph\hipGraphClone.cc:37: In file included from C:\hip-tests\catch\.\include\hip_test_common.hh:24: In file included from C:\hip-tests\catch\.\include/hip_test_context.hh:24: In file included from C:/install/native/Release/x64/hip/include\hip/hip_runtime.h:54: C:/dk/win\vc\14.31.31107\include\thread:76:70: error: cannot initialize a parameter of type '_beginthreadex_proc_type' (aka 'unsigned int (*)(void *) __attribute__((stdcall))') with an lvalue of type 'const unsigned int (*)(void *) noexcept __attribute__((stdcall))': different exception specifications 76 | reinterpret_cast<void*>(_CSTD _beginthreadex(nullptr, 0, _Invoker_proc, _Decay_copied.get(), 0, &_Thr._Id)); | ^~~~~~~~~~~~~ C:\hip-tests\catch\unit\graph\hipGraphClone.cc:290:21) &>' requested here 90 | _Start(_STD forward<_Fn>(_Fx), _STD forward<_Args>(_Ax)...); | ^ C:\hip-tests\catch\unit\graph\hipGraphClone.cc:290:21) &, 0>' requested here 311 | std::thread t(lambdaFunc); | ^ C:/dk/win\ms_wdk\e22621\Include\10.0.22621.0\ucrt\process.h:99:40: note: passing argument to parameter '_StartAddress' here 99 | _In_ _beginthreadex_proc_type _StartAddress, | ^ 1 error generated when compiling for gfx1030.
1 parent 19550e7 commit 27313b6

File tree

11 files changed

+68
-219
lines changed

11 files changed

+68
-219
lines changed

clang/include/clang/Sema/Sema.h

Lines changed: 9 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,14 +1012,6 @@ class Sema final {
10121012
}
10131013
} DelayedDiagnostics;
10141014

1015-
enum CUDAFunctionTarget {
1016-
CFT_Device,
1017-
CFT_Global,
1018-
CFT_Host,
1019-
CFT_HostDevice,
1020-
CFT_InvalidTarget
1021-
};
1022-
10231015
/// A RAII object to temporarily push a declaration context.
10241016
class ContextRAII {
10251017
private:
@@ -4765,13 +4757,8 @@ class Sema final {
47654757
bool isValidPointerAttrType(QualType T, bool RefOkay = false);
47664758

47674759
bool CheckRegparmAttr(const ParsedAttr &attr, unsigned &value);
4768-
4769-
/// Check validaty of calling convention attribute \p attr. If \p FD
4770-
/// is not null pointer, use \p FD to determine the CUDA/HIP host/device
4771-
/// target. Otherwise, it is specified by \p CFT.
47724760
bool CheckCallingConvAttr(const ParsedAttr &attr, CallingConv &CC,
4773-
const FunctionDecl *FD = nullptr,
4774-
CUDAFunctionTarget CFT = CFT_InvalidTarget);
4761+
const FunctionDecl *FD = nullptr);
47754762
bool CheckAttrTarget(const ParsedAttr &CurrAttr);
47764763
bool CheckAttrNoArgs(const ParsedAttr &CurrAttr);
47774764
bool checkStringLiteralArgumentAttr(const AttributeCommonInfo &CI,
@@ -13278,6 +13265,14 @@ class Sema final {
1327813265
void checkTypeSupport(QualType Ty, SourceLocation Loc,
1327913266
ValueDecl *D = nullptr);
1328013267

13268+
enum CUDAFunctionTarget {
13269+
CFT_Device,
13270+
CFT_Global,
13271+
CFT_Host,
13272+
CFT_HostDevice,
13273+
CFT_InvalidTarget
13274+
};
13275+
1328113276
/// Determines whether the given function is a CUDA device/host/kernel/etc.
1328213277
/// function.
1328313278
///
@@ -13296,29 +13291,6 @@ class Sema final {
1329613291
/// Determines whether the given variable is emitted on host or device side.
1329713292
CUDAVariableTarget IdentifyCUDATarget(const VarDecl *D);
1329813293

13299-
/// Defines kinds of CUDA global host/device context where a function may be
13300-
/// called.
13301-
enum CUDATargetContextKind {
13302-
CTCK_Unknown, /// Unknown context
13303-
CTCK_InitGlobalVar, /// Function called during global variable
13304-
/// initialization
13305-
};
13306-
13307-
/// Define the current global CUDA host/device context where a function may be
13308-
/// called. Only used when a function is called outside of any functions.
13309-
struct CUDATargetContext {
13310-
CUDAFunctionTarget Target = CFT_HostDevice;
13311-
CUDATargetContextKind Kind = CTCK_Unknown;
13312-
Decl *D = nullptr;
13313-
} CurCUDATargetCtx;
13314-
13315-
struct CUDATargetContextRAII {
13316-
Sema &S;
13317-
CUDATargetContext SavedCtx;
13318-
CUDATargetContextRAII(Sema &S_, CUDATargetContextKind K, Decl *D);
13319-
~CUDATargetContextRAII() { S.CurCUDATargetCtx = SavedCtx; }
13320-
};
13321-
1332213294
/// Gets the CUDA target for the current context.
1332313295
CUDAFunctionTarget CurrentCUDATarget() {
1332413296
return IdentifyCUDATarget(dyn_cast<FunctionDecl>(CurContext));

clang/lib/Parse/ParseDecl.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2571,7 +2571,6 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
25712571
}
25722572
}
25732573

2574-
Sema::CUDATargetContextRAII X(Actions, Sema::CTCK_InitGlobalVar, ThisDecl);
25752574
switch (TheInitKind) {
25762575
// Parse declarator '=' initializer.
25772576
case InitKind::Equal: {

clang/lib/Sema/SemaCUDA.cpp

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -105,37 +105,19 @@ Sema::IdentifyCUDATarget(const ParsedAttributesView &Attrs) {
105105
}
106106

107107
template <typename A>
108-
static bool hasAttr(const Decl *D, bool IgnoreImplicitAttr) {
108+
static bool hasAttr(const FunctionDecl *D, bool IgnoreImplicitAttr) {
109109
return D->hasAttrs() && llvm::any_of(D->getAttrs(), [&](Attr *Attribute) {
110110
return isa<A>(Attribute) &&
111111
!(IgnoreImplicitAttr && Attribute->isImplicit());
112112
});
113113
}
114114

115-
Sema::CUDATargetContextRAII::CUDATargetContextRAII(Sema &S_,
116-
CUDATargetContextKind K,
117-
Decl *D)
118-
: S(S_) {
119-
SavedCtx = S.CurCUDATargetCtx;
120-
assert(K == CTCK_InitGlobalVar);
121-
auto *VD = dyn_cast_or_null<VarDecl>(D);
122-
if (VD && VD->hasGlobalStorage() && !VD->isStaticLocal()) {
123-
auto Target = CFT_Host;
124-
if ((hasAttr<CUDADeviceAttr>(VD, /*IgnoreImplicit=*/true) &&
125-
!hasAttr<CUDAHostAttr>(VD, /*IgnoreImplicit=*/true)) ||
126-
hasAttr<CUDASharedAttr>(VD, /*IgnoreImplicit=*/true) ||
127-
hasAttr<CUDAConstantAttr>(VD, /*IgnoreImplicit=*/true))
128-
Target = CFT_Device;
129-
S.CurCUDATargetCtx = {Target, K, VD};
130-
}
131-
}
132-
133115
/// IdentifyCUDATarget - Determine the CUDA compilation target for this function
134116
Sema::CUDAFunctionTarget Sema::IdentifyCUDATarget(const FunctionDecl *D,
135117
bool IgnoreImplicitHDAttr) {
136-
// Code that lives outside a function gets the target from CurCUDATargetCtx.
118+
// Code that lives outside a function is run on the host.
137119
if (D == nullptr)
138-
return CurCUDATargetCtx.Target;
120+
return CFT_Host;
139121

140122
if (D->hasAttr<CUDAInvalidTargetAttr>())
141123
return CFT_InvalidTarget;

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5317,8 +5317,7 @@ static void handleNoRandomizeLayoutAttr(Sema &S, Decl *D,
53175317
}
53185318

53195319
bool Sema::CheckCallingConvAttr(const ParsedAttr &Attrs, CallingConv &CC,
5320-
const FunctionDecl *FD,
5321-
CUDAFunctionTarget CFT) {
5320+
const FunctionDecl *FD) {
53225321
if (Attrs.isInvalid())
53235322
return true;
53245323

@@ -5417,8 +5416,7 @@ bool Sema::CheckCallingConvAttr(const ParsedAttr &Attrs, CallingConv &CC,
54175416
// on their host/device attributes.
54185417
if (LangOpts.CUDA) {
54195418
auto *Aux = Context.getAuxTargetInfo();
5420-
assert(FD || CFT != CFT_InvalidTarget);
5421-
auto CudaTarget = FD ? IdentifyCUDATarget(FD) : CFT;
5419+
auto CudaTarget = IdentifyCUDATarget(FD);
54225420
bool CheckHost = false, CheckDevice = false;
54235421
switch (CudaTarget) {
54245422
case CFT_HostDevice:

clang/lib/Sema/SemaOverload.cpp

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6699,19 +6699,17 @@ void Sema::AddOverloadCandidate(
66996699
}
67006700

67016701
// (CUDA B.1): Check for invalid calls between targets.
6702-
if (getLangOpts().CUDA) {
6703-
const FunctionDecl *Caller = getCurFunctionDecl(/*AllowLambda=*/true);
6704-
// Skip the check for callers that are implicit members, because in this
6705-
// case we may not yet know what the member's target is; the target is
6706-
// inferred for the member automatically, based on the bases and fields of
6707-
// the class.
6708-
if (!(Caller && Caller->isImplicit()) &&
6709-
!IsAllowedCUDACall(Caller, Function)) {
6710-
Candidate.Viable = false;
6711-
Candidate.FailureKind = ovl_fail_bad_target;
6712-
return;
6713-
}
6714-
}
6702+
if (getLangOpts().CUDA)
6703+
if (const FunctionDecl *Caller = getCurFunctionDecl(/*AllowLambda=*/true))
6704+
// Skip the check for callers that are implicit members, because in this
6705+
// case we may not yet know what the member's target is; the target is
6706+
// inferred for the member automatically, based on the bases and fields of
6707+
// the class.
6708+
if (!Caller->isImplicit() && !IsAllowedCUDACall(Caller, Function)) {
6709+
Candidate.Viable = false;
6710+
Candidate.FailureKind = ovl_fail_bad_target;
6711+
return;
6712+
}
67156713

67166714
if (Function->getTrailingRequiresClause()) {
67176715
ConstraintSatisfaction Satisfaction;
@@ -7223,11 +7221,12 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl,
72237221

72247222
// (CUDA B.1): Check for invalid calls between targets.
72257223
if (getLangOpts().CUDA)
7226-
if (!IsAllowedCUDACall(getCurFunctionDecl(/*AllowLambda=*/true), Method)) {
7227-
Candidate.Viable = false;
7228-
Candidate.FailureKind = ovl_fail_bad_target;
7229-
return;
7230-
}
7224+
if (const FunctionDecl *Caller = getCurFunctionDecl(/*AllowLambda=*/true))
7225+
if (!IsAllowedCUDACall(Caller, Method)) {
7226+
Candidate.Viable = false;
7227+
Candidate.FailureKind = ovl_fail_bad_target;
7228+
return;
7229+
}
72317230

72327231
if (Method->getTrailingRequiresClause()) {
72337232
ConstraintSatisfaction Satisfaction;
@@ -12498,12 +12497,10 @@ class AddressOfFunctionResolver {
1249812497
return false;
1249912498

1250012499
if (FunctionDecl *FunDecl = dyn_cast<FunctionDecl>(Fn)) {
12501-
if (S.getLangOpts().CUDA) {
12502-
FunctionDecl *Caller = S.getCurFunctionDecl(/*AllowLambda=*/true);
12503-
if (!(Caller && Caller->isImplicit()) &&
12504-
!S.IsAllowedCUDACall(Caller, FunDecl))
12505-
return false;
12506-
}
12500+
if (S.getLangOpts().CUDA)
12501+
if (FunctionDecl *Caller = S.getCurFunctionDecl(/*AllowLambda=*/true))
12502+
if (!Caller->isImplicit() && !S.IsAllowedCUDACall(Caller, FunDecl))
12503+
return false;
1250712504
if (FunDecl->isMultiVersion()) {
1250812505
const auto *TA = FunDecl->getAttr<TargetAttr>();
1250912506
if (TA && !TA->isDefaultVersion())

clang/lib/Sema/SemaType.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4055,8 +4055,7 @@ static CallingConv getCCForDeclaratorChunk(
40554055
// function type. We'll diagnose the failure to apply them in
40564056
// handleFunctionTypeAttr.
40574057
CallingConv CC;
4058-
if (!S.CheckCallingConvAttr(AL, CC, /*FunctionDecl=*/nullptr,
4059-
S.IdentifyCUDATarget(D.getAttributes())) &&
4058+
if (!S.CheckCallingConvAttr(AL, CC) &&
40604059
(!FTI.isVariadic || supportsVariadicCall(CC))) {
40614060
return CC;
40624061
}

clang/test/CodeGenCUDA/global-initializers.cu

Lines changed: 0 additions & 51 deletions
This file was deleted.
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -aux-triple x86_64-pc-windows-msvc -fms-compatibility -fcuda-is-device -fsyntax-only -verify %s
2-
// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -fms-compatibility -fsyntax-only -verify %s
32

43
__cdecl void hostf1();
54
__vectorcall void (*hostf2)() = hostf1; // expected-error {{cannot initialize a variable of type 'void ((*))() __attribute__((vectorcall))' with an lvalue of type 'void () __attribute__((cdecl))'}}

clang/test/SemaCUDA/function-overload.cu

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -222,13 +222,7 @@ __host__ __device__ void hostdevicef() {
222222
// Test for address of overloaded function resolution in the global context.
223223
HostFnPtr fp_h = h;
224224
HostFnPtr fp_ch = ch;
225-
#if defined (__CUDA_ARCH__)
226-
__device__
227-
#endif
228225
CurrentFnPtr fp_dh = dh;
229-
#if defined (__CUDA_ARCH__)
230-
__device__
231-
#endif
232226
CurrentFnPtr fp_cdh = cdh;
233227
GlobalFnPtr fp_g = g;
234228

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// RUN: %clang_cc1 %s --std=c++11 -triple x86_64-linux-unknown -fsyntax-only -o - -verify
2+
3+
#include "Inputs/cuda.h"
4+
5+
// Check that we get an error if we try to call a __device__ function from a
6+
// module initializer.
7+
8+
struct S {
9+
__device__ S() {}
10+
// expected-note@-1 {{'S' declared here}}
11+
};
12+
13+
S s;
14+
// expected-error@-1 {{reference to __device__ function 'S' in global initializer}}
15+
16+
struct T {
17+
__host__ __device__ T() {}
18+
};
19+
T t; // No error, this is OK.
20+
21+
struct U {
22+
__host__ U() {}
23+
__device__ U(int) {}
24+
// expected-note@-1 {{'U' declared here}}
25+
};
26+
U u(42);
27+
// expected-error@-1 {{reference to __device__ function 'U' in global initializer}}
28+
29+
__device__ int device_fn() { return 42; }
30+
// expected-note@-1 {{'device_fn' declared here}}
31+
int n = device_fn();
32+
// expected-error@-1 {{reference to __device__ function 'device_fn' in global initializer}}

clang/test/SemaCUDA/global-initializers.cu

Lines changed: 0 additions & 72 deletions
This file was deleted.

0 commit comments

Comments
 (0)