[llvm-slicer] strncat side-effect call is sliced away
Summary
When slicing with criteria that should keep the value flow to an assertion
condition, strncat can be removed while strcmp/assert are kept.
This changes semantics (orig PASS, sliced FAIL): destination buffer content
is no longer updated, but the check that expects updated content remains.
Environment
- dg commit:
dc3615d03fedfce62f37604b45d22e31c9d7e557
- slicer:
llvm-slicer (built from this dg checkout)
- clang:
Ubuntu clang version 14.0.0-1ubuntu1.1
- lli:
Ubuntu LLVM version 14.0.0
- OS:
Linux ... WSL2 x86_64 (kernel 5.15.167.4-microsoft-standard-WSL2)
Minimal Reproducer
#include <assert.h>
#include <string.h>
int main(void) {
char buf[16] = "abc";
if (0) {
strcat(buf, "dead");
}
strncat(buf, "XYZ", 3);
int probe_ok = (strcmp(buf, "abcXYZ") == 0);
assert(probe_ok);
return 0;
}
Reproduction Steps
cat > /tmp/min_strncat_deadcode.c <<'EOF'
#include <assert.h>
#include <string.h>
int main(void) {
char buf[16] = "abc";
if (0) {
strcat(buf, "dead");
}
strncat(buf, "XYZ", 3);
int probe_ok = (strcmp(buf, "abcXYZ") == 0);
assert(probe_ok);
return 0;
}
EOF
clang-14 -O0 -g -c -emit-llvm /tmp/min_strncat_deadcode.c -o /tmp/min_strncat_deadcode.bc
lli-14 /tmp/min_strncat_deadcode.bc
# either criterion reproduces:
llvm-slicer -c __assert_fail /tmp/min_strncat_deadcode.bc -o /tmp/min_strncat_deadcode.assert.sliced.bc
lli-14 /tmp/min_strncat_deadcode.assert.sliced.bc
llvm-slicer -c 14:probe_ok /tmp/min_strncat_deadcode.bc -o /tmp/min_strncat_deadcode.line.sliced.bc
lli-14 /tmp/min_strncat_deadcode.line.sliced.bc
Actual Result
- Unsliced run passes.
- Sliced runs fail with assertion abort:
Assertion `probe_ok' failed.
Expected Result
Slicing should preserve effects needed to compute the criterion-dependent
condition. In this program, strncat should not be removed when strcmp/assert
remain in the slice.
IR Evidence
Original IR contains:
%6 = call i8* @strncat(...)
%8 = call i32 @strcmp(...)
call void @__assert_fail(...)
Sliced IR contains:
%5 = call i32 @strcmp(...)
call void @__assert_fail(...)
strncat is removed, but the check that depends on its buffer write is still
present.
Additional Diagnostic
Using --undefined-funs=rw-args keeps strncat in the slice and the sliced
program passes for this reproducer, which suggests the issue is related to
missing side-effect modeling for this external call under default settings.
[llvm-slicer] strncat side-effect call is sliced away
Summary
When slicing with criteria that should keep the value flow to an assertion
condition,
strncatcan be removed whilestrcmp/assertare kept.This changes semantics (
orig PASS,sliced FAIL): destination buffer contentis no longer updated, but the check that expects updated content remains.
Environment
dc3615d03fedfce62f37604b45d22e31c9d7e557llvm-slicer(built from this dg checkout)Ubuntu clang version 14.0.0-1ubuntu1.1Ubuntu LLVM version 14.0.0Linux ... WSL2 x86_64(kernel5.15.167.4-microsoft-standard-WSL2)Minimal Reproducer
Reproduction Steps
Actual Result
Expected Result
Slicing should preserve effects needed to compute the criterion-dependent
condition. In this program,
strncatshould not be removed whenstrcmp/assertremain in the slice.
IR Evidence
Original IR contains:
Sliced IR contains:
strncatis removed, but the check that depends on its buffer write is stillpresent.
Additional Diagnostic
Using
--undefined-funs=rw-argskeepsstrncatin the slice and the slicedprogram passes for this reproducer, which suggests the issue is related to
missing side-effect modeling for this external call under default settings.