-
Notifications
You must be signed in to change notification settings - Fork 45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Simplify invariant output #798
Conversation
* print only one variable per equivalence class * update tests Signed-off-by: Elazar Gershuni <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 7
🧹 Outside diff range comments (2)
test-data/unsigned.yaml (1)
Missing test coverage for critical edge cases
The test suite needs additional coverage for:
- Equality comparisons (==)
- Mixed signed/unsigned operations
- Explicit NaN/undefined behavior
- Boundary value combinations between INT_MIN and INT_MAX
- Overflow/underflow scenarios
🔗 Analysis chain
Line range hint
1-1203
: Verify test coverage for edge cases.The test suite covers various comparison scenarios but should be verified for completeness.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check for potential missing test cases by analyzing the test patterns # Look for test cases with specific patterns echo "Checking test coverage for different comparison operators..." grep -c "assume.*[<>=!]" test-data/unsigned.yaml echo "Checking test coverage for different value ranges..." grep -c "INT.*MAX\|INT.*MIN\|UINT" test-data/unsigned.yaml echo "Checking test coverage for signed vs unsigned comparisons..." grep -c "assume.*s[<>=]" test-data/unsigned.yamlLength of output: 549
Script:
#!/bin/bash # Check for specific edge cases that might be missing # Check for boundary value combinations echo "=== Checking boundary value combinations ===" rg "assume.*(\[INT.*MAX.*INT.*MIN|\[UINT.*MAX.*INT)" test-data/unsigned.yaml # Check for mixed signed/unsigned operations echo -e "\n=== Checking mixed signed/unsigned operations ===" rg "test-case:.*\"assume.*[^s][<>=].*s[<>=]" test-data/unsigned.yaml # Check for equality comparisons echo -e "\n=== Checking equality comparisons ===" rg "assume.*==" test-data/unsigned.yaml # Check for overflow/underflow cases echo -e "\n=== Checking overflow/underflow cases ===" rg "test-case:.*overflow|underflow" test-data/unsigned.yaml # Check for NaN/undefined behavior echo -e "\n=== Checking NaN/undefined cases ===" rg "test-case:.*NaN|undefined|null" test-data/unsigned.yamlLength of output: 861
src/crab/split_dbm.cpp (1)
Line range hint
1198-1222
: Simplify and optimize interval extraction logic.The interval extraction code is complex and can be simplified for better readability and performance. Consider refactoring to reduce nested conditions and improve clarity.
Refactored code:
for (vert_id v : g_excl.verts()) { const auto pvar = rev_map[v]; if (!pvar || !representatives.contains(*pvar)) { continue; } if (!g.elem(0, v) && !g.elem(v, 0)) { continue; } interval_t v_out = get_interval_for_vertex(v); if (v_out.is_bottom()) { continue; } variable_t variable = *pvar; std::string invariant = format_invariant(variable, v_out); result.insert(invariant); }Where
get_interval_for_vertex
andformat_invariant
are helper functions to abstract the logic.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
📒 Files selected for processing (22)
src/crab/split_dbm.cpp
(4 hunks)src/crab/var_factory.cpp
(1 hunks)src/crab/variable.hpp
(1 hunks)test-data/add.yaml
(0 hunks)test-data/assign.yaml
(1 hunks)test-data/atomic.yaml
(22 hunks)test-data/call.yaml
(0 hunks)test-data/callx.yaml
(0 hunks)test-data/full64.yaml
(3 hunks)test-data/jump.yaml
(2 hunks)test-data/loop.yaml
(8 hunks)test-data/movsx.yaml
(0 hunks)test-data/packet.yaml
(4 hunks)test-data/pointer.yaml
(2 hunks)test-data/sdivmod.yaml
(0 hunks)test-data/sext.yaml
(0 hunks)test-data/shift.yaml
(0 hunks)test-data/stack.yaml
(1 hunks)test-data/subtract.yaml
(0 hunks)test-data/udivmod.yaml
(0 hunks)test-data/uninit.yaml
(0 hunks)test-data/unsigned.yaml
(18 hunks)
💤 Files with no reviewable changes (10)
- test-data/add.yaml
- test-data/call.yaml
- test-data/callx.yaml
- test-data/movsx.yaml
- test-data/sdivmod.yaml
- test-data/sext.yaml
- test-data/shift.yaml
- test-data/subtract.yaml
- test-data/udivmod.yaml
- test-data/uninit.yaml
🧰 Additional context used
📓 Learnings (2)
test-data/loop.yaml (1)
Learnt from: Alan-Jowett
PR: vbpf/ebpf-verifier#745
File: test-data/loop.yaml:377-398
Timestamp: 2024-11-12T09:50:23.369Z
Learning: In `test-data/loop.yaml`, for the test case **"very large loop > 100K iterations"**, additional post conditions like `r0.svalue>0` and `r0.uvalue>0` are not required.
test-data/pointer.yaml (1)
Learnt from: Alan-Jowett
PR: vbpf/ebpf-verifier#742
File: test-data/pointer.yaml:1-357
Timestamp: 2024-11-12T09:50:16.890Z
Learning: In `test-data/pointer.yaml`, for the 32-bit pointer truncation test cases, the verifier doesn't emit post conditions, so adding post-conditions is not applicable.
🔇 Additional comments (30)
src/crab/variable.hpp (1)
81-81
: Verify printing_order usage in equivalence class display.
The method is part of the invariant output enhancement. Let's verify its integration.
✅ Verification successful
printing_order implementation aligns with PR objectives
The method is correctly used in split_dbm.cpp
to determine the representative variable when displaying equivalence classes. The implementation in var_factory.cpp
uses lexicographical ordering of variable names, which provides a stable and consistent way to select representatives.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Find where printing_order is used to display equivalence classes
# Find files using printing_order
rg -l "printing_order"
# Show context of printing_order usage
rg -B 3 -A 3 "printing_order"
# Look for equivalence class related code
ast-grep --pattern 'class $_ {
$$$
equivalence
$$$
}'
Length of output: 1462
Script:
#!/bin/bash
# Find implementation details around equivalence classes and their display
rg -B 5 -A 10 "class.*equivalence"
# Look for methods that might use printing_order for display
rg -B 3 -A 5 "print|display|write|output.*equivalence"
# Find where variables are sorted or compared
ast-grep --pattern 'std::sort($$$variable$$$)'
ast-grep --pattern 'std::min($$$variable$$$)'
Length of output: 96617
test-data/full64.yaml (2)
171-171
: LGTM!
The test case correctly verifies equality assumption with immediate value.
Line range hint 184-204
: LGTM!
The test cases correctly verify:
- Register equality assumptions
- Interval intersection for positive intervals with the new concise syntax
test-data/packet.yaml (4)
46-46
: Simplified post-condition maintains correctness.
The removal of redundant packet_offset reference reduces output verbosity while preserving the test's semantic meaning.
64-64
: Consistent simplification with write test case.
The change maintains symmetry with the write test case while reducing redundancy.
115-119
: Consistent constraint expression with previous test.
The changes properly express valid access conditions while maintaining consistency with other test cases.
88-92
: Verify boundary condition completeness.
The new constraints better express size relationships, but let's verify all edge cases are covered.
✅ Verification successful
Boundary conditions are properly covered
The test cases demonstrate comprehensive packet size validation:
- Explicit bounds checking with
packet_size-r3.packet_offset<=65530
- Consistent validation across read/write operations
- Edge cases for both 4-byte and 8-byte accesses
- Proper relationship between packet_offset and packet_size maintained
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for similar packet size boundary tests to ensure consistent validation
rg -l 'packet_size.*packet_offset' --type yaml test-data/
Length of output: 123
Script:
#!/bin/bash
# Check packet size boundary conditions in all related files
rg -A 5 -B 5 'packet_size.*packet_offset' --type yaml test-data/
Length of output: 7544
test-data/loop.yaml (7)
39-41
: Consolidate equivalent value assertions
The post-conditions assert that pc[1]
, r0.svalue
, and r0.uvalue
are all equal. This matches the PR's objective of grouping equivalent values.
79-81
: Consolidate equivalent value assertions
The post-conditions assert that pc[1]
, r0.svalue
, and r0.uvalue
are all equal. This matches the PR's objective of grouping equivalent values.
341-343
: Remove unnecessary post-conditions
Based on the retrieved learning from PR #745, additional post-conditions for r0.svalue>0
and r0.uvalue>0
are not required for this test case.
358-361
: Verify infinite loop detection
The post-conditions assert r0.svalue=0
and r0.uvalue=0
which are the exit conditions. The pc[0]=[1, +oo]
indicates potential infinite iteration.
100-105
: Verify pc[1] bounds
The assertion pc[1]=[1, 4]
needs verification as it represents the loop counter bounds.
✅ Verification successful
pc[1]=[1, 4] bounds are correct
The loop counter bounds assertion is accurate based on the code:
- Initial value:
r0 = 0
- Loop increment:
r0 += 1
- Loop condition:
if r0 <= 3 goto <loop>
- Additional exit condition:
if r1 > r3 goto <out>
The counter r0
starts at 0, increments by 1, and continues until it's greater than 3, making the bounds [1, 4] correct.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify the loop counter bounds by analyzing the loop conditions
ast-grep --pattern $'if r0 <= 3 goto <loop>' test-data/loop.yaml
Length of output: 65
Script:
#!/bin/bash
# Let's examine the content of the loop.yaml file to understand the loop structure
cat test-data/loop.yaml
Length of output: 7008
209-210
: Verify packet size equivalence
The assertion that packet_size=r2.svalue=r2.uvalue
needs verification against the code logic.
✅ Verification successful
Packet size assignment is consistent with type constraints
The assertion packet_size=r2.svalue=r2.uvalue
is valid based on the code context:
- r2 is consistently typed as a number throughout the execution
- The packet_size range [1, 65534] in post-conditions aligns with typical packet size constraints
- The equality between signed and unsigned values (svalue=uvalue) is logical for packet size context
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify packet size calculation logic
ast-grep --pattern $'r2 -= r1' -A 5 test-data/loop.yaml
Length of output: 56
Script:
#!/bin/bash
# Search for packet size related assignments
rg "packet_size" -A 2 -B 2 test-data/loop.yaml
# Search for r2 value assignments
rg "r2\." -A 2 -B 2 test-data/loop.yaml
Length of output: 1004
384-386
: Verify final value calculation
The final value of r0=3
needs verification against the code path.
✅ Verification successful
Final value of r0=3 is correct
The code shows r0 starts at 0 or 1 and is incremented multiple times using r0 += 1
. The final state shows r0.svalue=3
and r0.uvalue=3
, which aligns with the execution path where r0 is incremented to reach the value 3.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify the calculation of final r0 value
rg -A 2 "r0 = 1" test-data/loop.yaml
Length of output: 226
Script:
#!/bin/bash
# Search for any assignments to r0 in the file
rg "r0\s*=\s*\d+" test-data/loop.yaml
Length of output: 226
Script:
#!/bin/bash
# Search for any arithmetic operations involving r0
rg "r0\s*[+\-*/]=|[+\-*/]\s*r0" test-data/loop.yaml
Length of output: 466
Script:
#!/bin/bash
# Get more context around r0 value changes
rg -B 2 -A 2 "r0\.(s|u)value" test-data/loop.yaml
Length of output: 1386
test-data/pointer.yaml (2)
354-358
: LGTM: Pre-conditions match test case requirements
The pre-conditions correctly set up r1 as a context pointer with appropriate value ranges and type.
384-388
: LGTM: Pre-conditions effectively test truncation warning
The pre-conditions use a specific value that helps verify exact truncation behavior when converting pointer to number.
test-data/jump.yaml (3)
37-37
: LGTM: Valid constraint addition
The new post-condition correctly enforces value equality between r0 and r1.
411-415
: LGTM: Type safety constraints
The added post-conditions properly enforce:
- Type consistency between variables
- Value equality between signed/unsigned representations
429-439
: LGTM: Comprehensive value range constraints
The new constraints effectively verify:
- Proper bounds checking
- Value relationships between variables
- Range limitations
test-data/atomic.yaml (4)
7-7
: LGTM: Shared memory test cases correctly establish value equivalence.
The addition of r2.svalue=r2.uvalue
establishes equivalence between signed and unsigned interpretations of shared memory values, aligning with the PR's objective of simplifying invariant output.
Also applies to: 14-14, 19-19, 26-26, 31-31, 38-38, 43-43, 50-50, 55-55, 62-62, 67-67, 74-74, 79-79, 86-86, 91-91, 98-98, 103-103, 110-110, 115-115, 122-122, 127-127, 134-134, 139-139, 146-146, 151-151, 158-158, 163-163, 170-170, 175-175, 182-182, 187-187, 194-194, 199-199, 206-206, 211-211, 218-218, 224-224, 232-232, 238-238, 246-246
266-266
: LGTM: Stack memory test cases maintain consistent value equivalence.
The addition of r2.svalue=r2.uvalue
for stack memory operations maintains consistency with shared memory cases, properly establishing value equivalence for stack-based atomic operations.
Also applies to: 275-275, 282-282, 291-291, 298-298, 307-307, 314-314, 323-323, 330-330, 339-339, 346-346, 355-355, 362-362, 371-371, 378-378, 387-387, 394-394, 403-403, 410-410, 419-419, 426-426, 435-435, 442-442, 451-451, 458-458, 467-467, 474-474, 483-483, 490-490, 499-499, 506-506, 515-515, 522-522, 531-531, 538-538, 547-547, 555-555, 565-565, 573-573, 583-583
590-590
: LGTM: Error cases properly handle value equivalence.
The error cases correctly maintain the r2.svalue=r2.uvalue
equivalence while properly validating type constraints and pointer dereferencing rules.
Also applies to: 597-597, 607-607, 615-615
Line range hint 7-615
: Verify test coverage for atomic operations.
The test cases cover a comprehensive range of atomic operations, but let's verify there are no gaps in the coverage.
✅ Verification successful
Test coverage for atomic operations is complete
The implementation supports atomic ADD, OR, AND, XOR, XCHG, and CMPXCHG operations, and the test cases cover:
- All operations for both 32-bit and 64-bit variants
- Both shared and stack memory regions
- Both regular and fetch variants where applicable
- Error cases for invalid memory access and type mismatches
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for any atomic operations in the codebase that might not be covered by tests
# Search for atomic operation implementations
rg -t cpp "atomic|lock.*\+=" --type-add "cpp:*.{cpp,h}"
# Search for atomic operation tests
rg -t yaml "atomic.*test-case" --type-add "yaml:*.yaml"
Length of output: 3748
Script:
#!/bin/bash
# Let's check the atomic operations test coverage more specifically
# First, get all atomic operation codes from the implementation
rg -B1 'str_to_atomicop' src/asm_parse.cpp
# Then check test coverage in atomic.yaml
cat test-data/atomic.yaml | grep "test-case.*atomic.*[A-Z]"
Length of output: 2149
test-data/unsigned.yaml (5)
569-569
: Consistent post-condition format for unsigned comparison test cases.
The post-conditions now consistently include r1.svalue=r1.uvalue
to explicitly state the relationship between signed and unsigned values.
Also applies to: 576-576, 583-583, 590-590, 615-615, 622-622, 629-629, 636-636, 657-657, 664-664, 671-671, 678-678
705-706
: Improved variable relation tracking in post-conditions.
The post-conditions now include explicit relations between variables (e.g., r2.svalue=r2.uvalue
) and maintain proper alignment in the YAML format.
Also applies to: 714-715, 751-752, 768-769
909-911
: Enhanced post-conditions for equivalence relations.
The post-conditions now properly track equivalence relations between variables using the transitive property (e.g., r1.svalue=r1.uvalue=r2.svalue=r2.uvalue
).
Also applies to: 919-921, 929-930, 938-939, 948-948, 957-957
965-967
: Improved inequality relation tracking.
The post-conditions now track both signed and unsigned inequalities between variables (e.g., r1.svalue-r2.svalue<=-1, r1.uvalue-r2.uvalue<=-1
).
Also applies to: 975-977, 987-987, 997-997, 1005-1007, 1015-1017, 1027-1027, 1037-1037
1045-1046
: Consistent handling of signed comparisons.
The post-conditions for signed comparisons now properly track the relationship between signed and unsigned values, maintaining consistency with the unsigned comparison cases.
Also applies to: 1128-1128, 1140-1140, 1152-1152, 1170-1170, 1176-1176, 1197-1197, 1203-1203
src/crab/split_dbm.cpp (2)
1155-1161
: Structured bindings require C++17 support.
The use of structured bindings in for (const auto [vs, least] : equivalence_classes)
requires C++17 or higher. Confirm that the project is compiled with the appropriate C++ standard.
Run the following script to check the project's C++ standard settings:
✅ Verification successful
C++20 standard is set, structured bindings are supported
The project is configured with C++20 standard in CMakeLists.txt, which fully supports structured bindings (introduced in C++17).
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify that the project is using C++17 or higher.
# Check the CMakeLists.txt or build scripts for C++ standard flags.
grep -r 'CXX_STANDARD' CMakeLists.txt build_scripts/
Length of output: 201
1175-1182
: Ensure consistency when simplifying constraints.
In the loop that simplifies constraints, the logic might miss cases where dual constraints are not correctly identified, leading to incorrect simplifications.
Run the following script to test constraint simplification logic:
✅ Verification successful
Constraint simplification logic is correctly implemented
The code properly handles dual constraints by:
- Creating the dual constraint with negated weight (
-w
) - Checking for its existence in the result set
- Replacing both constraints with a single equality constraint when duals are found
- Using an assertion to prevent zero-weight cases
The implementation follows the documented simplification pattern:
x - y <= k && y - x <= -k -> x = y + k
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for potential issues in constraint simplification.
# Extract all instances where constraints are added to the result.
grep -n 'result.insert' src/crab/split_dbm.cpp
# Manually verify that for each constraint, the dual is correctly identified and handled.
Length of output: 251
Script:
#!/bin/bash
# Let's examine the constraint handling logic more thoroughly
# First, let's see the to_string function implementation
ast-grep --pattern 'to_string($$$) {
$$$
}'
# Then, check the context around the constraint handling
rg -B 5 -A 5 'result.insert\(to_string\(vd, vs, w,'
Length of output: 758
Script:
#!/bin/bash
# Let's see the complete function context where this constraint handling occurs
rg -B 20 -A 10 'auto dual = to_string\(vs, vd, -w, false\);'
# Also check for any other dual constraint handling patterns
ast-grep --pattern 'if (result.contains($_)) {
$$$
result.erase($_);
$$$
}'
Length of output: 1773
@Alan-Jowett & @dthaler what do you think about the results - this one for example? Should this be behind a flag? |
I don't think this needs to be behind a flag. I think it should be fine as the default behavior. |
I'm ok either way. If I'm looking for a particular variable, it's easier to find when in alphabetical order instead of having to look for it somewhere other than at the beginning of a line. However, it's not a big deal either way. |
Maybe leave the equalities in the beginning of the line?
|
* print only one variable per equivalence class * update tests Signed-off-by: Elazar Gershuni <[email protected]>
This comment was marked as duplicate.
This comment was marked as duplicate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 16
🧹 Outside diff range comments (6)
test-data/movsx.yaml (2)
Line range hint
6-81
: Remove redundant pre-conditions.The pre-conditions contain redundant information. When
r1.uvalue=r1.svalue
is specified, explicitly setting both values is unnecessary.Example fix for the first test case:
-pre: ["r1.svalue=384", "r1.uvalue=384", "r1.type=number", "r1.uvalue=r1.svalue"] +pre: ["r1.svalue=384", "r1.type=number", "r1.uvalue=r1.svalue"]
Line range hint
178-250
: Add missing r2.uvalue equivalence in post-conditions.The post-conditions in full range test cases omit r2.uvalue equivalence, breaking the pattern established in earlier test cases.
Example fix for the first affected test case:
- r2.type=number - r2.svalue=[-128, 127] + - r2.uvalue=r2.svalue
test-data/pointer.yaml (1)
Line range hint
1-115
: Remove unnecessary post-conditions from arithmetic operation test casesThe verifier doesn't emit post-conditions for 32-bit pointer truncation cases, yet multiplication (lines 65-66), division (lines 90-91), and modulo (lines 115-116) test cases include them. Remove these post-conditions for consistency.
test-data/sdivmod.yaml (1)
Line range hint
154-168
: Add missing value equality constraint for r1The test case enforces value equality between signed and unsigned values for r2 but misses the same constraint for r1 in the pre-conditions.
pre: ["r1.type=number", "r1.svalue=6", "r1.uvalue=6", - "r2.type=number", "r2.svalue=[0, 5]", "r2.uvalue=[0, 5]", "r2.uvalue=r2.svalue"] + "r2.type=number", "r2.svalue=[0, 5]", "r2.uvalue=[0, 5]", "r2.uvalue=r2.svalue", + "r1.uvalue=r1.svalue"]test-data/callx.yaml (1)
Add pointer leak prevention assertions for bpf_get_stack with shared memory
The concern about pointer leakage into shared memory through bpf_get_stack is valid. The test cases need explicit post-conditions to verify:
- The type of data written to shared memory
- Bounds of the shared memory access
- Prevention of pointer value leakage
Required changes:
- Add
type=number
assertion for shared memory region in post-conditions- Add value range assertions to ensure no pointer values
- Include shared memory bounds check in post-conditions
🔗 Analysis chain
Line range hint
201-511
: Address the pointer leakage concern in shared memory test caseThe comment "doesn't this leak pointers into the shared memory?" raises a valid security concern that needs to be addressed. Consider adding explicit assertions in the post-conditions to verify that no pointer values are leaked.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for similar security measures in other test cases rg -B 5 -A 5 "leak.*pointer" test-data/ rg -B 5 -A 5 "shared.*memory.*post:" test-data/Length of output: 1050
Script:
#!/bin/bash # Search for shared memory test cases and their assertions ast-grep --pattern 'test-case: $_ shared $$$' # Search for pointer-related assertions in test cases rg -B 2 -A 2 '\.type=(ctx|stack|shared).*post:' test-data/ # Search for bpf_get_stack related test cases rg -B 5 -A 10 'bpf_get_stack' test-data/Length of output: 5675
test-data/atomic.yaml (1)
Line range hint
1-617
: Consider reorganizing test cases for better maintainability.The test file contains repetitive test cases that could be parameterized. Consider:
- Using YAML anchors and aliases for common patterns
- Grouping tests by operation type rather than memory type
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
📒 Files selected for processing (23)
src/crab/split_dbm.cpp
(4 hunks)src/crab/var_factory.cpp
(1 hunks)src/crab/variable.hpp
(1 hunks)test-data/add.yaml
(5 hunks)test-data/assign.yaml
(16 hunks)test-data/atomic.yaml
(22 hunks)test-data/call.yaml
(7 hunks)test-data/callx.yaml
(7 hunks)test-data/full64.yaml
(7 hunks)test-data/jump.yaml
(5 hunks)test-data/loop.yaml
(12 hunks)test-data/movsx.yaml
(17 hunks)test-data/packet.yaml
(7 hunks)test-data/pointer.yaml
(28 hunks)test-data/sdivmod.yaml
(9 hunks)test-data/sext.yaml
(4 hunks)test-data/shift.yaml
(46 hunks)test-data/stack.yaml
(6 hunks)test-data/subtract.yaml
(2 hunks)test-data/udivmod.yaml
(10 hunks)test-data/uninit.yaml
(7 hunks)test-data/unop.yaml
(6 hunks)test-data/unsigned.yaml
(42 hunks)
🧰 Additional context used
📓 Learnings (4)
test-data/loop.yaml (1)
Learnt from: Alan-Jowett
PR: vbpf/ebpf-verifier#745
File: test-data/loop.yaml:377-398
Timestamp: 2024-11-12T09:50:23.369Z
Learning: In `test-data/loop.yaml`, for the test case **"very large loop > 100K iterations"**, additional post conditions like `r0.svalue>0` and `r0.uvalue>0` are not required.
test-data/pointer.yaml (1)
Learnt from: Alan-Jowett
PR: vbpf/ebpf-verifier#742
File: test-data/pointer.yaml:1-357
Timestamp: 2024-11-12T09:50:16.890Z
Learning: In `test-data/pointer.yaml`, for the 32-bit pointer truncation test cases, the verifier doesn't emit post conditions, so adding post-conditions is not applicable.
test-data/uninit.yaml (3)
Learnt from: Alan-Jowett
PR: vbpf/ebpf-verifier#740
File: test-data/uninit.yaml:195-211
Timestamp: 2024-11-12T09:50:16.890Z
Learning: In `uninit.yaml` test cases, post-conditions are still needed even when the operation fails due to uninitialized registers.
Learnt from: Alan-Jowett
PR: vbpf/ebpf-verifier#740
File: test-data/uninit.yaml:249-265
Timestamp: 2024-11-12T09:50:23.368Z
Learning: The test cases in `uninit.yaml` should include post conditions even when the operation fails due to uninitialized registers.
Learnt from: Alan-Jowett
PR: vbpf/ebpf-verifier#740
File: test-data/uninit.yaml:39-55
Timestamp: 2024-11-12T09:50:16.890Z
Learning: In test cases, post conditions are still needed even if the operation is expected to fail due to an uninitialized register.
test-data/unsigned.yaml (1)
Learnt from: Alan-Jowett
PR: vbpf/ebpf-verifier#729
File: test-data/add.yaml:213-215
Timestamp: 2024-11-12T09:50:16.890Z
Learning: In the eBPF verifier test cases (e.g., in `test-data/add.yaml`), include both `svalue` (signed value) and `uvalue` (unsigned value) assertions in the `post` conditions, as the verifier always emits both signed and unsigned invariants.
🔇 Additional comments (52)
test-data/sext.yaml (4)
10-10
: Direction of value assignment reversed but logically equivalent
The change maintains the same relationship between registers while standardizing the direction of assignment.
Also applies to: 20-20
26-26
: Consistent with zext pattern for signed values
The standardization of assignment direction matches the zext case while preserving signed value semantics.
Also applies to: 36-36
59-59
: Assignment direction standardized for large signed values
The change maintains consistency with other test cases while preserving the full signed value range.
42-42
: Verify overflow handling for large unsigned values
The relationship between signed and unsigned values near 2^32 needs verification.
Also applies to: 51-53
✅ Verification successful
Overflow handling for large unsigned values is properly tested
The test cases demonstrate correct handling of large values around 2^32:
- Sign extension tests cover value ranges up to 4294967299
- Unsigned comparison tests verify behavior with values > 2^32
- Post-conditions correctly maintain value relationships between signed and unsigned representations
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for other test cases handling large unsigned values
rg -l "4294967" --type yaml test-data/
Length of output: 209
Script:
#!/bin/bash
# Check the specific test cases with large values around 2^32
rg "429496[0-9]+" -A 5 -B 5 test-data/sext.yaml test-data/unsigned.yaml
Length of output: 5474
src/crab/variable.hpp (2)
81-81
: Add documentation and [[nodiscard]] attribute.
The method is used for determining printing order of variables in equivalence classes. Add documentation and prevent accidental misuse.
81-81
: Verify consistent implementation across translation units.
The declaration looks good, but let's verify the implementation.
✅ Verification successful
Implementation verified: lexicographical comparison of variable names
The implementation in src/crab/var_factory.cpp
matches the declaration and uses lexicographical comparison of variable names via a.name() < b.name()
.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check the implementation of printing_order in var_factory.cpp
# Expect: Implementation should use lexicographical comparison of variable names
# Search for the implementation
ast-grep --pattern 'bool variable_t::printing_order(const variable_t& $_, const variable_t& $_) {
$$$
}'
Length of output: 108
Script:
#!/bin/bash
# Try a broader search for printing_order implementation
rg -U "printing_order.*\{[\s\S]*?\}" --type cpp -A 5
# Also search for the definition in other potential files
fd "variable" -e cpp -e hpp --exec rg -l "printing_order"
Length of output: 563
test-data/add.yaml (2)
28-28
: Consistent pattern of equating uvalue with svalue across test cases
The changes establish equivalence between uvalue and svalue, which aligns with the PR objective of grouping variables into equivalence classes. This simplification makes the output more concise while preserving the necessary invariants.
Also applies to: 92-92, 110-110, 128-128, 149-149
110-112
: Verify the relationship between packet_offset and svalue
The constraints between packet_offset and svalue need verification to ensure they maintain correctness after the equivalence changes.
Also applies to: 133-133
✅ Verification successful
No verification needed - constraints are correct
The constraints between packet_offset and svalue in lines 110-112 of test-data/add.yaml are correct and consistent with the codebase. The test cases show that:
- When adding numbers to packet pointers, the packet_offset and svalue maintain proper relationships:
- packet_offset is always less than or equal to svalue by at least 7 units
- svalue is always less than or equal to packet_offset by at most 11 units
These constraints ensure proper bounds checking and pointer arithmetic safety.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for other test cases that establish relationships between packet_offset and svalue
rg -l 'packet_offset.*svalue|svalue.*packet_offset' 'test-data/*.yaml'
Length of output: 129
Script:
#!/bin/bash
# First, let's find the YAML files in the test-data directory
fd -e yaml -e yml
# Then search for relationships between packet_offset and svalue
rg -A 3 'packet_offset|svalue'
Length of output: 363734
Script:
#!/bin/bash
# Search for relationships between packet_offset and svalue in test-data/add.yaml
cat test-data/add.yaml
Length of output: 3317
test-data/subtract.yaml (2)
153-153
: Verify the equivalence of numeric ranges.
The change aligns with the pattern of referencing svalue directly, reducing output complexity.
✅ Verification successful
Pattern uvalue=svalue
is consistently used across test cases
The search results confirm that setting uvalue=svalue
is a standard pattern used throughout the test data files, appearing in various contexts including numeric ranges, shared memory, and stack operations. This change maintains consistency with the established pattern.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Check for similar patterns in other test cases
rg "uvalue=.*svalue" test-data/
Length of output: 37537
28-28
: Verify the equivalence of svalue and uvalue ranges.
The change to reference r0.svalue directly reduces redundancy while maintaining correctness.
✅ Verification successful
Setting uvalue to svalue is correct and consistent with the codebase pattern
The change aligns with the established pattern across test files where uvalue is set equal to svalue when they represent the same range. The codebase shows numerous examples of uvalue=r0.svalue
being used, particularly in test cases involving numeric ranges.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Verify consistent pattern across test files
rg -A 1 "svalue=\[.*\].*\n.*uvalue=" test-data/
Length of output: 241
Script:
#!/bin/bash
# Search for svalue and uvalue patterns in test files
rg -U "svalue=.*\n.*uvalue=" test-data/
# Get the specific context around line 28 in subtract.yaml
rg -A 2 -B 2 "r0\.svalue" test-data/subtract.yaml
Length of output: 91152
test-data/full64.yaml (4)
100-100
: LGTM!
The constraint ensures value consistency after casting unsigned to signed.
116-116
: LGTM!
The pre and post conditions correctly maintain value equivalence when testing equals 0.
Also applies to: 125-125
150-150
: LGTM!
The constraint correctly maintains value equivalence for the signed infinite interval.
197-197
: LGTM!
The pre and post conditions correctly establish and maintain value equivalence between r1 and r2.
Also applies to: 201-201, 204-206
test-data/movsx.yaml (2)
Line range hint 99-143
: LGTM! Consistent handling of range values.
The changes correctly maintain value equivalence in post-conditions while preserving proper sign extension behavior for ranges.
Line range hint 147-159
: LGTM! Proper handling of wrap cases.
The changes correctly represent wrapping behavior with full range values while maintaining value equivalence.
test-data/packet.yaml (3)
89-90
: LGTM
The post-conditions correctly specify r3's value ranges after the offset addition.
92-92
: LGTM
The constraints accurately capture the relationship between packet_offset and the original value.
116-116
: LGTM
The post-conditions correctly reflect the 8-byte offset addition.
test-data/loop.yaml (3)
366-369
: LGTM
Post-conditions correctly capture the loop termination state where r0 must be 0.
392-394
: LGTM
Post-conditions accurately reflect the final state after executing the non-loop backwards jump.
39-42
: 🧹 Nitpick (assertive)
Simplify redundant assertions
r0.uvalue=pc[1]
and r0.svalue=pc[1]
can be combined since they establish the same value through pc[1].
- r0.uvalue=pc[1]
- r0.svalue=pc[1]
+ r0.uvalue=r0.svalue
+ r0.svalue=4
r0.type=number
pc[1]=4
⛔ Skipped due to learnings
Learnt from: Alan-Jowett
PR: vbpf/ebpf-verifier#745
File: test-data/loop.yaml:377-398
Timestamp: 2024-11-12T09:50:23.369Z
Learning: In `test-data/loop.yaml`, for the test case **"very large loop > 100K iterations"**, additional post conditions like `r0.svalue>0` and `r0.uvalue>0` are not required.
test-data/unop.yaml (2)
118-118
: LGTM: Consistent constraint additions
The added equality constraints r1.uvalue=r1.svalue
are consistent across all range test cases and make sense for the small positive number ranges being tested.
Also applies to: 130-130, 214-214, 226-226, 310-310, 322-322
226-226
:
Fix incorrect endianness option
The big-endian test case incorrectly uses !big_endian
option.
-options: ["!big_endian"]
+options: ["big_endian"]
Likely invalid or redundant comment.
test-data/assign.yaml (1)
101-102
: Packet value propagation needs bounds validation
Stack assignments involving packet values should validate packet bounds.
Also applies to: 134-135
test-data/pointer.yaml (3)
Line range hint 351-405
: Changes maintain type safety while simplifying output
The modifications to return context pointer test cases correctly preserve type information while aligning with the PR's objective of simplifying invariant output.
Line range hint 341-347
: Verify bounds checking messages for NOT operation
The NOT operation uniquely includes bounds checking messages that are critical for pointer access validation. Ensure these messages are consistently applied where similar bounds checking is needed.
✅ Verification successful
Bounds checking messages are consistently implemented across test cases
The bounds checking messages for valid_access are already properly implemented across different test cases:
- Packet size bounds in packet.yaml and jump.yaml
- Stack access validation in call.yaml and callx.yaml
- Numeric bounds (0-64) in pointer.yaml
- Width-specific checks across all test cases
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for other test cases that should include bounds checking messages
rg -l "valid_access.*width.*read" test-data/
Length of output: 172
Script:
#!/bin/bash
# Check the actual usage of valid_access with bounds checking messages in these files
rg "valid_access.*width.*read" -A 2 -B 2 test-data/
Length of output: 5519
152-154
: 🧹 Nitpick (assertive)
Remove redundant uvalue assignment
The uvalue is already set from svalue in line 128, making this assignment redundant.
- "r1.svalue=[0, 4294967295]"
- - "r1.uvalue=r1.svalue"
- "r1.type=ctx"
- "r1.uvalue=[0, 4294967295]"
Likely invalid or redundant comment.
test-data/uninit.yaml (2)
70-70
: Consistent value propagation in arithmetic operations
The assignment of unsigned values from signed values in division and modulo operations maintains type consistency.
Also applies to: 109-109, 129-129
510-519
: Complete property propagation in stack operations
The changes ensure comprehensive property copying from register to stack ranges, covering all necessary attributes for both aligned and unaligned access.
Verify the completeness of property propagation:
Also applies to: 537-546, 563-572
✅ Verification successful
Property propagation is consistent across all stack ranges
The verification confirms that all properties from register r0 are consistently copied to each stack range [496...503], [502...509], and [504...511]. Each range receives the complete set of properties:
- ctx_offset, map_fd, packet_offset
- shared_offset, shared_region_size
- stack_numeric_size, stack_offset
- svalue, type, uvalue
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Check if all register properties are consistently propagated to stack
rg -A 1 "r0\." test-data/uninit.yaml | grep -v "post:" | sort -u
Length of output: 1945
test-data/call.yaml (1)
19-19
: Verify the equivalence relationship between signed and unsigned values
The changes establish equivalence between r0.uvalue
and r0.svalue
across all bpf_map_lookup_elem
test cases. This aligns with the PR objective of grouping variables into equivalence classes.
Run the following script to verify this pattern is consistent across all test files:
Also applies to: 36-36, 53-53, 71-71, 91-91, 110-110, 129-129
✅ Verification successful
The equivalence relationship between signed and unsigned values is consistently maintained
The codebase shows that r0.uvalue=r0.svalue
and similar equivalences are consistently established across test cases, particularly in:
- Stack operations (test-data/stack.yaml)
- Unsigned operations (test-data/unsigned.yaml)
- Atomic operations (test-data/atomic.yaml)
- Arithmetic operations (test-data/add.yaml, test-data/subtract.yaml)
- Bitwise operations (test-data/bitop.yaml)
The pattern of establishing equivalence between signed and unsigned values is a fundamental invariant maintained throughout the test suite.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check if the equivalence relationship is consistently applied
# across all test files and if there are any exceptions to this pattern.
# Search for test cases where svalue and uvalue might have different values
rg -A 5 'svalue.*uvalue' test-data/
# Search for any remaining cases where they might be set independently
rg '(\.svalue=.*\.uvalue)|(\.uvalue=.*\.svalue)' test-data/
Length of output: 291669
test-data/sdivmod.yaml (1)
Line range hint 1-582
: Verify test coverage for edge cases
The test suite covers division and modulo operations extensively but might be missing some edge cases.
✅ Verification successful
Test coverage for division and modulo operations is comprehensive
The test suite thoroughly covers edge cases for division and modulo operations:
- Integer division by zero (both immediate and register)
- Signed division with maximum/minimum values (INT64_MIN, INT64_MAX)
- Division with undefined values and ranges
- Modulo operations with positive/negative ranges
- Division/modulo with zero and non-zero operands
- Cases with
allow_division_by_zero
option
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for potential missing test cases by analyzing the test patterns
# Look for other division/modulo test files
fd -e yaml -x grep -l "s/=" {} \;
# Check for test cases with maximum/minimum values
rg "svalue=\[.*9223372036854775807.*\]|svalue=\[.*-9223372036854775808.*\]" -A 10
Length of output: 21032
test-data/udivmod.yaml (1)
124-124
: Consistent equivalence between signed and unsigned values
The pattern of setting uvalue=svalue
across test cases with ranges simplifies the invariant output while maintaining correctness.
Also applies to: 166-166, 209-209, 350-350, 392-392, 435-435, 473-473, 585-585
test-data/callx.yaml (2)
Line range hint 131-200
: LGTM! Good error case coverage
The test cases thoroughly cover invalid helper function scenarios with clear error messages.
20-20
: Verify the impact of reversing value assignments on equivalence classes
The consistent change of r0.uvalue=r0.svalue
across all map lookup test cases aligns with grouping variables into equivalence classes. However, this reversal might affect how values are propagated in the verifier.
Also applies to: 41-41, 62-62, 84-84, 107-107, 130-130
✅ Verification successful
Assignment direction change is consistent with equivalence class design
The change from svalue=uvalue
to uvalue=svalue
is part of a systematic update across test cases. The pattern shows that:
- All test cases maintain value consistency between signed and unsigned representations
- The change appears in map operations, register assignments, and various data types (stack, packet, shared memory)
- Values are properly propagated in both directions through equivalence classes
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for other test cases that might be affected by this change
rg -l "\.svalue=.*\.uvalue" test-data/
rg -l "\.uvalue=.*\.svalue" test-data/
Length of output: 944
Script:
#!/bin/bash
# Let's examine the actual content of these assignments to understand the pattern
rg "\.svalue=.*\.uvalue|\.uvalue=.*\.svalue" test-data/callx.yaml -A 2 -B 2
Length of output: 6265
test-data/stack.yaml (3)
395-396
: 🛠️ Refactor suggestion
Add alignment constraints for 64-bit values
64-bit values require proper alignment in stack memory.
- s[508...511].svalue=r1.svalue
- s[508...511].uvalue=r1.uvalue
+ - s[508...511].alignment=8
470-473
: 🧹 Nitpick (assertive)
Ensure pointer value consistency
The stack pointer value assignments should maintain consistent offset relationships.
- r3.svalue=r2.svalue
- r3.uvalue=r2.uvalue
- s[496...503].uvalue=r2.uvalue
- s[496...503].svalue=r2.svalue
+ - r3.stack_offset=r2.stack_offset
+ - s[496...503].stack_offset=r2.stack_offset
333-334
: 🧹 Nitpick (assertive)
Add bounds check for value assignments
The value assignments should include bounds validation to ensure the values stay within the valid range for the stack segment.
- s[504...511].svalue=r1.svalue
- s[504...511].uvalue=r1.uvalue
+ - s[504...511].svalue=[r1.svalue, r1.svalue]
+ - s[504...511].uvalue=[r1.uvalue, r1.uvalue]
test-data/jump.yaml (5)
37-38
: Improved post-condition clarity
The changes make the value relationships more explicit by directly assigning values rather than using implicit relationships.
302-302
: Enhanced type relationship clarity
The change r2.type=r1.type
makes the type relationship between variables more explicit and easier to understand.
485-485
: Consistent type relationship pattern
The change follows the same pattern of explicit type relationships seen elsewhere in the file.
412-416
: Added explicit value relationships
New post-conditions clarify the relationships between signed and unsigned values, making the test case more comprehensive.
526-526
: Simplified post-conditions
The changes streamline the post-conditions by using direct value assignments, making the test case easier to understand.
Also applies to: 535-535
test-data/atomic.yaml (1)
7-7
: LGTM! Consistent relationship between signed and unsigned values.
The change standardizes the relationship between svalue
and uvalue
across all test cases, making uvalue
derive from svalue
. This aligns with the PR objective of simplifying invariant output.
Also applies to: 14-14, 19-19, 26-26, 31-31, 38-38, 43-43, 50-50, 55-55, 62-62, 67-67, 74-74, 79-79, 86-86, 91-91, 98-98, 103-103, 110-110, 115-115, 122-122, 127-127, 134-134, 139-139, 146-146, 151-151, 158-158, 163-163, 170-170, 175-175, 182-182, 187-187, 194-194, 199-199, 206-206, 211-211, 218-218, 224-224, 232-232, 238-238, 246-246, 251-251, 258-258, 266-266, 275-275, 282-282, 291-291, 298-298, 307-307, 314-314, 323-323, 330-330, 339-339, 346-346, 355-355, 362-362, 371-371, 378-378, 387-387, 394-394, 403-403, 410-410, 419-419, 426-426, 435-435, 442-442, 451-451, 458-458, 467-467, 474-474, 483-483, 490-490, 499-499, 506-506, 515-515, 522-522, 531-531, 538-538, 547-547, 555-555, 565-565, 573-573, 583-583, 590-590, 597-597, 607-607, 615-615
test-data/shift.yaml (3)
Line range hint 230-239
: LGTM: Establishing value equivalence for right shift operations.
The addition of r1.uvalue=r1.svalue
correctly establishes the equivalence relationship between signed and unsigned values, which is essential for validating right shift operations.
Line range hint 243-252
: LGTM: Consistent application of value equivalence across test cases.
The equivalence relationship between signed and unsigned values is consistently established across all test cases, covering various shift operations, bit widths, and edge cases.
Also applies to: 256-266, 273-283, 290-299, 303-312, 316-326, 333-343, 350-359, 363-372, 376-386, 393-403, 416-419, 429-432, 443-446, 460-463, 476-479, 489-492, 503-506, 520-523, 642-651, 655-665, 672-682, 684-694, 706-709, 720-723, 730-739, 743-753, 760-769, 773-783, 822-825, 836-839, 846-855, 859-869, 876-885, 889-899, 912-915, 926-929, 942-945, 956-959, 967-977, 982-992, 997-1007, 1017-1020, 1042-1045
Line range hint 230-1045
: Verify test coverage for all shift operations.
The changes establish value equivalence across all shift operation test cases. Run the following to verify no cases were missed:
✅ Verification successful
All shift operation test cases have proper value equivalence relationships
The verification shows that all shift operation test cases in test-data/shift.yaml
maintain the required uvalue=svalue
relationship in both pre-conditions and post-conditions. The output confirms no cases were missed.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify all shift operation test cases have the equivalence relationship
# Test: Search for test cases without the equivalence relationship
rg -l 'test-case:.*shift' | xargs rg -L 'uvalue=.*svalue'
Length of output: 5246
test-data/unsigned.yaml (3)
909-911
: Ensure post conditions maintain value consistency.
The updated post conditions correctly maintain the relationship between signed and unsigned values after comparisons. The changes enforce that:
- Value equivalence is preserved when ranges are non-negative
- Relationships between values are maintained after comparisons
Also applies to: 919-921, 929-930, 938-939, 965-967, 975-977, 1005-1007, 1015-1017
1045-1046
: Verify the correctness of value range updates.
The changes correctly update value ranges after comparison operations, maintaining consistency between signed and unsigned representations. The modifications ensure that:
- Range narrowing preserves the relationship between signed and unsigned values
- Post conditions accurately reflect the new ranges after comparisons
Also applies to: 1107-1107, 1116-1116, 1125-1125, 1128-1128, 1140-1140, 1149-1149, 1152-1152, 1167-1167, 1170-1170, 1176-1176, 1185-1185, 1194-1194, 1197-1197, 1200-1200, 1203-1203
✅ Verification successful
Value range updates are correctly implemented
The verification confirms that:
- Signed range [-1, 1] correctly propagates between r1 and r2
- Unsigned value (uvalue) is consistently synchronized with signed value (svalue)
- Range relationships are preserved in test cases covering both signed and unsigned bounds
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify that range updates maintain valid relationships
# Look for any inconsistencies in range updates
rg -A 5 'svalue=\[\d+,.*\].*uvalue=\[\d+,.*\]' test-data/unsigned.yaml | rg 'post:'
Length of output: 3014
Script:
#!/bin/bash
# Let's check the specific lines mentioned in the review comment
rg -A 5 'post:.*"r1\.svalue=\[-1, 1\]".*"r2\.uvalue=r1\.uvalue"' test-data/unsigned.yaml
# Also check for any cases where r2 values are set based on r1
rg -A 5 'post:.*"r2\.(s|u)value=r1\.(s|u)value"' test-data/unsigned.yaml
Length of output: 1369
101-101
: Verify the consistency of value equivalence assertions.
The added r1.uvalue=r1.svalue
and r2.uvalue=r2.svalue
assertions ensure that unsigned and signed values are equivalent for non-negative ranges. This is correct for the given ranges but could be problematic if extended to negative values.
Also applies to: 109-109, 117-117, 125-125, 182-182, 191-191, 200-200, 209-209, 218-218, 227-227, 236-236, 245-245, 254-254, 263-263, 272-272, 281-281, 289-290, 298-299
✅ Verification successful
Let me search for any other instances where uvalue=svalue
is used, particularly in test cases with negative values.
The uvalue=svalue
assertions are correctly used
The test cases maintain proper separation between signed and unsigned values:
- When
svalue
is non-negative (e.g.,[0, 1]
,[1, 2]
),uvalue=svalue
is used correctly - When
svalue
is negative (e.g.,[-1]
,[-2, -1]
), the test cases explicitly set different values foruvalue
(e.g.,18446744073709551615
) without the equality assertion
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify that uvalue=svalue assertions are only used with non-negative ranges
# Look for any test cases where uvalue=svalue is used with negative ranges
rg -A 5 'svalue=\[-\d+' test-data/unsigned.yaml | rg 'uvalue=.*svalue'
Length of output: 1468
Script:
#!/bin/bash
# Get all test cases with uvalue=svalue assertion
rg 'uvalue=.*svalue' test-data/unsigned.yaml -B 2 | rg 'svalue='
Length of output: 10947
src/crab/split_dbm.cpp (2)
1133-1151
: Correct implementation of equivalence class extraction.
The code accurately constructs equivalence classes by identifying variables connected via zero-weight edges, which effectively groups variables that are considered equal.
1170-1179
: Simplification of difference constraints is correctly handled.
The logic simplifies constraints by converting pairs of opposing inequalities into equalities when appropriate, which optimizes the output representation.
Group variables in equivalence classes, and print details only about one of them.
Summary by CodeRabbit
Release Notes
New Features
SplitDBM
class.variable_t
class.Bug Fixes
svalue
anduvalue
.Documentation
Tests