Required prerequisites
Describe the bug
ValidateReturnStatements.all_paths_return (python/cudaq/kernel/analysis.py:191-206), the
compile-time check behind cudaq.kernel functions with return type annotations must have a return statement., treats a for/while loop as guaranteeing a return whenever its body
alone always returns, independent of whether the loop is ever entered:
if isinstance(stmt, (ast.For, ast.While)):
if all_paths_return(stmt.body) or all_paths_return(
stmt.orelse):
return True
For a loop whose trip count is a runtime value (for i in range(n):, while i < n:), this is
unsound: if the loop executes zero times, control falls off the end of the function with no
return statement ever having run, and the fatal error is never raised. The kernel compiles
successfully and the backend's cc.UndefOp fallback (ast_bridge.py's visit_FunctionDef
entry-block finalization) silently manufactures whatever value happens to be returned instead.
Steps to reproduce the bug
import cudaq
@cudaq.kernel
def kernel(n: int) -> int:
for i in range(n):
return 1
# falls through here when n <= 0, with no return statement having executed
print("compiled without error") # should have raised RuntimeError
print(cudaq.run(kernel, 0, shots_count=1)) # returns a value with no defined meaning
The sibling ast.If check just above is written correctly, requiring both branches to
return (all_paths_return(stmt.body) and all_paths_return(stmt.orelse)); the loop check uses
or instead, which is the bug.
What did you expect to happen?
Compilation should raise RuntimeError: cudaq.kernel functions with return type annotations must have a return statement., exactly as it already does for the equivalent case where the
loop body only conditionally returns (e.g. for i in range(n): if i == 0: return 1, already
covered by test_return_from_if_and_else_loop_having_for_with_no_return).
Environment
Reproduced against the installed cuda_quantum_cu13 0.15.1 wheel
(aca5853a76d499ecc3d5f97c2e06163ae99d9c75) on Linux/Python 3.12; python/cudaq/kernel/analysis.py
is byte-identical between that wheel and current main
(00536511e91775ca829e4fa816663e1618edb185), confirmed via git log <wheel-sha>..main -- python/cudaq/kernel/analysis.py (empty) and a direct diff.
Required prerequisites
Describe the bug
ValidateReturnStatements.all_paths_return(python/cudaq/kernel/analysis.py:191-206), thecompile-time check behind
cudaq.kernel functions with return type annotations must have a return statement., treats afor/whileloop as guaranteeing a return whenever its bodyalone always returns, independent of whether the loop is ever entered:
For a loop whose trip count is a runtime value (
for i in range(n):,while i < n:), this isunsound: if the loop executes zero times, control falls off the end of the function with no
return statement ever having run, and the fatal error is never raised. The kernel compiles
successfully and the backend's
cc.UndefOpfallback (ast_bridge.py'svisit_FunctionDefentry-block finalization) silently manufactures whatever value happens to be returned instead.
Steps to reproduce the bug
The sibling
ast.Ifcheck just above is written correctly, requiring both branches toreturn (
all_paths_return(stmt.body) and all_paths_return(stmt.orelse)); the loop check usesorinstead, which is the bug.What did you expect to happen?
Compilation should raise
RuntimeError: cudaq.kernel functions with return type annotations must have a return statement., exactly as it already does for the equivalent case where theloop body only conditionally returns (e.g.
for i in range(n): if i == 0: return 1, alreadycovered by
test_return_from_if_and_else_loop_having_for_with_no_return).Environment
Reproduced against the installed
cuda_quantum_cu130.15.1 wheel(
aca5853a76d499ecc3d5f97c2e06163ae99d9c75) on Linux/Python 3.12;python/cudaq/kernel/analysis.pyis byte-identical between that wheel and current
main(
00536511e91775ca829e4fa816663e1618edb185), confirmed viagit log <wheel-sha>..main -- python/cudaq/kernel/analysis.py(empty) and a direct diff.