Skip to content

Commit 4271f47

Browse files
authored
[HLSL2021] UDT template parms follow C++ rules (#4844)
HLSL built-in templates have some special rules for verifying template type parameters. These break with some common C++ template patterns. This change applies HLSL template argument validation only to HLSL implicit templates.
1 parent baae5dd commit 4271f47

2 files changed

Lines changed: 38 additions & 2 deletions

File tree

tools/clang/lib/Sema/SemaTemplate.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2054,9 +2054,10 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
20542054
return QualType();
20552055

20562056
// HLSL Change Starts - check template values for HLSL object/matrix/vector signatures
2057-
if (getLangOpts().HLSL && hlsl::CheckTemplateArgumentListForHLSL(*this, Template, TemplateLoc, TemplateArgs)) {
2057+
if (getLangOpts().HLSL && Template->isImplicit() &&
2058+
hlsl::CheckTemplateArgumentListForHLSL(*this, Template, TemplateLoc,
2059+
TemplateArgs))
20582060
return QualType();
2059-
}
20602061
// HLSL Change Ends
20612062

20622063
QualType CanonType;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// RUN: %dxc -T lib_6_3 -HV 2021 -ast-dump %s | FileCheck %s
2+
template<typename T>
3+
struct Leg {
4+
static T zero() {
5+
return (T)0;
6+
}
7+
};
8+
9+
template<class Animal>
10+
typename Animal::LegType getLegs(Animal A) {
11+
return A.Legs + Leg<typename Animal::LegType>::zero();
12+
}
13+
14+
// CHECK: FunctionTemplateDecl {{0x[0-9a-fA-F]+}} <line:9:1, line:12:1> line:10:26 getLegs
15+
// CHECK: CXXDependentScopeMemberExpr {{0x[0-9a-fA-F]+}} <col:10, col:12> '<dependent type>' lvalue
16+
// CHECK: DeclRefExpr {{0x[0-9a-fA-F]+}} <col:10> 'Animal' lvalue ParmVar {{0x[0-9a-fA-F]+}} 'A' 'Animal'
17+
// CHECK-NEXT: CallExpr {{0x[0-9a-fA-F]+}} <col:19, col:55> '<dependent type>'
18+
// CHECK-NEXT: DependentScopeDeclRefExpr {{0x[0-9a-fA-F]+}} <col:19, col:50> '<dependent type>' lvalue
19+
20+
// CHECK: FunctionDecl {{0x[0-9a-fA-F]+}} <line:10:1, line:12:1> line:10:26 used getLegs 'typename Pup::LegType (Pup)'
21+
// CHECK-NEXT: TemplateArgument type 'Pup'
22+
// CHECK: DeclRefExpr {{0x[0-9a-fA-F]+}} <col:10> 'Pup':'Pup' lvalue ParmVar {{0x[0-9a-fA-F]+}} 'A' 'Pup':'Pup'
23+
// CHECK-NEXT: CallExpr {{0x[0-9a-fA-F]+}} <col:19, col:55> 'int':'int'
24+
// CHECK-NEXT: ImplicitCastExpr {{0x[0-9a-fA-F]+}} <col:19, col:50> 'int (*)()' <FunctionToPointerDecay>
25+
// CHECK-NEXT: DeclRefExpr {{0x[0-9a-fA-F]+}} <col:19, col:50> 'int ()' lvalue CXXMethod {{0x[0-9a-fA-F]+}} 'zero' 'int ()'
26+
27+
struct Pup {
28+
using LegType = int;
29+
LegType Legs;
30+
};
31+
32+
int Fn() {
33+
Pup P = {0};
34+
return getLegs<Pup>(P);
35+
}

0 commit comments

Comments
 (0)