Переглянути джерело

[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.
Chris B 2 роки тому
батько
коміт
4271f47e7b

+ 3 - 2
tools/clang/lib/Sema/SemaTemplate.cpp

@@ -2054,9 +2054,10 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
     return QualType();
     return QualType();
 
 
   // HLSL Change Starts - check template values for HLSL object/matrix/vector signatures
   // HLSL Change Starts - check template values for HLSL object/matrix/vector signatures
-  if (getLangOpts().HLSL && hlsl::CheckTemplateArgumentListForHLSL(*this, Template, TemplateLoc, TemplateArgs)) {
+  if (getLangOpts().HLSL && Template->isImplicit() &&
+      hlsl::CheckTemplateArgumentListForHLSL(*this, Template, TemplateLoc,
+                                             TemplateArgs))
     return QualType();
     return QualType();
-  }
   // HLSL Change Ends
   // HLSL Change Ends
 
 
   QualType CanonType;
   QualType CanonType;

+ 35 - 0
tools/clang/test/HLSLFileCheck/hlsl/template/4771-udt-parameter-validation.hlsl

@@ -0,0 +1,35 @@
+// RUN: %dxc -T lib_6_3 -HV 2021 -ast-dump %s | FileCheck %s
+template<typename T>
+struct Leg {
+    static T zero() {
+        return (T)0;
+    }
+};
+
+template<class Animal>
+typename Animal::LegType getLegs(Animal A) {
+  return A.Legs + Leg<typename Animal::LegType>::zero();
+}
+
+// CHECK:      FunctionTemplateDecl {{0x[0-9a-fA-F]+}} <line:9:1, line:12:1> line:10:26 getLegs
+// CHECK:      CXXDependentScopeMemberExpr {{0x[0-9a-fA-F]+}} <col:10, col:12> '<dependent type>' lvalue
+// CHECK: DeclRefExpr {{0x[0-9a-fA-F]+}} <col:10> 'Animal' lvalue ParmVar {{0x[0-9a-fA-F]+}} 'A' 'Animal'
+// CHECK-NEXT: CallExpr {{0x[0-9a-fA-F]+}} <col:19, col:55> '<dependent type>'
+// CHECK-NEXT: DependentScopeDeclRefExpr {{0x[0-9a-fA-F]+}} <col:19, col:50> '<dependent type>' lvalue
+
+// CHECK: FunctionDecl {{0x[0-9a-fA-F]+}} <line:10:1, line:12:1> line:10:26 used getLegs 'typename Pup::LegType (Pup)'
+// CHECK-NEXT: TemplateArgument type 'Pup'
+// CHECK:      DeclRefExpr {{0x[0-9a-fA-F]+}} <col:10> 'Pup':'Pup' lvalue ParmVar {{0x[0-9a-fA-F]+}} 'A' 'Pup':'Pup'
+// CHECK-NEXT: CallExpr {{0x[0-9a-fA-F]+}} <col:19, col:55> 'int':'int'
+// CHECK-NEXT: ImplicitCastExpr {{0x[0-9a-fA-F]+}} <col:19, col:50> 'int (*)()' <FunctionToPointerDecay>
+// CHECK-NEXT: DeclRefExpr {{0x[0-9a-fA-F]+}} <col:19, col:50> 'int ()' lvalue CXXMethod {{0x[0-9a-fA-F]+}} 'zero' 'int ()'
+
+struct Pup {
+  using LegType = int;
+  LegType Legs;
+};
+
+int Fn() {
+  Pup P = {0};
+  return getLegs<Pup>(P);
+}