cda: mark functions with loops as potentially non-returning#6
Open
vmihalko wants to merge 1 commit intostaticafi:masterfrom
Open
cda: mark functions with loops as potentially non-returning#6vmihalko wants to merge 1 commit intostaticafi:masterfrom
vmihalko wants to merge 1 commit intostaticafi:masterfrom
Conversation
computeFuncInfo() missed functions that may loop forever — neither the syntactic unreachable-block check nor callee propagation catches them. This causes the slicer to drop code after such calls (including the instrumented __INSTR_fail), producing false negatives for the termination property. Fix: use LLVM LoopInfo to add every loop header terminator to noret. Sound over-approximation; external functions are unaffected. Add regression test: interproc-loop-noret.c Related: staticafi/symbiotic#274
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
LLVMInterprocCD::computeFuncInfo()seeds the noret set (instructionsafter which a function may not return) using two mechanisms:
ReturnInst: catchesunreachable/abort()/exit()call site
Both miss functions that contain loops:
ReturnInstis reachable but the back-edge preventshasNoSuccessors. Example:while(1);ReturnInstis reachable on one path, but the loop may spin forever.Example:
while(__VERIFIER_nondet_int());In both cases the slicer drops code that appears after a call to such a
function — the call is not treated as a potential noret point so no
interprocedural control dependency is created.
For the termination property this causes a false negative: the
instrumented
__INSTR_failassert is sliced away before KLEE can reach it.Fix
Use LLVM
LoopInfoto detect natural loops in the function.Every loop header's terminator is added to
info.noret.This is a sound over-approximation — any function with a reachable loop
may not return. External/library functions (
isDeclaration()) areunaffected. The fix applies to all CD algorithms (NTSCD, SCD) since
LLVMInterprocCDis constructed unconditionally for all of them.Known limitation
The fix is coarse: bounded loops such as
for (i = 0; i < 10; i++)also markthe function as potentially noret. A future refinement could use
ScalarEvolution::getSmallConstantTripCount()to skip provably bounded loops.Testing
Unit tests — dg slicing suite
No regressions. New regression test added:
tests/slicing/sources/interproc-loop-noret.c— verifies that code after acall to a looping function survives slicing.
SV-COMP termination benchmarks
2621 tasks, 60 s time limit, NTSCD algorithm (
symbiotic --sv-comp --prp=termination ...).The 2 verdict differences (
true → TIMEOUT) are timing noise at the 60 sboundary, not caused by this change.
Slice size impact (from sbt-slicer logs):
with loops inside called functions (Linux driver models, dietlibc string
functions)