Skip to content

Commit 21a443f

Browse files
Erich Keanebader
Erich Keane
authored andcommitted
[SYCL] Fix cast of __ocl_sampler_t type in member initializer
Since OpenCL/OpenCLCXX doesn't permit the sample_t to be used as a struct member, Clang lacks any implementation of member initialization in a constructor. This results in the initializer doing an assignment from an LValue, which causes Sema to issue a warning that binding a reference to a stack allocated parameter (-Wdangling-field) when attempting to initialize a member from a constructor parameter. This warning is obviously wrong, however is a result of a malformed AST, mostly that assigning an LValue from an LValue isn't legal. This patch correctly inserts an LValue to RValue cast in this situation, which prevents the warning seen in the header and should avoid an assert in the future if one is added to later validate this behavior. Signed-off-by: Erich Keane <[email protected]>
1 parent bb7cb34 commit 21a443f

File tree

2 files changed

+60
-5
lines changed

2 files changed

+60
-5
lines changed

clang/lib/Sema/SemaInit.cpp

+15-5
Original file line numberDiff line numberDiff line change
@@ -8096,9 +8096,10 @@ ExprResult InitializationSequence::Perform(Sema &S,
80968096
// 1a. argument is a file-scope variable
80978097
// 1b. argument is a function-scope variable
80988098
// 1c. argument is one of caller function's parameters
8099-
// 2. variable initialization
8100-
// 2a. initializing a file-scope variable
8101-
// 2b. initializing a function-scope variable
8099+
// 2. member initialization from a variable
8100+
// 3. variable initialization
8101+
// 3a. initializing a file-scope variable
8102+
// 3b. initializing a function-scope variable
81028103
//
81038104
// For file-scope variables, since they cannot be initialized by function
81048105
// call of __translate_sampler_initializer in LLVM IR, their references
@@ -8138,8 +8139,17 @@ ExprResult InitializationSequence::Perform(Sema &S,
81388139
Var->getInit()))->getSubExpr();
81398140
SourceType = Init->getType();
81408141
}
8142+
} else if (Entity.getKind() == InitializedEntity::EK_Member &&
8143+
!Entity.isImplicitMemberInitializer() &&
8144+
!Entity.isDefaultMemberInitializer() &&
8145+
isa<DeclRefExpr>(Init)) {
8146+
// Case 2: Member initialization from a variable.
8147+
CurInit =
8148+
ImplicitCastExpr::Create(S.Context, Step->Type, CK_LValueToRValue,
8149+
Init, /*BasePath=*/nullptr, VK_RValue);
8150+
break;
81418151
} else {
8142-
// Case 2
8152+
// Case 3
81438153
// Check initializer is 32 bit integer constant.
81448154
// If the initializer is taken from global variable, do not diagnose since
81458155
// this has already been done when parsing the variable declaration.
@@ -8177,7 +8187,7 @@ ExprResult InitializationSequence::Perform(Sema &S,
81778187
<< "Addressing Mode";
81788188
}
81798189

8180-
// Cases 1a, 2a and 2b
8190+
// Cases 1a, 3a and 3b
81818191
// Insert cast from integer to sampler.
81828192
CurInit = S.ImpCastExprToType(Init, S.Context.OCLSamplerTy,
81838193
CK_IntToOCLSampler);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// RUN: %clang_cc1 %s -fsycl-is-device -ast-dump 2>&1 | FileCheck %s
2+
3+
const __ocl_sampler_t Global = 0;
4+
5+
class Foo {
6+
int i;
7+
__ocl_sampler_t Member;
8+
__ocl_sampler_t Member2;
9+
__ocl_sampler_t Member3;
10+
__ocl_sampler_t Member4;
11+
12+
Foo(__ocl_sampler_t Param) :
13+
// CHECK: CXXConstructorDecl
14+
// CHECK-SAME: Foo 'void (__ocl_sampler_t)'
15+
Member(Param),
16+
// CHECK: CXXCtorInitializer Field
17+
// CHECK-SAME: 'Member' '__ocl_sampler_t':'sampler_t'
18+
// CHECK-NEXT: ImplicitCastExpr
19+
// CHECK-SAME: '__ocl_sampler_t':'sampler_t' <LValueToRValue>
20+
// CHECK-NEXT: DeclRefExpr
21+
// CHECK-SAME: lvalue ParmVar
22+
// CHECK-SAME: 'Param' '__ocl_sampler_t':'sampler_t'
23+
Member2(4),
24+
// CHECK: CXXCtorInitializer Field
25+
// CHECK-SAME: 'Member2' '__ocl_sampler_t':'sampler_t'
26+
// CHECK-NEXT: ImplicitCastExpr
27+
// CHECK-SAME: 'sampler_t' <IntToOCLSampler>
28+
// CHECK-NEXT: IntegerLiteral
29+
// CHECK-SAME: 'int' 4
30+
Member3(),
31+
// CHECK: CXXCtorInitializer Field
32+
// CHECK-SAME: 'Member3' '__ocl_sampler_t':'sampler_t'
33+
// CHECK-NEXT: ImplicitValueInitExpr
34+
// CHECK-SAME: '__ocl_sampler_t':'sampler_t'
35+
Member4(Global)
36+
// CHECK: CXXCtorInitializer Field
37+
// CHECK-SAME: 'Member4' '__ocl_sampler_t':'sampler_t'
38+
// CHECK-NEXT: ImplicitCastExpr
39+
// CHECK-SAME: '__ocl_sampler_t':'sampler_t' <LValueToRValue>
40+
// CHECK-NEXT: DeclRefExpr
41+
// CHECK-SAME: lvalue Var
42+
// CHECK-SAME: 'Global' 'const __ocl_sampler_t':'const sampler_t'
43+
{}
44+
};
45+

0 commit comments

Comments
 (0)