summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/slang/core.meta.slang9
-rw-r--r--source/slang/slang-diagnostic-defs.h4
-rw-r--r--source/slang/slang-ir-use-uninitialized-out-param.cpp29
3 files changed, 32 insertions, 10 deletions
diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang
index 849e4c642..5265d6cb6 100644
--- a/source/slang/core.meta.slang
+++ b/source/slang/core.meta.slang
@@ -2649,6 +2649,15 @@ __generic<T, U>
__intrinsic_op($(kIROp_Reinterpret))
T reinterpret(U value);
+// Use an otherwise unused value
+//
+// This can be used to silence the warning about returning before initializing
+// an out paramter.
+__generic<T>
+[__readNone]
+[ForceInline]
+void unused(inout T){}
+
// Specialized function
/// Given a string returns an integer hash of that string.
diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h
index 130102e44..ec8131824 100644
--- a/source/slang/slang-diagnostic-defs.h
+++ b/source/slang/slang-diagnostic-defs.h
@@ -595,7 +595,9 @@ DIAGNOSTIC(40020, Error, cannotUnrollLoop, "loop does not terminate within the l
DIAGNOSTIC(41000, Warning, unreachableCode, "unreachable code detected")
DIAGNOSTIC(41010, Warning, missingReturn, "control flow may reach end of non-'void' function")
-DIAGNOSTIC(41015, Error, usingUninitializedValue, "use of uninitialized value.")
+DIAGNOSTIC(41015, Error, usingUninitializedValue, "use of uninitialized value '$0'")
+DIAGNOSTIC(41016, Warning, returningWithUninitializedOut, "returning without initializing out parameter '$0'")
+DIAGNOSTIC(41017, Warning, returningWithPartiallyUninitializedOut, "returning without fully initializing out parameter '$0'")
DIAGNOSTIC(41011, Error, typeDoesNotFitAnyValueSize, "type '$0' does not fit in the size required by its conforming interface.")
DIAGNOSTIC(41012, Note, typeAndLimit, "sizeof($0) is $1, limit is $2")
diff --git a/source/slang/slang-ir-use-uninitialized-out-param.cpp b/source/slang/slang-ir-use-uninitialized-out-param.cpp
index 9818cec53..64f5f8bd3 100644
--- a/source/slang/slang-ir-use-uninitialized-out-param.cpp
+++ b/source/slang/slang-ir-use-uninitialized-out-param.cpp
@@ -75,27 +75,33 @@ namespace Slang
}
}
// Check all address loads.
- List<IRLoad*> loads;
+ List<IRInst*> loadsAndReturns;
for (auto addr : addresses)
{
for (auto use = addr->firstUse; use; use = use->nextUse)
{
if (auto load = as<IRLoad>(use->getUser()))
- loads.add(load);
+ loadsAndReturns.add(load);
}
}
+ for(const auto& b : func->getBlocks())
+ {
+ auto t = b->getTerminator();
+ if (t->m_op == kIROp_Return)
+ loadsAndReturns.add(t);
+ }
for (auto store : stores)
{
// Remove insts from `loads` that is reachable from the store.
- for (Index i = 0; i < loads.getCount();)
+ for (Index i = 0; i < loadsAndReturns.getCount();)
{
- auto load = loads[i];
- if (!canAddressesPotentiallyAlias(func, store.address, loads[i]->getPtr()))
+ auto load = as<IRLoad>(loadsAndReturns[i]);
+ if (load && !canAddressesPotentiallyAlias(func, store.address, load->getPtr()))
continue;
- if (reachability.isInstReachable(store.storeInst, load))
+ if (reachability.isInstReachable(store.storeInst, loadsAndReturns[i]))
{
- loads.fastRemoveAt(i);
+ loadsAndReturns.fastRemoveAt(i);
}
else
{
@@ -104,9 +110,14 @@ namespace Slang
}
}
// If there are any loads left, it means they are using uninitialized out params.
- for (auto load : loads)
+ for (auto load : loadsAndReturns)
{
- sink->diagnose(load, Diagnostics::usingUninitializedValue);
+ sink->diagnose(
+ load,
+ load->m_op == kIROp_Return
+ ? Diagnostics::returningWithUninitializedOut
+ : Diagnostics::usingUninitializedValue,
+ param);
}
}
}