Skip to content

Commit b9c5bec

Browse files
Fix segfault when compiling hlsl intrinsics with variadic argu… (microsoft#6012)
For hlsl intrinsics with variadic argument lists (in my case: printf), the number of param modifiers and function arguments did not match, resulting in segfaults when creating a FunctionProtoType. The presumed oversight: The paramsMods was made twice as large as intended, by first resizing to the expected number of arguments, and then pushing back the same number of arguments again. A fix that seems to resolve this issue comes with this PR. Please have a look. Edit: The suggested modifications do not feel as if they are the proper way to handle modParams initialization. They only defuse the issue I had with printf. If you think this issue needs a better solution and/or a proper bug report before suggesting a PR, please let me know - and please apologize in case I opened up a PR too early.
1 parent c97d488 commit b9c5bec

File tree

1 file changed

+13
-21
lines changed

1 file changed

+13
-21
lines changed

tools/clang/lib/Sema/SemaHLSL.cpp

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1836,25 +1836,21 @@ ParamModsFromIntrinsicArg(const HLSL_INTRINSIC_ARGUMENT *pArg) {
18361836
DXASSERT(qwUsage & AR_QUAL_IN, "else usage is incorrect");
18371837
return hlsl::ParameterModifier(hlsl::ParameterModifier::Kind::In);
18381838
}
1839-
18401839
static void InitParamMods(const HLSL_INTRINSIC *pIntrinsic,
1841-
SmallVectorImpl<hlsl::ParameterModifier> &paramMods) {
1840+
SmallVectorImpl<hlsl::ParameterModifier> &paramMods,
1841+
size_t VariadicArgumentCount = 0u) {
18421842
// The first argument is the return value, which isn't included.
1843-
UINT i = 1, size = paramMods.size();
1844-
for (; i < pIntrinsic->uNumArgs; ++i) {
1843+
for (unsigned i = 1; i < pIntrinsic->uNumArgs; ++i) {
18451844
// Once we reach varargs we can break out of this loop.
18461845
if (IsVariadicArgument(pIntrinsic->pArgs[i]))
18471846
break;
18481847
paramMods.push_back(ParamModsFromIntrinsicArg(&pIntrinsic->pArgs[i]));
18491848
}
1850-
18511849
// For variadic functions, any argument not explicitly specified will be
18521850
// considered an input argument.
1853-
if (IsVariadicIntrinsicFunction(pIntrinsic)) {
1854-
for (; i < size; ++i) {
1855-
paramMods.push_back(
1856-
hlsl::ParameterModifier(hlsl::ParameterModifier::Kind::In));
1857-
}
1851+
for (unsigned i = 0; i < VariadicArgumentCount; ++i) {
1852+
paramMods.push_back(
1853+
hlsl::ParameterModifier(hlsl::ParameterModifier::Kind::In));
18581854
}
18591855
}
18601856

@@ -1913,20 +1909,16 @@ AddHLSLIntrinsicFunction(ASTContext &context, NamespaceDecl *NS,
19131909
DeclContext *currentDeclContext = context.getTranslationUnitDecl();
19141910
std::vector<QualType> &functionArgQualTypes = *functionArgQualTypesVector;
19151911
const size_t functionArgTypeCount = functionArgQualTypes.size();
1916-
19171912
const bool isVariadic = IsVariadicIntrinsicFunction(pIntrinsic);
1913+
// For variadic functions, the number of arguments is larger than the
1914+
// function declaration signature.
1915+
const size_t VariadicArgumentCount =
1916+
isVariadic ? (functionArgTypeCount - (pIntrinsic->uNumArgs - 1)) : 0;
19181917
DXASSERT(isVariadic || functionArgTypeCount - 1 <= g_MaxIntrinsicParamCount,
19191918
"otherwise g_MaxIntrinsicParamCount should be larger");
19201919

19211920
SmallVector<hlsl::ParameterModifier, g_MaxIntrinsicParamCount> paramMods;
1922-
1923-
if (isVariadic) {
1924-
// For variadic functions, the number of arguments is larger than the
1925-
// function declaration signature.
1926-
paramMods.resize(functionArgTypeCount);
1927-
}
1928-
1929-
InitParamMods(pIntrinsic, paramMods);
1921+
InitParamMods(pIntrinsic, paramMods, VariadicArgumentCount);
19301922

19311923
for (size_t i = 1; i < functionArgTypeCount; i++) {
19321924
// Change out/inout param to reference type.
@@ -3733,7 +3725,7 @@ class HLSLExternalSource : public ExternalSemaSource {
37333725
// Get types for parameters.
37343726
SmallVector<QualType, 2> paramTypes =
37353727
VkIntrinsicFunctionParamTypes(intrinsic, templateTypeParmDecls);
3736-
SmallVector<ParameterModifier, g_MaxIntrinsicParamCount> paramMods;
3728+
SmallVector<hlsl::ParameterModifier, g_MaxIntrinsicParamCount> paramMods;
37373729
InitParamMods(intrinsic, paramMods);
37383730

37393731
// Create FunctionDecl.
@@ -5723,7 +5715,7 @@ class HLSLExternalSource : public ExternalSemaSource {
57235715
parameterTypes[0] = m_context->getLValueReferenceType(retTy);
57245716

57255717
// Create a new specialization.
5726-
SmallVector<ParameterModifier, g_MaxIntrinsicParamCount> paramMods;
5718+
SmallVector<hlsl::ParameterModifier, g_MaxIntrinsicParamCount> paramMods;
57275719
InitParamMods(intrinsic, paramMods);
57285720

57295721
for (unsigned int i = 1; i < parameterTypeCount; i++) {

0 commit comments

Comments
 (0)