Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 26 additions & 3 deletions tools/clang/lib/Analysis/UninitializedValues.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,12 @@ class CFGBlockValues {
return declToIndex.getHLSLOutParams();
}
// HLSL Change End - Treat `out` parameters as uninitialized values.

// HLSL Change Begin - check the variable is in the declToIndex map
bool hasValueIndex(const VarDecl *vd) {
return declToIndex.getValueIndex(vd).hasValue();
}
// HLSL Change End - check the variable is in the declToIndex map
};
} // end anonymous namespace

Expand Down Expand Up @@ -781,10 +787,23 @@ void TransferFunctions::VisitDeclRefExpr(DeclRefExpr *dr) {
case ClassifyRefs::Ignore:
break;
case ClassifyRefs::Use:
reportUse(dr, cast<VarDecl>(dr->getDecl()));
// HLSL Change Begin - check the variable is in the declToIndex map
// before calling reportUse(). HLSL out parameters or local variables from
// template instantiations may not be mapped in the current DeclContext.
if (const VarDecl *VD = cast<VarDecl>(dr->getDecl())) {
if (vals.hasValueIndex(VD))
reportUse(dr, VD);
}
// HLSL Change End - check the variable is in the declToIndex map
break;
case ClassifyRefs::Init:
vals[cast<VarDecl>(dr->getDecl())] = Initialized;
// HLSL Change Begin - check the variable is in the declToIndex map
// before marking it Initialized.
if (const VarDecl *VD = cast<VarDecl>(dr->getDecl())) {
if (vals.hasValueIndex(VD))
vals[VD] = Initialized;
}
// HLSL Change End - check the variable is in the declToIndex map
break;
case ClassifyRefs::SelfInit:
handler.handleSelfInit(cast<VarDecl>(dr->getDecl()));
Expand All @@ -795,8 +814,12 @@ void TransferFunctions::VisitDeclRefExpr(DeclRefExpr *dr) {
void TransferFunctions::VisitBinaryOperator(BinaryOperator *BO) {
if (BO->getOpcode() == BO_Assign) {
FindVarResult Var = findVar(BO->getLHS());
// HLSL Change Begin - check the variable is in the declToIndex map
// before marking it Initialized.
if (const VarDecl *VD = Var.getDecl())
vals[VD] = Initialized;
if (vals.hasValueIndex(VD))
vals[VD] = Initialized;
// HLSL Change End - check the variable is in the declToIndex map
}
}

Expand Down
63 changes: 63 additions & 0 deletions tools/clang/test/DXC/template_uninitialized_values.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// RUN: dxc -E main -T cs_6_6 -HV 2021 -Wno-unused-value %s | FileCheck %s

// Asserts in UnitializedValues.cpp were triggered by the following code
// examples. The cause was that HLSL out parameters or local variables from
// template instantiations may not be present in the declToIndex map when the
// variable's DeclContext differs from the analysis context (common in
// template instantiations).
// The fix was to add defensive checks so that if the variable isn't tracked
// it is silently ignored.

// CHECK: define void @main()

template <typename R>
void test(R x, out uint result) {
uint repro = 0;
result = 10;
}

[numthreads(32, 32, 1)] void main(uint2 threadId: SV_DispatchThreadID) {
uint x;
test(10, x);
}

template <typename NameType>
void func2(out uint var1)
{
uint var3;
uint var4;
uint var5;
uint var6;
uint var7;
uint var8;
uint var9;
uint var10;
uint var11;
uint var12;
uint var13;
uint var14;
uint var15;
uint var16;
uint var17;
uint var18;
uint var19;
uint var20;
uint var21;
uint var22;
uint var23;
uint var24;
uint var25;
uint var26;
uint var27;
uint var28;
uint var29;
uint var30;
uint var31;
var1;
}

void func1()
{
uint var33;
func2<uint>(var33);
}
Loading