[clang] [SemaHLSL] Warn when a local resource is re-assigned to non-unique global resource (PR #182101)
Finn Plummer via cfe-commits
cfe-commits at lists.llvm.org
Mon Mar 2 09:46:12 PST 2026
https://github.com/inbelic updated https://github.com/llvm/llvm-project/pull/182101
>From bf87d3cbdc7118754c85db1022561e3241e80486 Mon Sep 17 00:00:00 2001
From: Finn Plummer <mail at inbelic.dev>
Date: Tue, 17 Feb 2026 11:54:04 -0800
Subject: [PATCH 1/5] [SemaHLSL] Emit a warning if local resource refer to
non-unique global resources
---
.../clang/Basic/DiagnosticSemaKinds.td | 3 +
clang/include/clang/Sema/SemaHLSL.h | 18 +++++
clang/lib/Sema/SemaHLSL.cpp | 68 ++++++++++++++++++-
.../SemaHLSL/local_resource_bindings.hlsl | 56 +++++++++++++++
.../local_resource_bindings_errs.hlsl | 49 +++++++++++++
5 files changed, 193 insertions(+), 1 deletion(-)
create mode 100644 clang/test/SemaHLSL/local_resource_bindings.hlsl
create mode 100644 clang/test/SemaHLSL/local_resource_bindings_errs.hlsl
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 68016ec4d58a3..7c1958457a881 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -13585,6 +13585,9 @@ def err_hlsl_incomplete_resource_array_in_function_param: Error<
"incomplete resource array in a function parameter">;
def err_hlsl_assign_to_global_resource: Error<
"assignment to global resource variable %0 is not allowed">;
+def warn_hlsl_assigning_local_resource_is_not_unique
+ : Warning<"assignment of %0 to local resource %1 is not to the same "
+ "unique global resource">;
def err_hlsl_push_constant_unique
: Error<"cannot have more than one push constant block">;
diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h
index 020a4dc44ee7f..86748f15b9e76 100644
--- a/clang/include/clang/Sema/SemaHLSL.h
+++ b/clang/include/clang/Sema/SemaHLSL.h
@@ -132,6 +132,8 @@ class SemaHLSL : public SemaBase {
bool ActOnUninitializedVarDecl(VarDecl *D);
void ActOnEndOfTranslationUnit(TranslationUnitDecl *TU);
void CheckEntryPoint(FunctionDecl *FD);
+
+ // Return true if everything is ok; returns false if there was an error.
bool CheckResourceBinOp(BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr,
SourceLocation Loc);
@@ -234,6 +236,12 @@ class SemaHLSL : public SemaBase {
// List of all resource bindings
ResourceBindings Bindings;
+ // Map of local resource variables to their assigned global resources.
+ //
+ // The binding can be a nullptr, in which case, the variable has yet to be
+ // initialized or assigned to.
+ llvm::DenseMap<const VarDecl *, const DeclBindingInfo *> Assigns;
+
// Global declaration collected for the $Globals default constant
// buffer which will be created at the end of the translation unit.
llvm::SmallVector<Decl *> DefaultCBufferDecls;
@@ -313,6 +321,16 @@ class SemaHLSL : public SemaBase {
bool initGlobalResourceDecl(VarDecl *VD);
bool initGlobalResourceArrayDecl(VarDecl *VD);
+
+ // Infer a common global binding info for an Expr
+ //
+ // Returns std::nullopt if the expr refers to non-unique global bindings.
+ // Returns nullptr if it refer to any global binding, otherwise it returns
+ // a reference to the global binding info.
+ std::optional<const DeclBindingInfo *> inferGlobalBinding(Expr *E);
+
+ // Returns true if no diagnostic is reported
+ bool trackLocalResource(VarDecl *VDecl, Expr *E);
};
} // namespace clang
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 911dba40d3bde..73e5935d79bb7 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -4686,7 +4686,67 @@ bool SemaHLSL::ActOnUninitializedVarDecl(VarDecl *VD) {
return false;
}
-// Return true if everything is ok; returns false if there was an error.
+std::optional<const DeclBindingInfo *> SemaHLSL::inferGlobalBinding(Expr *E) {
+ if (auto *Ternary = dyn_cast<ConditionalOperator>(E)) {
+ auto TrueInfo = inferGlobalBinding(Ternary->getTrueExpr());
+ auto FalseInfo = inferGlobalBinding(Ternary->getFalseExpr());
+ if (!TrueInfo || !FalseInfo)
+ return std::nullopt;
+ if (*TrueInfo != *FalseInfo)
+ return std::nullopt;
+ return TrueInfo;
+ }
+
+ if (auto *ASE = dyn_cast<ArraySubscriptExpr>(E))
+ E = ASE->getBase()->IgnoreParenImpCasts();
+
+ if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParens()))
+ if (VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
+ const Type *Ty = VD->getType()->getUnqualifiedDesugaredType();
+ if (Ty->isArrayType())
+ Ty = Ty->getArrayElementTypeNoTypeQual();
+
+ if (const auto *AttrResType =
+ HLSLAttributedResourceType::findHandleTypeOnResource(Ty)) {
+ ResourceClass RC = AttrResType->getAttrs().ResourceClass;
+ return Bindings.getDeclBindingInfo(VD, RC);
+ }
+ }
+
+ return nullptr;
+}
+
+bool SemaHLSL::trackLocalResource(VarDecl *VD, Expr *E) {
+ std::optional<const DeclBindingInfo *> ExprBinding = inferGlobalBinding(E);
+ if (!ExprBinding) {
+ SemaRef.Diag(E->getBeginLoc(),
+ diag::warn_hlsl_assigning_local_resource_is_not_unique)
+ << E << VD;
+ return false;
+ }
+
+ if (*ExprBinding == nullptr)
+ return true; // No binding could be inferred to track, return without error
+
+ auto PrevBinding = Assigns.find(VD);
+ if (PrevBinding == Assigns.end()) {
+ // No previous binding recorded, simply record the new assignment
+ Assigns.insert({VD, *ExprBinding});
+ return true;
+ }
+
+ // Otherwise, warn if the assignment implies different resource bindings
+ if (*ExprBinding != PrevBinding->second) {
+ SemaRef.Diag(E->getBeginLoc(),
+ diag::warn_hlsl_assigning_local_resource_is_not_unique)
+ << E << VD;
+ SemaRef.Diag(VD->getLocation(), diag::note_var_declared_here) << VD;
+ return false;
+ }
+
+ return true;
+}
+
bool SemaHLSL::CheckResourceBinOp(BinaryOperatorKind Opc, Expr *LHSExpr,
Expr *RHSExpr, SourceLocation Loc) {
assert((LHSExpr->getType()->isHLSLResourceRecord() ||
@@ -4709,6 +4769,8 @@ bool SemaHLSL::CheckResourceBinOp(BinaryOperatorKind Opc, Expr *LHSExpr,
SemaRef.Diag(VD->getLocation(), diag::note_var_declared_here) << VD;
return false;
}
+
+ trackLocalResource(VD, RHSExpr);
}
}
return true;
@@ -5315,6 +5377,10 @@ QualType SemaHLSL::checkMatrixComponent(Sema &S, QualType baseType,
}
bool SemaHLSL::handleInitialization(VarDecl *VDecl, Expr *&Init) {
+ // If initializing a local resource, track the resource binding it is using
+ if (VDecl->getType()->isHLSLResourceRecord() && !VDecl->hasGlobalStorage())
+ trackLocalResource(VDecl, Init);
+
const HLSLVkConstantIdAttr *ConstIdAttr =
VDecl->getAttr<HLSLVkConstantIdAttr>();
if (!ConstIdAttr)
diff --git a/clang/test/SemaHLSL/local_resource_bindings.hlsl b/clang/test/SemaHLSL/local_resource_bindings.hlsl
new file mode 100644
index 0000000000000..3059452b49ef0
--- /dev/null
+++ b/clang/test/SemaHLSL/local_resource_bindings.hlsl
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -verify %s
+
+// expected-no-diagnostics
+
+RWBuffer<int> In : register(u0);
+RWStructuredBuffer<int> Out0 : register(u1);
+RWStructuredBuffer<int> Out1 : register(u2);
+RWStructuredBuffer<int> OutArr[];
+
+cbuffer c {
+ bool cond;
+};
+
+void no_initial_assignment(int idx) {
+ RWStructuredBuffer<int> Out;
+ if (cond) {
+ Out = Out1;
+ }
+ Out[idx] = In[idx];
+}
+
+void same_assignment(int idx) {
+ RWStructuredBuffer<int> Out = Out1;
+ if (cond) {
+ Out = Out1;
+ }
+ Out[idx] = In[idx];
+}
+
+void conditional_initialization_with_index(int idx) {
+ RWStructuredBuffer<int> Out = cond ? OutArr[0] : OutArr[1];
+ Out[idx] = In[idx];
+}
+
+void conditional_assignment_with_index(int idx) {
+ RWStructuredBuffer<int> Out;
+ if (cond) {
+ Out = OutArr[0];
+ } else {
+ Out = OutArr[1];
+ }
+ Out[idx] = In[idx];
+}
+
+void reassignment(int idx) {
+ RWStructuredBuffer<int> Out = Out0;
+ if (cond) {
+ Out = Out0;
+ }
+ Out[idx] = In[idx];
+}
+
+void conditional_result_in_same(int idx) {
+ RWStructuredBuffer<int> Out = cond ? Out0 : Out0;
+ Out[idx] = In[idx];
+}
diff --git a/clang/test/SemaHLSL/local_resource_bindings_errs.hlsl b/clang/test/SemaHLSL/local_resource_bindings_errs.hlsl
new file mode 100644
index 0000000000000..3be8268ec0505
--- /dev/null
+++ b/clang/test/SemaHLSL/local_resource_bindings_errs.hlsl
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -verify %s
+
+RWBuffer<int> In : register(u0);
+RWStructuredBuffer<int> Out0 : register(u1);
+RWStructuredBuffer<int> Out1 : register(u2);
+RWStructuredBuffer<int> OutArr[];
+
+cbuffer c {
+ bool cond;
+};
+
+void conditional_initialization(int idx) {
+ // expected-warning at +1 {{assignment of 'cond ? Out0 : Out1' to local resource 'Out' is not to the same unique global resource}}
+ RWStructuredBuffer<int> Out = cond ? Out0 : Out1;
+ Out[idx] = In[idx];
+}
+
+void branched_assignment(int idx) {
+ RWStructuredBuffer<int> Out = Out0; // expected-note {{variable 'Out' is declared here}}
+ if (cond) {
+ // expected-warning at +1 {{assignment of 'Out1' to local resource 'Out' is not to the same unique global resource}}
+ Out = Out1;
+ }
+ Out[idx] = In[idx];
+}
+
+void branched_assignment_with_array(int idx) {
+ RWStructuredBuffer<int> Out = Out0; // expected-note {{variable 'Out' is declared here}}
+ if (cond) {
+ // expected-warning at +1 {{assignment of 'OutArr[0]' to local resource 'Out' is not to the same unique global resource}}
+ Out = OutArr[0];
+ }
+ Out[idx] = In[idx];
+}
+
+void conditional_assignment(int idx) {
+ RWStructuredBuffer<int> Out;
+ // expected-warning at +1 {{assignment of 'cond ? Out0 : Out1' to local resource 'Out' is not to the same unique global resource}}
+ Out = cond ? Out0 : Out1;
+ Out[idx] = In[idx];
+}
+
+static RWStructuredBuffer<int> StaticOut;
+
+void static_conditional_assignment(int idx) {
+ // expected-warning at +1 {{assignment of 'cond ? Out0 : Out1' to local resource 'StaticOut' is not to the same unique global resource}}
+ StaticOut = cond ? Out0 : Out1;
+ StaticOut[idx] = In[idx];
+}
>From 5287da122980a3884664a71f2281c51c1ebe1983 Mon Sep 17 00:00:00 2001
From: Finn Plummer <mail at inbelic.dev>
Date: Thu, 19 Feb 2026 14:59:45 -0800
Subject: [PATCH 2/5] review: add assignment to uninitialized test
- no warnings generated
---
clang/test/SemaHLSL/local_resource_bindings.hlsl | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/clang/test/SemaHLSL/local_resource_bindings.hlsl b/clang/test/SemaHLSL/local_resource_bindings.hlsl
index 3059452b49ef0..a7f28018516a6 100644
--- a/clang/test/SemaHLSL/local_resource_bindings.hlsl
+++ b/clang/test/SemaHLSL/local_resource_bindings.hlsl
@@ -19,6 +19,12 @@ void no_initial_assignment(int idx) {
Out[idx] = In[idx];
}
+void assignment_to_uninitialized(int idx) {
+ RWStructuredBuffer<int> Out;
+ Out = Out;
+ Out[idx] = In[idx];
+}
+
void same_assignment(int idx) {
RWStructuredBuffer<int> Out = Out1;
if (cond) {
>From c09420c976f23a83b0b3bc0adcfeffe56846d725 Mon Sep 17 00:00:00 2001
From: Finn Plummer <mail at inbelic.dev>
Date: Thu, 19 Feb 2026 15:01:02 -0800
Subject: [PATCH 3/5] review: remove unused return value
---
clang/include/clang/Sema/SemaHLSL.h | 3 +--
clang/lib/Sema/SemaHLSL.cpp | 12 ++++++------
2 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h
index 86748f15b9e76..a6a38531ac284 100644
--- a/clang/include/clang/Sema/SemaHLSL.h
+++ b/clang/include/clang/Sema/SemaHLSL.h
@@ -329,8 +329,7 @@ class SemaHLSL : public SemaBase {
// a reference to the global binding info.
std::optional<const DeclBindingInfo *> inferGlobalBinding(Expr *E);
- // Returns true if no diagnostic is reported
- bool trackLocalResource(VarDecl *VDecl, Expr *E);
+ void trackLocalResource(VarDecl *VDecl, Expr *E);
};
} // namespace clang
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 73e5935d79bb7..804ea70aaddce 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -4716,23 +4716,23 @@ std::optional<const DeclBindingInfo *> SemaHLSL::inferGlobalBinding(Expr *E) {
return nullptr;
}
-bool SemaHLSL::trackLocalResource(VarDecl *VD, Expr *E) {
+void SemaHLSL::trackLocalResource(VarDecl *VD, Expr *E) {
std::optional<const DeclBindingInfo *> ExprBinding = inferGlobalBinding(E);
if (!ExprBinding) {
SemaRef.Diag(E->getBeginLoc(),
diag::warn_hlsl_assigning_local_resource_is_not_unique)
<< E << VD;
- return false;
+ return; // Expr use multiple resources
}
if (*ExprBinding == nullptr)
- return true; // No binding could be inferred to track, return without error
+ return; // No binding could be inferred to track, return without error
auto PrevBinding = Assigns.find(VD);
if (PrevBinding == Assigns.end()) {
// No previous binding recorded, simply record the new assignment
Assigns.insert({VD, *ExprBinding});
- return true;
+ return;
}
// Otherwise, warn if the assignment implies different resource bindings
@@ -4741,10 +4741,10 @@ bool SemaHLSL::trackLocalResource(VarDecl *VD, Expr *E) {
diag::warn_hlsl_assigning_local_resource_is_not_unique)
<< E << VD;
SemaRef.Diag(VD->getLocation(), diag::note_var_declared_here) << VD;
- return false;
+ return;
}
- return true;
+ return;
}
bool SemaHLSL::CheckResourceBinOp(BinaryOperatorKind Opc, Expr *LHSExpr,
>From 5a09a3694ce0e44a3d6383fdfcac2b5deacc215a Mon Sep 17 00:00:00 2001
From: Finn Plummer <mail at inbelic.dev>
Date: Mon, 2 Mar 2026 16:55:41 +0000
Subject: [PATCH 4/5] self-review: fix conversion errors
---
.../SemaHLSL/local_resource_bindings.hlsl | 38 +++++++++----------
.../local_resource_bindings_errs.hlsl | 30 +++++++--------
2 files changed, 34 insertions(+), 34 deletions(-)
diff --git a/clang/test/SemaHLSL/local_resource_bindings.hlsl b/clang/test/SemaHLSL/local_resource_bindings.hlsl
index a7f28018516a6..58e7bf47d2d0d 100644
--- a/clang/test/SemaHLSL/local_resource_bindings.hlsl
+++ b/clang/test/SemaHLSL/local_resource_bindings.hlsl
@@ -1,45 +1,45 @@
-// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -verify %s
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -finclude-default-header -verify %s
// expected-no-diagnostics
-RWBuffer<int> In : register(u0);
-RWStructuredBuffer<int> Out0 : register(u1);
-RWStructuredBuffer<int> Out1 : register(u2);
-RWStructuredBuffer<int> OutArr[];
+RWBuffer<uint> In : register(u0);
+RWStructuredBuffer<uint> Out0 : register(u1);
+RWStructuredBuffer<uint> Out1 : register(u2);
+RWStructuredBuffer<uint> OutArr[];
cbuffer c {
bool cond;
};
-void no_initial_assignment(int idx) {
- RWStructuredBuffer<int> Out;
+void no_initial_assignment(uint idx) {
+ RWStructuredBuffer<uint> Out;
if (cond) {
Out = Out1;
}
Out[idx] = In[idx];
}
-void assignment_to_uninitialized(int idx) {
- RWStructuredBuffer<int> Out;
+void assignment_to_uninitialized(uint idx) {
+ RWStructuredBuffer<uint> Out;
Out = Out;
Out[idx] = In[idx];
}
-void same_assignment(int idx) {
- RWStructuredBuffer<int> Out = Out1;
+void same_assignment(uint idx) {
+ RWStructuredBuffer<uint> Out = Out1;
if (cond) {
Out = Out1;
}
Out[idx] = In[idx];
}
-void conditional_initialization_with_index(int idx) {
- RWStructuredBuffer<int> Out = cond ? OutArr[0] : OutArr[1];
+void conditional_initialization_with_index(uint idx) {
+ RWStructuredBuffer<uint> Out = cond ? OutArr[0] : OutArr[1];
Out[idx] = In[idx];
}
-void conditional_assignment_with_index(int idx) {
- RWStructuredBuffer<int> Out;
+void conditional_assignment_with_index(uint idx) {
+ RWStructuredBuffer<uint> Out;
if (cond) {
Out = OutArr[0];
} else {
@@ -48,15 +48,15 @@ void conditional_assignment_with_index(int idx) {
Out[idx] = In[idx];
}
-void reassignment(int idx) {
- RWStructuredBuffer<int> Out = Out0;
+void reassignment(uint idx) {
+ RWStructuredBuffer<uint> Out = Out0;
if (cond) {
Out = Out0;
}
Out[idx] = In[idx];
}
-void conditional_result_in_same(int idx) {
- RWStructuredBuffer<int> Out = cond ? Out0 : Out0;
+void conditional_result_in_same(uint idx) {
+ RWStructuredBuffer<uint> Out = cond ? Out0 : Out0;
Out[idx] = In[idx];
}
diff --git a/clang/test/SemaHLSL/local_resource_bindings_errs.hlsl b/clang/test/SemaHLSL/local_resource_bindings_errs.hlsl
index 3be8268ec0505..7404e444390b1 100644
--- a/clang/test/SemaHLSL/local_resource_bindings_errs.hlsl
+++ b/clang/test/SemaHLSL/local_resource_bindings_errs.hlsl
@@ -1,22 +1,22 @@
-// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -verify %s
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -finclude-default-header -verify %s
-RWBuffer<int> In : register(u0);
-RWStructuredBuffer<int> Out0 : register(u1);
-RWStructuredBuffer<int> Out1 : register(u2);
-RWStructuredBuffer<int> OutArr[];
+RWBuffer<uint> In : register(u0);
+RWStructuredBuffer<uint> Out0 : register(u1);
+RWStructuredBuffer<uint> Out1 : register(u2);
+RWStructuredBuffer<uint> OutArr[];
cbuffer c {
bool cond;
};
-void conditional_initialization(int idx) {
+void conditional_initialization(uint idx) {
// expected-warning at +1 {{assignment of 'cond ? Out0 : Out1' to local resource 'Out' is not to the same unique global resource}}
- RWStructuredBuffer<int> Out = cond ? Out0 : Out1;
+ RWStructuredBuffer<uint> Out = cond ? Out0 : Out1;
Out[idx] = In[idx];
}
-void branched_assignment(int idx) {
- RWStructuredBuffer<int> Out = Out0; // expected-note {{variable 'Out' is declared here}}
+void branched_assignment(uint idx) {
+ RWStructuredBuffer<uint> Out = Out0; // expected-note {{variable 'Out' is declared here}}
if (cond) {
// expected-warning at +1 {{assignment of 'Out1' to local resource 'Out' is not to the same unique global resource}}
Out = Out1;
@@ -24,8 +24,8 @@ void branched_assignment(int idx) {
Out[idx] = In[idx];
}
-void branched_assignment_with_array(int idx) {
- RWStructuredBuffer<int> Out = Out0; // expected-note {{variable 'Out' is declared here}}
+void branched_assignment_with_array(uint idx) {
+ RWStructuredBuffer<uint> Out = Out0; // expected-note {{variable 'Out' is declared here}}
if (cond) {
// expected-warning at +1 {{assignment of 'OutArr[0]' to local resource 'Out' is not to the same unique global resource}}
Out = OutArr[0];
@@ -33,16 +33,16 @@ void branched_assignment_with_array(int idx) {
Out[idx] = In[idx];
}
-void conditional_assignment(int idx) {
- RWStructuredBuffer<int> Out;
+void conditional_assignment(uint idx) {
+ RWStructuredBuffer<uint> Out;
// expected-warning at +1 {{assignment of 'cond ? Out0 : Out1' to local resource 'Out' is not to the same unique global resource}}
Out = cond ? Out0 : Out1;
Out[idx] = In[idx];
}
-static RWStructuredBuffer<int> StaticOut;
+static RWStructuredBuffer<uint> StaticOut;
-void static_conditional_assignment(int idx) {
+void static_conditional_assignment(uint idx) {
// expected-warning at +1 {{assignment of 'cond ? Out0 : Out1' to local resource 'StaticOut' is not to the same unique global resource}}
StaticOut = cond ? Out0 : Out1;
StaticOut[idx] = In[idx];
>From 47db9794c04f7cde2969a8534845f96f0d6a4eaf Mon Sep 17 00:00:00 2001
From: Finn Plummer <mail at inbelic.dev>
Date: Mon, 2 Mar 2026 17:45:52 +0000
Subject: [PATCH 5/5] self-review: fix missing warning flag error
---
clang/include/clang/Basic/DiagnosticGroups.td | 3 +++
clang/include/clang/Basic/DiagnosticSemaKinds.td | 3 ++-
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 7df83d2a4011f..1d9652845c17c 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -1852,6 +1852,9 @@ def HLSLMixPackOffset : DiagGroup<"mix-packoffset">;
// Warning for implicit resource bindings.
def HLSLImplicitBinding : DiagGroup<"hlsl-implicit-binding">;
+// Warning for explicit resource bindings.
+def HLSLExplicitBinding : DiagGroup<"hlsl-explicit-binding">;
+
// Warnings for DXIL validation
def DXILValidation : DiagGroup<"dxil-validation">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 7c1958457a881..c887e834b9a9a 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -13587,7 +13587,8 @@ def err_hlsl_assign_to_global_resource: Error<
"assignment to global resource variable %0 is not allowed">;
def warn_hlsl_assigning_local_resource_is_not_unique
: Warning<"assignment of %0 to local resource %1 is not to the same "
- "unique global resource">;
+ "unique global resource">,
+ InGroup<HLSLExplicitBinding>;
def err_hlsl_push_constant_unique
: Error<"cannot have more than one push constant block">;
More information about the cfe-commits
mailing list