https://github.com/bob80905 updated 
https://github.com/llvm/llvm-project/pull/174028

>From 44ff1d1605aefc0dbd197397db9124346dd2411b Mon Sep 17 00:00:00 2001
From: Joshua Batista <[email protected]>
Date: Tue, 30 Dec 2025 13:46:14 -0800
Subject: [PATCH 1/7] first attempt

---
 .../clang/Basic/DiagnosticSemaKinds.td        |   1 +
 clang/lib/Sema/SemaHLSL.cpp                   | 102 ++++++++++++++++++
 ...esource_binding_attr_error_uint32_max.hlsl |  31 ++++++
 3 files changed, 134 insertions(+)
 create mode 100644 
clang/test/SemaHLSL/resource_binding_attr_error_uint32_max.hlsl

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 6c6a26614ad0e..3807d1dab728a 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -13336,6 +13336,7 @@ def warn_hlsl_register_type_c_packoffset: 
Warning<"binding type 'c' ignored in b
 def warn_hlsl_deprecated_register_type_b: Warning<"binding type 'b' only 
applies to constant buffers. The 'bool constant' binding type is no longer 
supported">, InGroup<LegacyConstantRegisterBinding>, DefaultError;
 def warn_hlsl_deprecated_register_type_i: Warning<"binding type 'i' ignored. 
The 'integer constant' binding type is no longer supported">, 
InGroup<LegacyConstantRegisterBinding>, DefaultError;
 def err_hlsl_unsupported_register_number : Error<"register number should be an 
integer">;
+def err_hlsl_register_number_too_large : Error<"register number should not 
exceed UINT32_MAX, 4294967295">;
 def err_hlsl_expected_space : Error<"invalid space specifier '%0' used; 
expected 'space' followed by an integer, like space1">;
 def err_hlsl_space_on_global_constant : Error<"register space cannot be 
specified on global constants">;
 def warn_hlsl_implicit_binding : Warning<"resource has implicit register 
binding">, InGroup<HLSLImplicitBinding>, DefaultIgnore;
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index a6de1cd550212..7760b1f791374 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -2361,6 +2361,99 @@ static bool DiagnoseHLSLRegisterAttribute(Sema &S, 
SourceLocation &ArgLoc,
   return ValidateMultipleRegisterAnnotations(S, D, RegType);
 }
 
+bool ExceedsUInt32Max(llvm::StringRef S) {
+  constexpr size_t MaxDigits = 10; // UINT32_MAX = 4294967295
+  if (S.size() > MaxDigits)
+    return true;
+
+  if (S.size() < MaxDigits)
+    return false;
+
+  return S.compare("4294967295") > 0;
+}
+
+// return false if the slot count exceeds the limit, true otherwise
+static bool AccumulateHLSLResourceSlots(QualType Ty, llvm::APInt &SlotCount,
+                                        const llvm::APInt &Limit,
+                                        ASTContext &Ctx,
+                                        uint64_t Multiplier = 1) {
+  Ty = Ty.getCanonicalType();
+  const Type *T = Ty.getTypePtr();
+
+  // Early exit if already overflowed
+  if (SlotCount.ugt(Limit))
+    return false;
+
+  // Case 1: array type
+  if (const auto *AT = dyn_cast<ArrayType>(T)) {
+    uint64_t Count = 1;
+
+    if (const auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
+      Count = CAT->getSize().getZExtValue();
+    }
+    // TODO: how do we handle non constant resource arrays?
+
+    QualType ElemTy = AT->getElementType();
+
+    return AccumulateHLSLResourceSlots(ElemTy, SlotCount, Limit, Ctx,
+                                       Multiplier * Count);
+  }
+
+  // Case 2: resource leaf
+  if (T->isHLSLResourceRecord()) {
+    llvm::APInt Add(SlotCount.getBitWidth(), Multiplier);
+    SlotCount += Add;
+    return SlotCount.ule(Limit);
+  }
+
+  // Case 3: struct / record
+  if (const auto *RT = dyn_cast<RecordType>(T)) {
+    const RecordDecl *RD = RT->getDecl();
+    for (const FieldDecl *Field : RD->fields()) {
+      if (!AccumulateHLSLResourceSlots(Field->getType(), SlotCount, Limit, Ctx,
+                                       Multiplier))
+        return false;
+    }
+    return true;
+  }
+
+  // Case 4: everything else
+  return true;
+}
+
+// return true if there is something invalid, false otherwise
+bool ValidateRegisterNumber(StringRef SlotNumStr, Decl *TheDecl,
+                            ASTContext &Ctx) {
+  if (ExceedsUInt32Max(SlotNumStr))
+    return true;
+
+  llvm::APInt SlotNum;
+  if (SlotNumStr.getAsInteger(10, SlotNum))
+    return false;
+  SlotNum = SlotNum.zext(64);
+
+  // uint32_max isn't 64 bits, but this int should
+  // have a 64 bit width in case it is compared to
+  // another 64 bit-width value. Assert failure otherwise.
+  llvm::APInt Limit(64, UINT32_MAX);
+  VarDecl *VD = dyn_cast<VarDecl>(TheDecl);
+  if (VD) {
+    AccumulateHLSLResourceSlots(VD->getType(), SlotNum, Limit, Ctx);
+    return SlotNum.ugt(Limit);
+  }
+  // handle the cbuffer case
+  HLSLBufferDecl *HBD = dyn_cast<HLSLBufferDecl>(TheDecl);
+  if (HBD) {
+    // resources cannot be put within a cbuffer, so no need
+    // to analyze the structure since the register number
+    // won't be pushed any higher.
+    return SlotNum.ugt(Limit);
+  }
+
+  // we don't expect any other decl type, so fail
+  return true;
+}
+
 void SemaHLSL::handleResourceBindingAttr(Decl *TheDecl, const ParsedAttr &AL) {
   if (VarDecl *VD = dyn_cast<VarDecl>(TheDecl)) {
     QualType Ty = VD->getType();
@@ -2420,6 +2513,15 @@ void SemaHLSL::handleResourceBindingAttr(Decl *TheDecl, 
const ParsedAttr &AL) {
       return;
     }
     StringRef SlotNumStr = Slot.substr(1);
+
+    // Validate register number. It should not exceed UINT32_MAX,
+    // including if the resource type is an array that starts
+    // before UINT32_MAX, but ends afterwards.
+    if (ValidateRegisterNumber(SlotNumStr, TheDecl, getASTContext())) {
+      Diag(SlotLoc, diag::err_hlsl_register_number_too_large);
+      return;
+    }
+
     unsigned N;
     if (SlotNumStr.getAsInteger(10, N)) {
       Diag(SlotLoc, diag::err_hlsl_unsupported_register_number);
diff --git a/clang/test/SemaHLSL/resource_binding_attr_error_uint32_max.hlsl 
b/clang/test/SemaHLSL/resource_binding_attr_error_uint32_max.hlsl
new file mode 100644
index 0000000000000..81a51fb601e54
--- /dev/null
+++ b/clang/test/SemaHLSL/resource_binding_attr_error_uint32_max.hlsl
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -o - 
-fsyntax-only %s -verify
+
+// test semantic validation for register numbers that exceed UINT32_MAX
+
+struct S {
+  RWBuffer<float> A[4];
+  RWBuffer<int> B[10];
+};
+
+// test that S.A carries the register number over the limit and emits the error
+// expected-error@+1 {{register number should not exceed UINT32_MAX, 
4294967295}}
+S s : register(u4294967294); // UINT32_MAX - 1
+
+// test the error is also triggered when analyzing S.B
+// expected-error@+1 {{register number should not exceed UINT32_MAX, 
4294967295}}
+S s2 : register(u4294967289);
+
+// test a standard resource array
+// expected-error@+1 {{register number should not exceed UINT32_MAX, 
4294967295}}
+RWBuffer<float> Buf[10] : register(u4294967294); 
+
+// test directly an excessively high register number.
+// expected-error@+1 {{register number should not exceed UINT32_MAX, 
4294967295}}
+RWBuffer<float> A : register(u9995294967294);
+
+// test a struct within a cbuffer
+// expected-error@+1 {{register number should not exceed UINT32_MAX, 
4294967295}}
+cbuffer MyCB : register(b9995294967294) {
+  float F[4];
+  int   I[10];
+};

>From 6ffc9ec83357b45c59439a0eaaad5081c64f9d49 Mon Sep 17 00:00:00 2001
From: Joshua Batista <[email protected]>
Date: Tue, 30 Dec 2025 13:57:39 -0800
Subject: [PATCH 2/7] add some more tests

---
 ...resource_binding_attr_error_uint32_max.hlsl | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/clang/test/SemaHLSL/resource_binding_attr_error_uint32_max.hlsl 
b/clang/test/SemaHLSL/resource_binding_attr_error_uint32_max.hlsl
index 81a51fb601e54..70a226337ef6a 100644
--- a/clang/test/SemaHLSL/resource_binding_attr_error_uint32_max.hlsl
+++ b/clang/test/SemaHLSL/resource_binding_attr_error_uint32_max.hlsl
@@ -7,6 +7,11 @@ struct S {
   RWBuffer<int> B[10];
 };
 
+// do some more nesting
+struct S2 {
+  S a[3];
+};
+
 // test that S.A carries the register number over the limit and emits the error
 // expected-error@+1 {{register number should not exceed UINT32_MAX, 
4294967295}}
 S s : register(u4294967294); // UINT32_MAX - 1
@@ -15,9 +20,17 @@ S s : register(u4294967294); // UINT32_MAX - 1
 // expected-error@+1 {{register number should not exceed UINT32_MAX, 
4294967295}}
 S s2 : register(u4294967289);
 
+
+// test the error is also triggered when analyzing S2.a[1].B
+// expected-error@+1 {{register number should not exceed UINT32_MAX, 
4294967295}}
+S2 s3 : register(u4294967275);
+
+// expected-error@+1 {{register number should not exceed UINT32_MAX, 
4294967295}}
+RWBuffer<float> Buf[10][10] : register(u4294967234);
+
 // test a standard resource array
 // expected-error@+1 {{register number should not exceed UINT32_MAX, 
4294967295}}
-RWBuffer<float> Buf[10] : register(u4294967294); 
+RWBuffer<float> Buf2[10] : register(u4294967294); 
 
 // test directly an excessively high register number.
 // expected-error@+1 {{register number should not exceed UINT32_MAX, 
4294967295}}
@@ -29,3 +42,6 @@ cbuffer MyCB : register(b9995294967294) {
   float F[4];
   int   I[10];
 };
+
+// no errors expected, all 100 register numbers are occupied here
+RWBuffer<float> Buf3[10][10] : register(u4294967194); 

>From 8d838fcfcf86ce2a78ab795e0f9518eeb2b12e5e Mon Sep 17 00:00:00 2001
From: Joshua Batista <[email protected]>
Date: Tue, 30 Dec 2025 14:07:09 -0800
Subject: [PATCH 3/7] adjust comment

---
 clang/test/SemaHLSL/resource_binding_attr_error_uint32_max.hlsl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/SemaHLSL/resource_binding_attr_error_uint32_max.hlsl 
b/clang/test/SemaHLSL/resource_binding_attr_error_uint32_max.hlsl
index 70a226337ef6a..d2e089391143c 100644
--- a/clang/test/SemaHLSL/resource_binding_attr_error_uint32_max.hlsl
+++ b/clang/test/SemaHLSL/resource_binding_attr_error_uint32_max.hlsl
@@ -36,7 +36,7 @@ RWBuffer<float> Buf2[10] : register(u4294967294);
 // expected-error@+1 {{register number should not exceed UINT32_MAX, 
4294967295}}
 RWBuffer<float> A : register(u9995294967294);
 
-// test a struct within a cbuffer
+// test a cbuffer directly with an excessively high register number.
 // expected-error@+1 {{register number should not exceed UINT32_MAX, 
4294967295}}
 cbuffer MyCB : register(b9995294967294) {
   float F[4];

>From 8968c821e246667c24c8d7430aa89e54bb3c8dfc Mon Sep 17 00:00:00 2001
From: Joshua Batista <[email protected]>
Date: Wed, 31 Dec 2025 00:39:59 -0800
Subject: [PATCH 4/7] address Damyan

---
 .../clang/Basic/DiagnosticSemaKinds.td        |  2 +-
 clang/lib/Sema/SemaHLSL.cpp                   | 59 +++++++------------
 ...esource_binding_attr_error_uint32_max.hlsl | 20 ++++---
 3 files changed, 35 insertions(+), 46 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 3807d1dab728a..38205d6087f68 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -13336,7 +13336,7 @@ def warn_hlsl_register_type_c_packoffset: 
Warning<"binding type 'c' ignored in b
 def warn_hlsl_deprecated_register_type_b: Warning<"binding type 'b' only 
applies to constant buffers. The 'bool constant' binding type is no longer 
supported">, InGroup<LegacyConstantRegisterBinding>, DefaultError;
 def warn_hlsl_deprecated_register_type_i: Warning<"binding type 'i' ignored. 
The 'integer constant' binding type is no longer supported">, 
InGroup<LegacyConstantRegisterBinding>, DefaultError;
 def err_hlsl_unsupported_register_number : Error<"register number should be an 
integer">;
-def err_hlsl_register_number_too_large : Error<"register number should not 
exceed UINT32_MAX, 4294967295">;
+def err_hlsl_register_number_too_large : Error<"register number should not 
exceed 4294967295">;
 def err_hlsl_expected_space : Error<"invalid space specifier '%0' used; 
expected 'space' followed by an integer, like space1">;
 def err_hlsl_space_on_global_constant : Error<"register space cannot be 
specified on global constants">;
 def warn_hlsl_implicit_binding : Warning<"resource has implicit register 
binding">, InGroup<HLSLImplicitBinding>, DefaultIgnore;
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 7760b1f791374..157c6c0f6def7 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -2361,27 +2361,15 @@ static bool DiagnoseHLSLRegisterAttribute(Sema &S, 
SourceLocation &ArgLoc,
   return ValidateMultipleRegisterAnnotations(S, D, RegType);
 }
 
-bool ExceedsUInt32Max(llvm::StringRef S) {
-  constexpr size_t MaxDigits = 10; // UINT32_MAX = 4294967295
-  if (S.size() > MaxDigits)
-    return true;
-
-  if (S.size() < MaxDigits)
-    return false;
-
-  return S.compare("4294967295") > 0;
-}
-
 // return false if the slot count exceeds the limit, true otherwise
-static bool AccumulateHLSLResourceSlots(QualType Ty, llvm::APInt &SlotCount,
-                                        const llvm::APInt &Limit,
-                                        ASTContext &Ctx,
+static bool AccumulateHLSLResourceSlots(QualType Ty, uint64_t &SlotCount,
+                                        const uint64_t &Limit, ASTContext &Ctx,
                                         uint64_t Multiplier = 1) {
   Ty = Ty.getCanonicalType();
   const Type *T = Ty.getTypePtr();
 
   // Early exit if already overflowed
-  if (SlotCount.ugt(Limit))
+  if (SlotCount > Limit)
     return false;
 
   // Case 1: array type
@@ -2391,19 +2379,17 @@ static bool AccumulateHLSLResourceSlots(QualType Ty, 
llvm::APInt &SlotCount,
     if (const auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
       Count = CAT->getSize().getZExtValue();
     }
-    // TODO: how do we handle non constant resource arrays?
 
     QualType ElemTy = AT->getElementType();
-
     return AccumulateHLSLResourceSlots(ElemTy, SlotCount, Limit, Ctx,
                                        Multiplier * Count);
   }
 
   // Case 2: resource leaf
   if (T->isHLSLResourceRecord()) {
-    llvm::APInt Add(SlotCount.getBitWidth(), Multiplier);
-    SlotCount += Add;
-    return SlotCount.ule(Limit);
+
+    SlotCount += Multiplier;
+    return SlotCount <= Limit;
   }
 
   // Case 3: struct / record
@@ -2422,24 +2408,17 @@ static bool AccumulateHLSLResourceSlots(QualType Ty, 
llvm::APInt &SlotCount,
 }
 
 // return true if there is something invalid, false otherwise
-bool ValidateRegisterNumber(StringRef SlotNumStr, Decl *TheDecl,
-                            ASTContext &Ctx) {
-  if (ExceedsUInt32Max(SlotNumStr))
-    return true;
-
-  llvm::APInt SlotNum;
+static bool ValidateRegisterNumber(StringRef SlotNumStr, Decl *TheDecl,
+                                   ASTContext &Ctx) {
+  uint64_t SlotNum;
   if (SlotNumStr.getAsInteger(10, SlotNum))
     return false;
-  SlotNum = SlotNum.zext(64);
 
-  // uint32_max isn't 64 bits, but this int should
-  // have a 64 bit width in case it is compared to
-  // another 64 bit-width value. Assert failure otherwise.
-  llvm::APInt Limit(64, UINT32_MAX);
+  uint64_t Limit = UINT32_MAX;
   VarDecl *VD = dyn_cast<VarDecl>(TheDecl);
   if (VD) {
     AccumulateHLSLResourceSlots(VD->getType(), SlotNum, Limit, Ctx);
-    return SlotNum.ugt(Limit);
+    return SlotNum > Limit;
   }
   // handle the cbuffer case
   HLSLBufferDecl *HBD = dyn_cast<HLSLBufferDecl>(TheDecl);
@@ -2447,7 +2426,7 @@ bool ValidateRegisterNumber(StringRef SlotNumStr, Decl 
*TheDecl,
     // resources cannot be put within a cbuffer, so no need
     // to analyze the structure since the register number
     // won't be pushed any higher.
-    return SlotNum.ugt(Limit);
+    return SlotNum > Limit;
   }
 
   // we don't expect any other decl type, so fail
@@ -2514,6 +2493,13 @@ void SemaHLSL::handleResourceBindingAttr(Decl *TheDecl, 
const ParsedAttr &AL) {
     }
     StringRef SlotNumStr = Slot.substr(1);
 
+    unsigned N;
+    // validate that the stringref has a non-empty number
+    if (SlotNumStr.empty() || !llvm::all_of(SlotNumStr, llvm::isDigit)) {
+      Diag(SlotLoc, diag::err_hlsl_unsupported_register_number);
+      return;
+    }
+
     // Validate register number. It should not exceed UINT32_MAX,
     // including if the resource type is an array that starts
     // before UINT32_MAX, but ends afterwards.
@@ -2522,11 +2508,8 @@ void SemaHLSL::handleResourceBindingAttr(Decl *TheDecl, 
const ParsedAttr &AL) {
       return;
     }
 
-    unsigned N;
-    if (SlotNumStr.getAsInteger(10, N)) {
-      Diag(SlotLoc, diag::err_hlsl_unsupported_register_number);
-      return;
-    }
+    // this shouldn't fail now that it's validated.
+    assert(!SlotNumStr.getAsInteger(10, N));
     SlotNum = N;
   }
 
diff --git a/clang/test/SemaHLSL/resource_binding_attr_error_uint32_max.hlsl 
b/clang/test/SemaHLSL/resource_binding_attr_error_uint32_max.hlsl
index d2e089391143c..9f2f4b0a7d816 100644
--- a/clang/test/SemaHLSL/resource_binding_attr_error_uint32_max.hlsl
+++ b/clang/test/SemaHLSL/resource_binding_attr_error_uint32_max.hlsl
@@ -13,31 +13,31 @@ struct S2 {
 };
 
 // test that S.A carries the register number over the limit and emits the error
-// expected-error@+1 {{register number should not exceed UINT32_MAX, 
4294967295}}
+// expected-error@+1 {{register number should not exceed 4294967295}}
 S s : register(u4294967294); // UINT32_MAX - 1
 
 // test the error is also triggered when analyzing S.B
-// expected-error@+1 {{register number should not exceed UINT32_MAX, 
4294967295}}
+// expected-error@+1 {{register number should not exceed 4294967295}}
 S s2 : register(u4294967289);
 
 
 // test the error is also triggered when analyzing S2.a[1].B
-// expected-error@+1 {{register number should not exceed UINT32_MAX, 
4294967295}}
+// expected-error@+1 {{register number should not exceed 4294967295}}
 S2 s3 : register(u4294967275);
 
-// expected-error@+1 {{register number should not exceed UINT32_MAX, 
4294967295}}
+// expected-error@+1 {{register number should not exceed 4294967295}}
 RWBuffer<float> Buf[10][10] : register(u4294967234);
 
 // test a standard resource array
-// expected-error@+1 {{register number should not exceed UINT32_MAX, 
4294967295}}
+// expected-error@+1 {{register number should not exceed 4294967295}}
 RWBuffer<float> Buf2[10] : register(u4294967294); 
 
 // test directly an excessively high register number.
-// expected-error@+1 {{register number should not exceed UINT32_MAX, 
4294967295}}
+// expected-error@+1 {{register number should not exceed 4294967295}}
 RWBuffer<float> A : register(u9995294967294);
 
 // test a cbuffer directly with an excessively high register number.
-// expected-error@+1 {{register number should not exceed UINT32_MAX, 
4294967295}}
+// expected-error@+1 {{register number should not exceed 4294967295}}
 cbuffer MyCB : register(b9995294967294) {
   float F[4];
   int   I[10];
@@ -45,3 +45,9 @@ cbuffer MyCB : register(b9995294967294) {
 
 // no errors expected, all 100 register numbers are occupied here
 RWBuffer<float> Buf3[10][10] : register(u4294967194); 
+
+// expected-error@+1 {{register number should be an integer}}
+RWBuffer<float> Buf4[10][10] : register(ud); 
+
+// expected-error@+1 {{expected <numeric_constant>}}
+RWBuffer<float> BadBuf[10][10] : register(u); 

>From 34d30832c0f017206de32824324f76ac9a431c83 Mon Sep 17 00:00:00 2001
From: Joshua Batista <[email protected]>
Date: Wed, 31 Dec 2025 10:50:30 -0800
Subject: [PATCH 5/7] try to fix macos issue

---
 clang/lib/Sema/SemaHLSL.cpp | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 157c6c0f6def7..207fd7abb827e 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -2408,7 +2408,7 @@ static bool AccumulateHLSLResourceSlots(QualType Ty, 
uint64_t &SlotCount,
 }
 
 // return true if there is something invalid, false otherwise
-static bool ValidateRegisterNumber(StringRef SlotNumStr, Decl *TheDecl,
+static bool ValidateRegisterNumber(const StringRef SlotNumStr, Decl *TheDecl,
                                    ASTContext &Ctx) {
   uint64_t SlotNum;
   if (SlotNumStr.getAsInteger(10, SlotNum))
@@ -2491,7 +2491,7 @@ void SemaHLSL::handleResourceBindingAttr(Decl *TheDecl, 
const ParsedAttr &AL) {
       Diag(SlotLoc, diag::warn_hlsl_deprecated_register_type_i);
       return;
     }
-    StringRef SlotNumStr = Slot.substr(1);
+    const StringRef SlotNumStr = Slot.substr(1);
 
     unsigned N;
     // validate that the stringref has a non-empty number
@@ -2508,8 +2508,10 @@ void SemaHLSL::handleResourceBindingAttr(Decl *TheDecl, 
const ParsedAttr &AL) {
       return;
     }
 
-    // this shouldn't fail now that it's validated.
-    assert(!SlotNumStr.getAsInteger(10, N));
+    if (SlotNumStr.getAsInteger(10, N)) {
+      Diag(SlotLoc, diag::err_hlsl_unsupported_register_number);
+      return;
+    }
     SlotNum = N;
   }
 

>From 05d31181e14f3f6e18034b5e49230a4c3a7efc3f Mon Sep 17 00:00:00 2001
From: Joshua Batista <[email protected]>
Date: Wed, 31 Dec 2025 12:33:58 -0800
Subject: [PATCH 6/7] address Finn

---
 clang/lib/Sema/SemaHLSL.cpp                   | 34 +++++++++++--------
 ...esource_binding_attr_error_uint32_max.hlsl |  7 ++--
 2 files changed, 23 insertions(+), 18 deletions(-)

diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 207fd7abb827e..e30f5b4e5d8dc 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -2376,9 +2376,8 @@ static bool AccumulateHLSLResourceSlots(QualType Ty, 
uint64_t &SlotCount,
   if (const auto *AT = dyn_cast<ArrayType>(T)) {
     uint64_t Count = 1;
 
-    if (const auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
+    if (const auto *CAT = dyn_cast<ConstantArrayType>(AT))
       Count = CAT->getSize().getZExtValue();
-    }
 
     QualType ElemTy = AT->getElementType();
     return AccumulateHLSLResourceSlots(ElemTy, SlotCount, Limit, Ctx,
@@ -2395,11 +2394,11 @@ static bool AccumulateHLSLResourceSlots(QualType Ty, 
uint64_t &SlotCount,
   // Case 3: struct / record
   if (const auto *RT = dyn_cast<RecordType>(T)) {
     const RecordDecl *RD = RT->getDecl();
-    for (const FieldDecl *Field : RD->fields()) {
+    for (const FieldDecl *Field : RD->fields())
       if (!AccumulateHLSLResourceSlots(Field->getType(), SlotCount, Limit, Ctx,
                                        Multiplier))
         return false;
-    }
+
     return true;
   }
 
@@ -2409,24 +2408,32 @@ static bool AccumulateHLSLResourceSlots(QualType Ty, 
uint64_t &SlotCount,
 
 // return true if there is something invalid, false otherwise
 static bool ValidateRegisterNumber(const StringRef SlotNumStr, Decl *TheDecl,
-                                   ASTContext &Ctx) {
+                                   ASTContext &Ctx, unsigned &Result) {
   uint64_t SlotNum;
   if (SlotNumStr.getAsInteger(10, SlotNum))
     return false;
 
   uint64_t Limit = UINT32_MAX;
-  VarDecl *VD = dyn_cast<VarDecl>(TheDecl);
-  if (VD) {
+  if (VarDecl *VD = dyn_cast<VarDecl>(TheDecl)) {
     AccumulateHLSLResourceSlots(VD->getType(), SlotNum, Limit, Ctx);
-    return SlotNum > Limit;
+
+    bool TooHigh = SlotNum > Limit;
+    if (!TooHigh)
+      SlotNumStr.getAsInteger(10, Result);
+    return TooHigh;
   }
   // handle the cbuffer case
   HLSLBufferDecl *HBD = dyn_cast<HLSLBufferDecl>(TheDecl);
   if (HBD) {
+    SlotNumStr.getAsInteger(10, Result);
     // resources cannot be put within a cbuffer, so no need
     // to analyze the structure since the register number
     // won't be pushed any higher.
-    return SlotNum > Limit;
+    bool TooHigh = SlotNum > Limit;
+    if (!TooHigh)
+      SlotNumStr.getAsInteger(10, Result);
+
+    return TooHigh;
   }
 
   // we don't expect any other decl type, so fail
@@ -2494,7 +2501,8 @@ void SemaHLSL::handleResourceBindingAttr(Decl *TheDecl, 
const ParsedAttr &AL) {
     const StringRef SlotNumStr = Slot.substr(1);
 
     unsigned N;
-    // validate that the stringref has a non-empty number
+
+    // validate that the slot number is a non-empty number
     if (SlotNumStr.empty() || !llvm::all_of(SlotNumStr, llvm::isDigit)) {
       Diag(SlotLoc, diag::err_hlsl_unsupported_register_number);
       return;
@@ -2503,15 +2511,11 @@ void SemaHLSL::handleResourceBindingAttr(Decl *TheDecl, 
const ParsedAttr &AL) {
     // Validate register number. It should not exceed UINT32_MAX,
     // including if the resource type is an array that starts
     // before UINT32_MAX, but ends afterwards.
-    if (ValidateRegisterNumber(SlotNumStr, TheDecl, getASTContext())) {
+    if (ValidateRegisterNumber(SlotNumStr, TheDecl, getASTContext(), N)) {
       Diag(SlotLoc, diag::err_hlsl_register_number_too_large);
       return;
     }
 
-    if (SlotNumStr.getAsInteger(10, N)) {
-      Diag(SlotLoc, diag::err_hlsl_unsupported_register_number);
-      return;
-    }
     SlotNum = N;
   }
 
diff --git a/clang/test/SemaHLSL/resource_binding_attr_error_uint32_max.hlsl 
b/clang/test/SemaHLSL/resource_binding_attr_error_uint32_max.hlsl
index 9f2f4b0a7d816..7ed084aec2cfd 100644
--- a/clang/test/SemaHLSL/resource_binding_attr_error_uint32_max.hlsl
+++ b/clang/test/SemaHLSL/resource_binding_attr_error_uint32_max.hlsl
@@ -2,6 +2,10 @@
 
 // test semantic validation for register numbers that exceed UINT32_MAX
 
+
+// expected-error@+1 {{expected <numeric_constant>}}
+RWBuffer<float> BadBuf[10][10] : register(u); 
+
 struct S {
   RWBuffer<float> A[4];
   RWBuffer<int> B[10];
@@ -48,6 +52,3 @@ RWBuffer<float> Buf3[10][10] : register(u4294967194);
 
 // expected-error@+1 {{register number should be an integer}}
 RWBuffer<float> Buf4[10][10] : register(ud); 
-
-// expected-error@+1 {{expected <numeric_constant>}}
-RWBuffer<float> BadBuf[10][10] : register(u); 

>From d7150e90fe2219528f3a98fbd88b4f0a7ee1b961 Mon Sep 17 00:00:00 2001
From: Joshua Batista <[email protected]>
Date: Wed, 31 Dec 2025 12:45:53 -0800
Subject: [PATCH 7/7] one quick move

---
 clang/test/SemaHLSL/resource_binding_attr_error.hlsl          | 3 +++
 .../test/SemaHLSL/resource_binding_attr_error_uint32_max.hlsl | 4 ----
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/clang/test/SemaHLSL/resource_binding_attr_error.hlsl 
b/clang/test/SemaHLSL/resource_binding_attr_error.hlsl
index afd7d407c34c2..66b42825c5cf7 100644
--- a/clang/test/SemaHLSL/resource_binding_attr_error.hlsl
+++ b/clang/test/SemaHLSL/resource_binding_attr_error.hlsl
@@ -34,6 +34,9 @@ cbuffer D : register(b 2, space3) {}
 // expected-error@+1 {{expected <numeric_constant>}}
 cbuffer E : register(u-1) {};
 
+// expected-error@+1 {{expected <numeric_constant>}}
+cbuffer F : register(u) {}; 
+
 // expected-error@+1 {{'register' attribute only applies to cbuffer/tbuffer 
and external global variables}}
 static MyTemplatedSRV<float> U : register(u5);
 
diff --git a/clang/test/SemaHLSL/resource_binding_attr_error_uint32_max.hlsl 
b/clang/test/SemaHLSL/resource_binding_attr_error_uint32_max.hlsl
index 7ed084aec2cfd..6f35aed0f2ccb 100644
--- a/clang/test/SemaHLSL/resource_binding_attr_error_uint32_max.hlsl
+++ b/clang/test/SemaHLSL/resource_binding_attr_error_uint32_max.hlsl
@@ -2,10 +2,6 @@
 
 // test semantic validation for register numbers that exceed UINT32_MAX
 
-
-// expected-error@+1 {{expected <numeric_constant>}}
-RWBuffer<float> BadBuf[10][10] : register(u); 
-
 struct S {
   RWBuffer<float> A[4];
   RWBuffer<int> B[10];

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to