From a2399f6ad40434ae59b3ff5b2249c8613740331e Mon Sep 17 00:00:00 2001 From: Simon Moll Date: Thu, 8 May 2025 11:40:54 +0200 Subject: [PATCH] Fix PAQ memory leak by never pushing redundant stages to backing vector Closes #7104 --- tools/clang/lib/Parse/ParseDecl.cpp | 14 +++++++++++-- .../payload_qualifier/redundant_clause.hlsl | 21 +++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 tools/clang/test/HLSLFileCheck/hlsl/payload_qualifier/redundant_clause.hlsl diff --git a/tools/clang/lib/Parse/ParseDecl.cpp b/tools/clang/lib/Parse/ParseDecl.cpp index 59be41a484..023577fcc7 100644 --- a/tools/clang/lib/Parse/ParseDecl.cpp +++ b/tools/clang/lib/Parse/ParseDecl.cpp @@ -397,9 +397,19 @@ bool Parser::MaybeParseHLSLAttributes(std::vector &ta stage = hlsl::DXIL::PayloadAccessShaderStage::Miss; } else if (shaderStage == "anyhit") { stage = hlsl::DXIL::PayloadAccessShaderStage::Anyhit; - } + } + + // mod.ShaderStages can only take four elements before it starts to + // migrate. Make sure not to add redundant stages. + bool IsDuplicate = false; + for (auto s : mod.ShaderStages) + if (s == stage) { + IsDuplicate = true; + break; + } + if (!IsDuplicate) + mod.ShaderStages.push_back(stage); - mod.ShaderStages.push_back(stage); ConsumeToken(); // consume shader type if (Tok.is(tok::comma)) // check if we have a list of shader types diff --git a/tools/clang/test/HLSLFileCheck/hlsl/payload_qualifier/redundant_clause.hlsl b/tools/clang/test/HLSLFileCheck/hlsl/payload_qualifier/redundant_clause.hlsl new file mode 100644 index 0000000000..96b6c6fc81 --- /dev/null +++ b/tools/clang/test/HLSLFileCheck/hlsl/payload_qualifier/redundant_clause.hlsl @@ -0,0 +1,21 @@ +// RUN: %dxc -T lib_6_9 %s + +// COM: No FileCheck required: Error raised by ASAN-enabled DXC builds where underlying bug #7104 is not fixed. +// COM: This checks that the backing memory of the shader stages vector does not migrate when more than four (it's preallocated size) shader stages are added. + +struct [raypayload] Payload +{ + int a : read(anyhit,caller,miss,closesthit,closesthit) : write(anyhit,caller,miss,closesthit,caller); +}; + +struct Attribs +{ + float2 barys; +}; + +[shader("closesthit")] +void ClosestHitInOut( inout Payload payload, in Attribs attribs ) +{ + if (payload.a == 1) + payload.a = 2; +} \ No newline at end of file