From 0943b55c8c21b1165186a4b81e9994a8d53729a8 Mon Sep 17 00:00:00 2001 From: Chris Bieneman Date: Thu, 10 Sep 2026 15:09:48 -0500 Subject: [PATCH 1/9] [202x] Enable `auto` return types This PR enables return type deduction for normal functions following C++ 14's use of `auto` as the return type in normal function prototype syntax. The HLSL proposal is in progress here: https://hlsl-tc57.github.io/tc57/proposal/0010 While this proposal is still in Refinement, so this is getting a bit ahead of the standard committee it seems like a highly likely feature that brings a lot of value for a fairly small set of changes. Assisted-by: GitHub Copilot ../tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-errors.hlsl ../tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-extension-war ning.hlsl ../tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-type.hlsl --- tools/clang/lib/Sema/SemaDecl.cpp | 12 ++-- tools/clang/lib/Sema/SemaExpr.cpp | 9 ++- tools/clang/lib/Sema/SemaStmt.cpp | 4 +- tools/clang/lib/Sema/SemaType.cpp | 10 ++- .../test/CodeGenSPIRV/fn.auto.return.hlsl | 39 +++++++++++ .../hlsl/auto/auto-return-errors.hlsl | 35 ++++++++++ .../auto/auto-return-extension-warning.hlsl | 19 ++++++ .../hlsl/auto/auto-return-type.hlsl | 65 +++++++++++++++++++ 8 files changed, 183 insertions(+), 10 deletions(-) create mode 100644 tools/clang/test/CodeGenSPIRV/fn.auto.return.hlsl create mode 100644 tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-errors.hlsl create mode 100644 tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-extension-warning.hlsl create mode 100644 tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-type.hlsl diff --git a/tools/clang/lib/Sema/SemaDecl.cpp b/tools/clang/lib/Sema/SemaDecl.cpp index 52c870d994..8f999945fa 100644 --- a/tools/clang/lib/Sema/SemaDecl.cpp +++ b/tools/clang/lib/Sema/SemaDecl.cpp @@ -7479,12 +7479,13 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, NewFD->setVirtualAsWritten(true); } - if (getLangOpts().CPlusPlus14 && + // HLSL Change - HLSL supports C++14-style deduced return types. + if ((getLangOpts().CPlusPlus14 || getLangOpts().HLSL) && NewFD->getReturnType()->isUndeducedType()) Diag(D.getDeclSpec().getVirtualSpecLoc(), diag::err_auto_fn_virtual); } - if (getLangOpts().CPlusPlus14 && + if ((getLangOpts().CPlusPlus14 || getLangOpts().HLSL) && // HLSL Change (NewFD->isDependentContext() || (isFriend && CurContext->isDependentContext())) && NewFD->getReturnType()->isUndeducedType()) { @@ -10907,8 +10908,11 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, if (FD) { FD->setBody(Body); - if (getLangOpts().CPlusPlus14 && !FD->isInvalidDecl() && Body && - !FD->isDependentContext() && FD->getReturnType()->isUndeducedType()) { + // HLSL Change Begin - HLSL supports C++14-style deduced return types. + if ((getLangOpts().CPlusPlus14 || getLangOpts().HLSL) && + !FD->isInvalidDecl() && Body && !FD->isDependentContext() && + FD->getReturnType()->isUndeducedType()) { + // HLSL Change End // If the function has a deduced result type but contains no 'return' // statements, the result type as written must be exactly 'auto', and // the deduced result type is 'void'. diff --git a/tools/clang/lib/Sema/SemaExpr.cpp b/tools/clang/lib/Sema/SemaExpr.cpp index 1c6c699bde..220c31ba26 100644 --- a/tools/clang/lib/Sema/SemaExpr.cpp +++ b/tools/clang/lib/Sema/SemaExpr.cpp @@ -63,7 +63,9 @@ bool Sema::CanUseDecl(NamedDecl *D) { // If the function has a deduced return type, and we can't deduce it, // then we can't use it either. - if (getLangOpts().CPlusPlus14 && FD->getReturnType()->isUndeducedType() && + // HLSL Change - HLSL supports C++14-style deduced return types. + if ((getLangOpts().CPlusPlus14 || getLangOpts().HLSL) && + FD->getReturnType()->isUndeducedType() && DeduceReturnType(FD, SourceLocation(), /*Diagnose*/ false)) return false; } @@ -366,8 +368,9 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc, // If the function has a deduced return type, and we can't deduce it, // then we can't use it either. - if (getLangOpts().CPlusPlus14 && FD->getReturnType()->isUndeducedType() && - DeduceReturnType(FD, Loc)) + // HLSL Change - HLSL supports C++14-style deduced return types. + if ((getLangOpts().CPlusPlus14 || getLangOpts().HLSL) && + FD->getReturnType()->isUndeducedType() && DeduceReturnType(FD, Loc)) return true; } DiagnoseAvailabilityOfDecl(*this, D, Loc, UnknownObjCClass, diff --git a/tools/clang/lib/Sema/SemaStmt.cpp b/tools/clang/lib/Sema/SemaStmt.cpp index baa9559dbb..5235d76f48 100644 --- a/tools/clang/lib/Sema/SemaStmt.cpp +++ b/tools/clang/lib/Sema/SemaStmt.cpp @@ -3177,7 +3177,9 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { // FIXME: Add a flag to the ScopeInfo to indicate whether we're performing // deduction. - if (getLangOpts().CPlusPlus14) { + // HLSL Change Begin - HLSL supports C++14-style deduced return types. + if (getLangOpts().CPlusPlus14 || getLangOpts().HLSL) { + // HLSL Change End if (AutoType *AT = FnRetType->getContainedAutoType()) { FunctionDecl *FD = cast(CurContext); if (DeduceFunctionTypeFromReturnExpr(FD, ReturnLoc, RetValExp, AT)) { diff --git a/tools/clang/lib/Sema/SemaType.cpp b/tools/clang/lib/Sema/SemaType.cpp index 7465cc2cec..9f7d1f5fca 100644 --- a/tools/clang/lib/Sema/SemaType.cpp +++ b/tools/clang/lib/Sema/SemaType.cpp @@ -2658,8 +2658,12 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state, // type (this is checked later) and we can skip this. In other languages // using auto, we need to check regardless. // C++14 In generic lambdas allow 'auto' in their parameters. + // HLSL Change Begin - HLSL supports 'auto' as a function declarator return + // type with C++14-style deduction; skip this check for functions. if (ContainsPlaceholderType && - (!SemaRef.getLangOpts().CPlusPlus11 || !D.isFunctionDeclarator())) { + (!(SemaRef.getLangOpts().CPlusPlus11 || SemaRef.getLangOpts().HLSL) || + !D.isFunctionDeclarator())) { + // HLSL Change End int Error = -1; switch (D.getContext()) { @@ -3748,9 +3752,11 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, if (!D.isInvalidType()) { // trailing-return-type is only required if we're declaring a function, // and not, for instance, a pointer to a function. + // HLSL Change Begin - HLSL supports C++14-style deduced return types. if (D.getDeclSpec().containsPlaceholderType() && !FTI.hasTrailingReturnType() && chunkIndex == 0 && - !S.getLangOpts().CPlusPlus14) { + !(S.getLangOpts().CPlusPlus14 || S.getLangOpts().HLSL)) { + // HLSL Change End S.Diag(D.getDeclSpec().getTypeSpecTypeLoc(), D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto ? diag::err_auto_missing_trailing_return diff --git a/tools/clang/test/CodeGenSPIRV/fn.auto.return.hlsl b/tools/clang/test/CodeGenSPIRV/fn.auto.return.hlsl new file mode 100644 index 0000000000..67b9d74285 --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV/fn.auto.return.hlsl @@ -0,0 +1,39 @@ +// RUN: %dxc -T cs_6_0 -E main -HV 202x -fcgl %s -spirv | FileCheck %s + +// Test that the 'auto' keyword can be used as a function return type and +// that the deduced type is used correctly when targeting SPIR-V. + +// CHECK-DAG: [[INT:%[a-zA-Z0-9_]+]] = OpTypeInt 32 1 +// CHECK-DAG: [[FLOAT:%[a-zA-Z0-9_]+]] = OpTypeFloat 32 +// CHECK-DAG: [[V4FLOAT:%[a-zA-Z0-9_]+]] = OpTypeVector [[FLOAT]] 4 + +// Function 'SquareInt' must return int. +// CHECK-DAG: %SquareInt = OpFunction [[INT]] None +// CHECK-DAG: %SquareFloat = OpFunction [[FLOAT]] None +// CHECK-DAG: %Scale = OpFunction [[V4FLOAT]] None +// CHECK-DAG: %WriteOutput = OpFunction %void None + +RWBuffer output : register(u0); + +auto SquareInt(int x) { + return x * x; +} + +auto SquareFloat(float x) { + return x * x; +} + +auto Scale(float4 v, float s) { + return v * s; +} + +auto WriteOutput(uint i, float v) { + output[i] = v; +} + +[numthreads(1,1,1)] +void main() { + float4 v = float4(1, 2, 3, 4); + float4 s = Scale(v, 0.5f); + WriteOutput(0, (float)SquareInt(3) + SquareFloat(2.5f) + s.x); +} diff --git a/tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-errors.hlsl b/tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-errors.hlsl new file mode 100644 index 0000000000..339aabf244 --- /dev/null +++ b/tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-errors.hlsl @@ -0,0 +1,35 @@ +// RUN: %dxc -T cs_6_0 -HV 202x -verify %s + +// Test diagnostics for incorrect uses of 'auto' as a function return type. + +// Inconsistent deduced types between return statements is an error. +auto BadDeduction(int x) { + if (x > 0) + return 1; // deduced as int + return 2.0f; // expected-error {{'auto' in return type deduced as 'float' here but deduced as 'int' in earlier return statement}} +} + +// A function declared with 'auto' must be defined before it is used; a +// forward declaration alone is not sufficient for the call site. +auto ForwardOnly(int x); +void useForward() { + ForwardOnly(1); // expected-error {{function 'ForwardOnly' with deduced return type cannot be used before it is defined}} +} +// expected-note@-4 {{'ForwardOnly' declared here}} + +// A recursive call to a function with deduced return type must occur after +// a return statement that allows the type to be deduced. +auto BadRecurse(int x) { + return BadRecurse(x - 1) + 1; // expected-error {{cannot be used before it is defined}} +} +// expected-note@-3 {{'BadRecurse' declared here}} + +// Returning an initializer list as the deduced return value is not allowed. +// (Initializer lists in return statements are also unsupported in HLSL more +// broadly, but the auto-return-type case is still flagged early.) + +[numthreads(1,1,1)] +void main() { + BadDeduction(1); + BadRecurse(2); +} diff --git a/tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-extension-warning.hlsl b/tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-extension-warning.hlsl new file mode 100644 index 0000000000..886a84bd27 --- /dev/null +++ b/tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-extension-warning.hlsl @@ -0,0 +1,19 @@ +// RUN: %dxc -T cs_6_0 -E main -HV 2016 -verify %s +// RUN: %dxc -T cs_6_0 -E main -HV 2017 -verify %s +// RUN: %dxc -T cs_6_0 -E main -HV 2018 -verify %s +// RUN: %dxc -T cs_6_0 -E main -HV 2021 -verify %s + +// 'auto' is allowed as a function return type from HLSL 2016 onward, but +// using it before language mode 202x produces an extension warning. + +RWBuffer output : register(u0); + +// expected-warning@+1 {{'auto' type specifier is a HLSL 202x extension}} +auto Square(int x) { + return x * x; +} + +[numthreads(1,1,1)] +void main() { + output[0] = (float)Square(3); +} diff --git a/tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-type.hlsl b/tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-type.hlsl new file mode 100644 index 0000000000..9f532c67d1 --- /dev/null +++ b/tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-type.hlsl @@ -0,0 +1,65 @@ +// RUN: %dxc -T cs_6_0 -E main - %s -verify +// RUN: %dxc -T cs_6_0 -E main -HV 202x -fcgl %s | FileCheck %s + +// Test that the 'auto' keyword can be used as a function return type and +// that the deduced type matches C++14 [dcl.spec.auto] rules. + +// CHECK-LABEL: define void @main() + +// CHECK-LABEL: define internal <4 x float> @"\01?Scale +// CHECK: ret <4 x float> + +// CHECK-LABEL: define internal void @"\01?WriteOutput +// CHECK: ret void + +// CHECK-LABEL: define internal i32 @"\01?SquareInt +// CHECK: ret i32 + +// CHECK-LABEL: define internal float @"\01?SquareFloat +// CHECK: ret float + +// CHECK-LABEL: define internal float @"\01?Clamp01 +// CHECK: ret float + +RWBuffer output : register(u0); + +// Deduces int from a single return statement. +// expected-warning@+1 {{'auto' type specifier is a HLSL 202x extension}} +auto SquareInt(int x) { + return x * x; +} + +// Deduces float from a single return statement. +// expected-warning@+1 {{'auto' type specifier is a HLSL 202x extension}} +auto SquareFloat(float x) { + return x * x; +} + +// Deduces float4 from a single return statement. +// expected-warning@+1 {{'auto' type specifier is a HLSL 202x extension}} +auto Scale(float4 v, float s) { + return v * s; +} + +// Deduces void when no return statement is present. +// expected-warning@+1 {{'auto' type specifier is a HLSL 202x extension}} +auto WriteOutput(uint i, float v) { + output[i] = v; +} + +// Multiple return statements with the same deduced type are allowed. +// expected-warning@+1 {{'auto' type specifier is a HLSL 202x extension}} +auto Clamp01(float v) { + if (v < 0.0f) + return 0.0f; + if (v > 1.0f) + return 1.0f; + return v; +} + +[numthreads(1,1,1)] +void main() { + float4 v = float4(1, 2, 3, 4); + float4 s = Scale(v, 0.5f); + WriteOutput(0, (float)SquareInt(3) + SquareFloat(2.5f) + s.x + Clamp01(1.5f)); +} From 1c227d394f0f9dfd7505380d2fee533c23845f2b Mon Sep 17 00:00:00 2001 From: Chris Bieneman Date: Thu, 10 Sep 2026 18:19:01 -0500 Subject: [PATCH 2/9] Error on non-deducible types --- tools/clang/lib/Sema/SemaStmt.cpp | 11 ++++ .../auto/auto-return-undeducible-types.hlsl | 53 +++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-undeducible-types.hlsl diff --git a/tools/clang/lib/Sema/SemaStmt.cpp b/tools/clang/lib/Sema/SemaStmt.cpp index 5235d76f48..5cb7194e50 100644 --- a/tools/clang/lib/Sema/SemaStmt.cpp +++ b/tools/clang/lib/Sema/SemaStmt.cpp @@ -3071,6 +3071,17 @@ bool Sema::DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD, if (DAR != DAR_Succeeded) return true; + // HLSL Change Begin - Diagnose deduced return types that 'auto' cannot + // represent. A dependent deduced type cannot be classified yet; defer the + // check to instantiation, when 'auto' is re-deduced to a concrete type. + if (getLangOpts().HLSL && !Deduced->isDependentType() && + !hlsl::IsTypeDeducibleWithAuto(*this, Deduced)) { + Diag(RetExpr->getExprLoc(), diag::err_hlsl_auto_undeducible_type) + << Deduced; + return true; + } + // HLSL Change End + // If a local type is part of the returned type, mark its fields as // referenced. LocalTypedefNameReferencer Referencer(*this); diff --git a/tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-undeducible-types.hlsl b/tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-undeducible-types.hlsl new file mode 100644 index 0000000000..f8648a2040 --- /dev/null +++ b/tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-undeducible-types.hlsl @@ -0,0 +1,53 @@ +// RUN: %dxc -T lib_6_3 -HV 202x -verify %s + +// Test that deducing a return type that 'auto' cannot represent produces a +// diagnostic, mirroring the checks already performed for 'auto' variables +// (see auto-undeducible-types.hlsl and auto-no-subobject.hlsl). + +Texture2D tex : register(t0); +Texture2DMS texMS : register(t1); + +GlobalRootSignature grs = {"CBV(b0)"}; + +// String literals cannot be deduced by 'auto'. +auto GetString() { + // expected-error@+1 {{'auto' cannot deduce type 'literal string'}} + return "abc"; +} + +// The proxy types used for '.mips'/'.sample' subscript operators cannot be +// deduced by 'auto'. +auto GetMips() { + // expected-error@+1 {{'auto' cannot deduce type}} + return tex.mips; +} + +auto GetMipsElement() { + // expected-error@+1 {{'auto' cannot deduce type}} + return tex.mips[0]; +} + +auto GetSample() { + // expected-error@+1 {{'auto' cannot deduce type}} + return texMS.sample; +} + +auto GetSampleElement() { + // expected-error@+1 {{'auto' cannot deduce type}} + return texMS.sample[0]; +} + +// Subobjects cannot be deduced by 'auto'. +auto GetSubobject() { + // expected-error@+1 {{'auto' cannot deduce type 'GlobalRootSignature'}} + return grs; +} + +// Fully subscripted mips/sample accesses deduce a normal, deducible type. +auto GetMipsValue() { + return tex.mips[0][int2(1, 2)]; +} + +auto GetSampleValue() { + return texMS.sample[0][int2(1, 2)]; +} From b569a7ce2cef6c80e3a1984c94e34d991c78dc95 Mon Sep 17 00:00:00 2001 From: Chris Bieneman Date: Thu, 10 Sep 2026 20:24:00 -0500 Subject: [PATCH 3/9] Roll back unreachable change --- tools/clang/lib/Sema/SemaDecl.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/clang/lib/Sema/SemaDecl.cpp b/tools/clang/lib/Sema/SemaDecl.cpp index 8f999945fa..5f885be2e4 100644 --- a/tools/clang/lib/Sema/SemaDecl.cpp +++ b/tools/clang/lib/Sema/SemaDecl.cpp @@ -7479,8 +7479,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, NewFD->setVirtualAsWritten(true); } - // HLSL Change - HLSL supports C++14-style deduced return types. - if ((getLangOpts().CPlusPlus14 || getLangOpts().HLSL) && + if ((getLangOpts().CPlusPlus14) && NewFD->getReturnType()->isUndeducedType()) Diag(D.getDeclSpec().getVirtualSpecLoc(), diag::err_auto_fn_virtual); } From d984ebe5f5490acbe9c46bf89f5f4e8b44b9d7e7 Mon Sep 17 00:00:00 2001 From: Chris Bieneman Date: Fri, 11 Sep 2026 09:19:47 -0500 Subject: [PATCH 4/9] Error on inferring dynamic resources ../tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-errors.hlsl ../tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-undeducible-t ypes.hlsl ../tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-errors.hlsl ../tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-undeducible-t ypes.hlsl --- tools/clang/lib/AST/ASTContextHLSL.cpp | 1 + .../hlsl/auto/auto-return-errors.hlsl | 4 ---- .../hlsl/auto/auto-return-undeducible-types.hlsl | 12 +++++++++++- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/tools/clang/lib/AST/ASTContextHLSL.cpp b/tools/clang/lib/AST/ASTContextHLSL.cpp index 6077177939..c63e494fc4 100644 --- a/tools/clang/lib/AST/ASTContextHLSL.cpp +++ b/tools/clang/lib/AST/ASTContextHLSL.cpp @@ -1334,6 +1334,7 @@ CXXRecordDecl *hlsl::DeclareResourceType(ASTContext &context, bool bSampler) { CXXRecordDecl *recordDecl = typeDeclBuilder.getRecordDecl(); recordDecl->addAttr( HLSLDynamicResourceAttr::CreateImplicit(context, bSampler)); + recordDecl->addAttr(HLSLNonAutoDeducibleAttr::CreateImplicit(context)); QualType indexType = context.UnsignedIntTy; QualType resultType = context.getRecordType(recordDecl); diff --git a/tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-errors.hlsl b/tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-errors.hlsl index 339aabf244..d8cb621d7b 100644 --- a/tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-errors.hlsl +++ b/tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-errors.hlsl @@ -24,10 +24,6 @@ auto BadRecurse(int x) { } // expected-note@-3 {{'BadRecurse' declared here}} -// Returning an initializer list as the deduced return value is not allowed. -// (Initializer lists in return statements are also unsupported in HLSL more -// broadly, but the auto-return-type case is still flagged early.) - [numthreads(1,1,1)] void main() { BadDeduction(1); diff --git a/tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-undeducible-types.hlsl b/tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-undeducible-types.hlsl index f8648a2040..a1d57b71c0 100644 --- a/tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-undeducible-types.hlsl +++ b/tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-undeducible-types.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T lib_6_3 -HV 202x -verify %s +// RUN: %dxc -T lib_6_6 -HV 202x -verify %s // Test that deducing a return type that 'auto' cannot represent produces a // diagnostic, mirroring the checks already performed for 'auto' variables @@ -51,3 +51,13 @@ auto GetMipsValue() { auto GetSampleValue() { return texMS.sample[0][int2(1, 2)]; } + +auto GetDynamicResource() { + // expected-error@+1 {{'auto' cannot deduce type '.Resource'}} + return ResourceDescriptorHeap[0]; +} + +auto GetDynamicSampler() { + // expected-error@+1 {{'auto' cannot deduce type '.Sampler'}} + return SamplerDescriptorHeap[0]; +} From fc3ef919ab4b4abfdb1a3036c477861e87e7cb8c Mon Sep 17 00:00:00 2001 From: Chris Bieneman Date: Fri, 11 Sep 2026 09:40:26 -0500 Subject: [PATCH 5/9] Simplify comment for accuracty --- tools/clang/include/clang/Basic/Attr.td | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/clang/include/clang/Basic/Attr.td b/tools/clang/include/clang/Basic/Attr.td index 21b57c8934..2d298fb056 100644 --- a/tools/clang/include/clang/Basic/Attr.td +++ b/tools/clang/include/clang/Basic/Attr.td @@ -1189,8 +1189,7 @@ def HLSLSubObject : InheritableAttr { } // Marks builtin record types that have no deducible value form, so 'auto' must -// not infer them: the inner indexer objects behind .mips / .sample, and the -// subobject types used to configure DXR state objects. +// not infer them. def HLSLNonAutoDeducible : InheritableAttr { let Spellings = []; // No spellings! let Subjects = SubjectList<[CXXRecord]>; From a995d87445e2fd598d60acb5d33fb748a305aa8a Mon Sep 17 00:00:00 2001 From: Chris Bieneman Date: Fri, 11 Sep 2026 09:43:42 -0500 Subject: [PATCH 6/9] Add some extra tests around dynamic resource returns ../tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-undeducible-t ypes.hlsl --- .../hlsl/auto/auto-return-undeducible-types.hlsl | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-undeducible-types.hlsl b/tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-undeducible-types.hlsl index a1d57b71c0..17c74b7f0c 100644 --- a/tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-undeducible-types.hlsl +++ b/tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-undeducible-types.hlsl @@ -61,3 +61,14 @@ auto GetDynamicSampler() { // expected-error@+1 {{'auto' cannot deduce type '.Sampler'}} return SamplerDescriptorHeap[0]; } + +auto GetDynamicResource2() { + return ((RWBuffer)ResourceDescriptorHeap[0]); +} + +auto GetDynamicResource(bool IsRW) { + if (IsRW) + return ((RWBuffer)ResourceDescriptorHeap[0]); + // expected-error@+1 {{'auto' in return type deduced as 'Buffer' here but deduced as 'RWBuffer' in earlier return statement}} + return ((Buffer)ResourceDescriptorHeap[0]); +} From ffa4159640fa65484d62741f1a7bc7f5b76e03c1 Mon Sep 17 00:00:00 2001 From: Chris Bieneman Date: Fri, 11 Sep 2026 09:47:16 -0500 Subject: [PATCH 7/9] Add release note --- docs/ReleaseNotes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/ReleaseNotes.md b/docs/ReleaseNotes.md index aacc4162b1..a40f324922 100644 --- a/docs/ReleaseNotes.md +++ b/docs/ReleaseNotes.md @@ -49,6 +49,8 @@ line upon naming the release. Refer to previous for appropriate section names. with language changes introduced in HLSL 2026. - The legacy effects syntax support is removed in HLSL 202x [#8480](https://github.com/microsoft/DirectXShaderCompiler/issues/8480). +- Added support for `auto` return types for normal functions aligning with C++14 + [#8903](https://github.com/microsoft/DirectXShaderCompiler/issues/8903). #### SPIR-V From 4e9ef8e4033f7450109ed49e2796e04f1c843b55 Mon Sep 17 00:00:00 2001 From: Chris Bieneman Date: Mon, 21 Sep 2026 10:29:12 -0500 Subject: [PATCH 8/9] Fixup for upstream change --- tools/clang/lib/Sema/SemaStmt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/clang/lib/Sema/SemaStmt.cpp b/tools/clang/lib/Sema/SemaStmt.cpp index 5cb7194e50..856748e207 100644 --- a/tools/clang/lib/Sema/SemaStmt.cpp +++ b/tools/clang/lib/Sema/SemaStmt.cpp @@ -3075,7 +3075,7 @@ bool Sema::DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD, // represent. A dependent deduced type cannot be classified yet; defer the // check to instantiation, when 'auto' is re-deduced to a concrete type. if (getLangOpts().HLSL && !Deduced->isDependentType() && - !hlsl::IsTypeDeducibleWithAuto(*this, Deduced)) { + !hlsl::IsTypeDeducibleWithAuto(Deduced)) { Diag(RetExpr->getExprLoc(), diag::err_hlsl_auto_undeducible_type) << Deduced; return true; From bcc525c7ab363cb13f23c6efeb49dd1ea491ea1e Mon Sep 17 00:00:00 2001 From: Chris Bieneman Date: Mon, 21 Sep 2026 10:56:22 -0500 Subject: [PATCH 9/9] Update tests to cover auto returns of template-dependent types ../tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-type.hlsl --- tools/clang/test/CodeGenSPIRV/fn.auto.return.hlsl | 8 +++++++- .../HLSLFileCheckLit/hlsl/auto/auto-return-type.hlsl | 11 ++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/tools/clang/test/CodeGenSPIRV/fn.auto.return.hlsl b/tools/clang/test/CodeGenSPIRV/fn.auto.return.hlsl index 67b9d74285..b66b267d61 100644 --- a/tools/clang/test/CodeGenSPIRV/fn.auto.return.hlsl +++ b/tools/clang/test/CodeGenSPIRV/fn.auto.return.hlsl @@ -12,6 +12,7 @@ // CHECK-DAG: %SquareFloat = OpFunction [[FLOAT]] None // CHECK-DAG: %Scale = OpFunction [[V4FLOAT]] None // CHECK-DAG: %WriteOutput = OpFunction %void None +// CHECK-DAG: %Sum = OpFunction [[FLOAT]] None RWBuffer output : register(u0); @@ -27,6 +28,11 @@ auto Scale(float4 v, float s) { return v * s; } +template +auto Sum(T L, T R) { + return L + R; +} + auto WriteOutput(uint i, float v) { output[i] = v; } @@ -35,5 +41,5 @@ auto WriteOutput(uint i, float v) { void main() { float4 v = float4(1, 2, 3, 4); float4 s = Scale(v, 0.5f); - WriteOutput(0, (float)SquareInt(3) + SquareFloat(2.5f) + s.x); + WriteOutput(0, (float)SquareInt(3) + Sum(SquareFloat(2.5f), s.x)); } diff --git a/tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-type.hlsl b/tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-type.hlsl index 9f532c67d1..24c2566f06 100644 --- a/tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-type.hlsl +++ b/tools/clang/test/HLSLFileCheckLit/hlsl/auto/auto-return-type.hlsl @@ -18,6 +18,9 @@ // CHECK-LABEL: define internal float @"\01?SquareFloat // CHECK: ret float +// CHECK-LABEL: define internal float @"\01??$Sum +// CHECK ret float + // CHECK-LABEL: define internal float @"\01?Clamp01 // CHECK: ret float @@ -57,9 +60,15 @@ auto Clamp01(float v) { return v; } +// expected-warning@+2 {{'auto' type specifier is a HLSL 202x extension}} +template +auto Sum(T L, T R) { + return L + R; +} + [numthreads(1,1,1)] void main() { float4 v = float4(1, 2, 3, 4); float4 s = Scale(v, 0.5f); - WriteOutput(0, (float)SquareInt(3) + SquareFloat(2.5f) + s.x + Clamp01(1.5f)); + WriteOutput(0, (float)SquareInt(3) + SquareFloat(2.5f) + Sum(s.x, Clamp01(1.5f))); }