Skip to content

Commit 06b1455

Browse files
authored
[HLSL] Update type for out arguments only for dependent params types (#163832)
When a template function with `out` arguments is instantiated, only the arguments with dependent types need to have their `out` type updated to a restricted reference. Non-dependent argument types have already been converted and the template instantiation should not change that. Fixes #163648
1 parent e501a1f commit 06b1455

File tree

2 files changed

+96
-5
lines changed

2 files changed

+96
-5
lines changed

clang/lib/Sema/SemaTemplateInstantiateDecl.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -765,10 +765,18 @@ static bool isRelevantAttr(Sema &S, const Decl *D, const Attr *A) {
765765

766766
static void instantiateDependentHLSLParamModifierAttr(
767767
Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
768-
const HLSLParamModifierAttr *Attr, Decl *New) {
769-
ParmVarDecl *P = cast<ParmVarDecl>(New);
770-
P->addAttr(Attr->clone(S.getASTContext()));
771-
P->setType(S.HLSL().getInoutParameterType(P->getType()));
768+
const HLSLParamModifierAttr *Attr, const Decl *Old, Decl *New) {
769+
ParmVarDecl *NewParm = cast<ParmVarDecl>(New);
770+
NewParm->addAttr(Attr->clone(S.getASTContext()));
771+
772+
const Type *OldParmTy = cast<ParmVarDecl>(Old)->getType().getTypePtr();
773+
if (OldParmTy->isDependentType() && Attr->isAnyOut())
774+
NewParm->setType(S.HLSL().getInoutParameterType(NewParm->getType()));
775+
776+
assert(
777+
(!Attr->isAnyOut() || (NewParm->getType().isRestrictQualified() &&
778+
NewParm->getType()->isReferenceType())) &&
779+
"out or inout parameter type must be a reference and restrict qualified");
772780
}
773781

774782
void Sema::InstantiateAttrsForDecl(
@@ -923,7 +931,7 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
923931

924932
if (const auto *ParamAttr = dyn_cast<HLSLParamModifierAttr>(TmplAttr)) {
925933
instantiateDependentHLSLParamModifierAttr(*this, TemplateArgs, ParamAttr,
926-
New);
934+
Tmpl, New);
927935
continue;
928936
}
929937

clang/test/SemaHLSL/Language/TemplateOutArg.hlsl

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,81 @@ T buzz(int X, T Y) {
195195
return X + Y;
196196
}
197197

198+
// Case 4: Verify that the parameter modifier attributes are instantiated
199+
// for both templated and non-templated arguments, and that the non-templated
200+
// out argument type is not modified by the template instantiation.
201+
202+
// CHECK-LABEL: FunctionTemplateDecl {{.*}} fizz_two
203+
204+
// Check the pattern decl.
205+
// CHECK: FunctionDecl {{.*}} fizz_two 'void (inout T, out int)'
206+
// CHECK-NEXT: ParmVarDecl {{.*}} referenced V 'T'
207+
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} inout
208+
// CHECK-NEXT: ParmVarDecl {{.*}} referenced I 'int &__restrict'
209+
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
210+
211+
// Check the 3 instantiations (int, float, & double).
212+
213+
// CHECK-LABEL: FunctionDecl {{.*}} used fizz_two 'void (inout int, out int)' implicit_instantiation
214+
// CHECK: ParmVarDecl {{.*}} used V 'int &__restrict'
215+
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} inout
216+
// CHECK: ParmVarDecl {{.*}} used I 'int &__restrict'
217+
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
218+
219+
// CHECK-LABEL: FunctionDecl {{.*}} used fizz_two 'void (inout float, out int)' implicit_instantiation
220+
// CHECK: ParmVarDecl {{.*}} used V 'float &__restrict'
221+
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} inout
222+
// CHECK: ParmVarDecl {{.*}} used I 'int &__restrict'
223+
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
224+
225+
// CHECK-LABEL: FunctionDecl {{.*}} used fizz_two 'void (inout double, out int)' implicit_instantiation
226+
// CHECK: ParmVarDecl {{.*}} used V 'double &__restrict'
227+
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} inout
228+
// CHECK: ParmVarDecl {{.*}} used I 'int &__restrict'
229+
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
230+
template <typename T>
231+
void fizz_two(inout T V, out int I) {
232+
V += 2;
233+
I = V;
234+
}
235+
236+
// Case 5: Verify that `in` parameter modifier attributes are instantiated
237+
// for both templated and non-templated arguments and argument types are not
238+
// modified
239+
240+
// CHECK-LABEL: FunctionTemplateDecl {{.*}} buzz_two
241+
242+
// Check the pattern decl.
243+
// CHECK: FunctionDecl {{.*}} buzz_two 'int (T, int)'
244+
// CHECK-NEXT: ParmVarDecl {{.*}} referenced A 'T'
245+
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} in
246+
// CHECK-NEXT: ParmVarDecl {{.*}} referenced B 'int'
247+
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} in
248+
249+
// Check the 3 instantiations (int, float, & double).
250+
251+
// CHECK-LABEL: FunctionDecl {{.*}} used buzz_two 'int (int, int)' implicit_instantiation
252+
// CHECK: ParmVarDecl {{.*}} used A 'int'
253+
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} in
254+
// CHECK: ParmVarDecl {{.*}} used B 'int'
255+
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} in
256+
257+
// CHECK-LABEL: FunctionDecl {{.*}} used buzz_two 'int (float, int)' implicit_instantiation
258+
// CHECK: ParmVarDecl {{.*}} used A 'float'
259+
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} in
260+
// CHECK: ParmVarDecl {{.*}} used B 'int'
261+
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} in
262+
263+
// CHECK-LABEL: FunctionDecl {{.*}} used buzz_two 'int (double, int)' implicit_instantiation
264+
// CHECK: ParmVarDecl {{.*}} used A 'double'
265+
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} in
266+
// CHECK: ParmVarDecl {{.*}} used B 'int'
267+
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} in
268+
template <typename T>
269+
int buzz_two(in T A, in int B) {
270+
return A + B;
271+
}
272+
198273
export void caller() {
199274
int X = 2;
200275
float Y = 3.3;
@@ -211,4 +286,12 @@ export void caller() {
211286
X = buzz(X, X);
212287
Y = buzz(X, Y);
213288
Z = buzz(X, Z);
289+
290+
fizz_two(X, X);
291+
fizz_two(Y, X);
292+
fizz_two(Z, X);
293+
294+
X = buzz_two(X, X);
295+
X = buzz_two(Y, X);
296+
X = buzz_two(Z, X);
214297
}

0 commit comments

Comments
 (0)