From c1f238c463d40fea86a48638e898bb06277c2431 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Wed, 19 Apr 2023 22:14:17 +0200 Subject: [PATCH] [Eva] Adds a test of splits according to the returning value of a call. --- .../oracle/partitioning-annots.0.res.oracle | 74 +++++++++++++++++-- .../oracle/partitioning-annots.3.res.oracle | 8 +- .../oracle/partitioning-annots.4.res.oracle | 8 +- .../partitioning-annots.0.res.oracle | 14 +++- .../partitioning-annots.3.res.oracle | 2 +- .../partitioning-annots.0.res.oracle | 2 +- tests/value/partitioning-annots.c | 56 ++++++++++++++ 7 files changed, 146 insertions(+), 18 deletions(-) diff --git a/tests/value/oracle/partitioning-annots.0.res.oracle b/tests/value/oracle/partitioning-annots.0.res.oracle index ef583a47f12..aa52873360d 100644 --- a/tests/value/oracle/partitioning-annots.0.res.oracle +++ b/tests/value/oracle/partitioning-annots.0.res.oracle @@ -6,13 +6,13 @@ nondet ∈ [--..--] k ∈ {0} [eva] computing for function test_slevel <- main. - Called from partitioning-annots.c:223. -[eva] partitioning-annots.c:188: starting to merge loop iterations -[eva] partitioning-annots.c:193: starting to merge loop iterations + Called from partitioning-annots.c:278. +[eva] partitioning-annots.c:243: starting to merge loop iterations +[eva] partitioning-annots.c:248: starting to merge loop iterations [eva] Recording results for test_slevel [eva] Done for function test_slevel [eva] computing for function test_unroll <- main. - Called from partitioning-annots.c:224. + Called from partitioning-annots.c:279. [eva:loop-unroll:partial] partitioning-annots.c:26: loop not completely unrolled [eva] partitioning-annots.c:26: starting to merge loop iterations [eva:loop-unroll:partial] partitioning-annots.c:34: loop not completely unrolled @@ -25,7 +25,7 @@ [eva] Recording results for test_unroll [eva] Done for function test_unroll [eva] computing for function test_split <- main. - Called from partitioning-annots.c:225. + Called from partitioning-annots.c:280. [eva] computing for function Frama_C_interval <- test_split <- main. Called from partitioning-annots.c:73. [eva] using specification for function Frama_C_interval @@ -65,7 +65,7 @@ [eva] Recording results for test_split [eva] Done for function test_split [eva] computing for function test_dynamic_split <- main. - Called from partitioning-annots.c:226. + Called from partitioning-annots.c:281. [eva] partitioning-annots.c:95: Warning: this partitioning parameter cannot be evaluated safely on all states [eva] computing for function Frama_C_interval <- test_dynamic_split <- main. @@ -90,13 +90,44 @@ [eva] Recording results for test_dynamic_split [eva] Done for function test_dynamic_split [eva] computing for function test_dynamic_split_predicate <- main. - Called from partitioning-annots.c:227. + Called from partitioning-annots.c:282. [eva] partitioning-annots.c:124: starting to merge loop iterations [eva] Recording results for test_dynamic_split_predicate [eva] Done for function test_dynamic_split_predicate +[eva] computing for function test_splits_post_call <- main. + Called from partitioning-annots.c:283. +[eva] computing for function Frama_C_interval <- test_splits_post_call <- main. + Called from partitioning-annots.c:205. +[eva] partitioning-annots.c:205: + function Frama_C_interval: precondition 'order' got status valid. +[eva] Done for function Frama_C_interval +[eva] computing for function spec <- test_splits_post_call <- main. + Called from partitioning-annots.c:206. +[eva] using specification for function spec +[eva] Done for function spec +[eva] partitioning-annots.c:211: Frama_C_show_each_spec: [-2147483648..-10], ⊥ +[eva] partitioning-annots.c:211: Frama_C_show_each_spec: [10..2147483647], ⊥ +[eva] partitioning-annots.c:211: Frama_C_show_each_spec: {-1}, [-1000..1000] +[eva] computing for function body <- test_splits_post_call <- main. + Called from partitioning-annots.c:212. +[eva] Recording results for body +[eva] Done for function body +[eva] partitioning-annots.c:212: Reusing old results for call to body +[eva] partitioning-annots.c:212: Reusing old results for call to body +[eva] partitioning-annots.c:217: Frama_C_show_each_body: [-510..-10], ⊥ +[eva] partitioning-annots.c:217: Frama_C_show_each_body: [10..510], ⊥ +[eva] partitioning-annots.c:217: Frama_C_show_each_body: {-1}, [-1000..1000] +[eva] Recording results for test_splits_post_call +[eva] Done for function test_splits_post_call [eva] Recording results for main [eva] done for function main [eva] ====== VALUES COMPUTED ====== +[eva:final-states] Values at end of function body: + i2 ∈ [-500..500] + absolute ∈ [0..500] + state ∈ {-1; 0; 1} + y ∈ [-1000..1000] or UNINITIALIZED + __retres ∈ [-510..510] [eva:final-states] Values at end of function test_dynamic_split: Frama_C_entropy_source ∈ [--..--] a ∈ {0} @@ -117,6 +148,13 @@ k ∈ {0; 1} i ∈ {0; 1} j ∈ {0; 1; 2} +[eva:final-states] Values at end of function test_splits_post_call: + Frama_C_entropy_source ∈ [--..--] + x ∈ [-1000..1000] or UNINITIALIZED + y ∈ [-1000..1000] or UNINITIALIZED + error ∈ [-1000..1000] or UNINITIALIZED + i ∈ [-1000..1000] + r ∈ [-510..510] [eva:final-states] Values at end of function test_unroll: a[0..9] ∈ {42} b[0..9] ∈ {42} @@ -145,6 +183,8 @@ [eva:final-states] Values at end of function main: Frama_C_entropy_source ∈ [--..--] k ∈ {0; 1} +[from] Computing for function body +[from] Done for function body [from] Computing for function test_dynamic_split [from] Computing for function Frama_C_interval <-test_dynamic_split [from] Done for function Frama_C_interval @@ -155,6 +195,10 @@ [from] Done for function test_slevel [from] Computing for function test_split [from] Done for function test_split +[from] Computing for function test_splits_post_call +[from] Computing for function spec <-test_splits_post_call +[from] Done for function spec +[from] Done for function test_splits_post_call [from] Computing for function test_unroll [from] Done for function test_unroll [from] Computing for function main @@ -164,6 +208,12 @@ [from] Function Frama_C_interval: Frama_C_entropy_source FROM Frama_C_entropy_source (and SELF) \result FROM Frama_C_entropy_source; min; max +[from] Function body: + y FROM nondet; i; p (and SELF) + \result FROM nondet; i +[from] Function spec: + x FROM i + \result FROM i [from] Function test_dynamic_split: Frama_C_entropy_source FROM Frama_C_entropy_source; nondet (and SELF) [from] Function test_dynamic_split_predicate: @@ -173,12 +223,18 @@ [from] Function test_split: Frama_C_entropy_source FROM Frama_C_entropy_source (and SELF) k FROM Frama_C_entropy_source +[from] Function test_splits_post_call: + Frama_C_entropy_source FROM Frama_C_entropy_source (and SELF) [from] Function test_unroll: NO EFFECTS [from] Function main: Frama_C_entropy_source FROM Frama_C_entropy_source; nondet (and SELF) k FROM Frama_C_entropy_source [from] ====== END OF DEPENDENCIES ====== +[inout] Out (internal) for function body: + i2; absolute; tmp; state; y; __retres +[inout] Inputs for function body: + nondet [inout] Out (internal) for function test_dynamic_split: Frama_C_entropy_source; a; b [inout] Inputs for function test_dynamic_split: @@ -195,6 +251,10 @@ Frama_C_entropy_source; k; i; j [inout] Inputs for function test_split: Frama_C_entropy_source; k +[inout] Out (internal) for function test_splits_post_call: + Frama_C_entropy_source; x; y; error; i; r +[inout] Inputs for function test_splits_post_call: + Frama_C_entropy_source; nondet [inout] Out (internal) for function test_unroll: a[0..9]; b[0..9]; c[0..19]; d[0..19]; e[0..9]; i; j; i_0; j_0; i_1; i_2; i_3; j_1 diff --git a/tests/value/oracle/partitioning-annots.3.res.oracle b/tests/value/oracle/partitioning-annots.3.res.oracle index 3fe49f8ff92..365ff709693 100644 --- a/tests/value/oracle/partitioning-annots.3.res.oracle +++ b/tests/value/oracle/partitioning-annots.3.res.oracle @@ -6,13 +6,13 @@ nondet ∈ [--..--] k ∈ {0} [eva] computing for function Frama_C_interval <- test_history. - Called from partitioning-annots.c:167. + Called from partitioning-annots.c:222. [eva] using specification for function Frama_C_interval -[eva] partitioning-annots.c:167: +[eva] partitioning-annots.c:222: function Frama_C_interval: precondition 'order' got status valid. [eva] Done for function Frama_C_interval -[eva] partitioning-annots.c:173: Frama_C_show_each: {0; 1}, {0; 1} -[eva:alarm] partitioning-annots.c:176: Warning: +[eva] partitioning-annots.c:228: Frama_C_show_each: {0; 1}, {0; 1} +[eva:alarm] partitioning-annots.c:231: Warning: division by zero. assert j ≢ 0; [eva] Recording results for test_history [eva] done for function test_history diff --git a/tests/value/oracle/partitioning-annots.4.res.oracle b/tests/value/oracle/partitioning-annots.4.res.oracle index 793324f2603..8ad2cdfc8af 100644 --- a/tests/value/oracle/partitioning-annots.4.res.oracle +++ b/tests/value/oracle/partitioning-annots.4.res.oracle @@ -6,13 +6,13 @@ nondet ∈ [--..--] k ∈ {0} [eva] computing for function Frama_C_interval <- test_history. - Called from partitioning-annots.c:167. + Called from partitioning-annots.c:222. [eva] using specification for function Frama_C_interval -[eva] partitioning-annots.c:167: +[eva] partitioning-annots.c:222: function Frama_C_interval: precondition 'order' got status valid. [eva] Done for function Frama_C_interval -[eva] partitioning-annots.c:173: Frama_C_show_each: {0}, {0} -[eva] partitioning-annots.c:173: Frama_C_show_each: {1}, {1} +[eva] partitioning-annots.c:228: Frama_C_show_each: {0}, {0} +[eva] partitioning-annots.c:228: Frama_C_show_each: {1}, {1} [eva] Recording results for test_history [eva] done for function test_history [eva] ====== VALUES COMPUTED ====== diff --git a/tests/value/oracle_apron/partitioning-annots.0.res.oracle b/tests/value/oracle_apron/partitioning-annots.0.res.oracle index 94ed9ffca14..68d268103b8 100644 --- a/tests/value/oracle_apron/partitioning-annots.0.res.oracle +++ b/tests/value/oracle_apron/partitioning-annots.0.res.oracle @@ -1,4 +1,16 @@ -105,106c105,106 +115,116c115,122 +< [eva] partitioning-annots.c:212: Reusing old results for call to body +< [eva] partitioning-annots.c:212: Reusing old results for call to body +--- +> [eva] computing for function body <- test_splits_post_call <- main. +> Called from partitioning-annots.c:212. +> [eva] Recording results for body +> [eva] Done for function body +> [eva] computing for function body <- test_splits_post_call <- main. +> Called from partitioning-annots.c:212. +> [eva] Recording results for body +> [eva] Done for function body +136,137c142,143 < x ∈ [0..44] < y ∈ [0..44] --- diff --git a/tests/value/oracle_apron/partitioning-annots.3.res.oracle b/tests/value/oracle_apron/partitioning-annots.3.res.oracle index d04cebfc945..5a8823d8cc9 100644 --- a/tests/value/oracle_apron/partitioning-annots.3.res.oracle +++ b/tests/value/oracle_apron/partitioning-annots.3.res.oracle @@ -1,3 +1,3 @@ 15,16d14 -< [eva:alarm] partitioning-annots.c:176: Warning: +< [eva:alarm] partitioning-annots.c:231: Warning: < division by zero. assert j ≢ 0; diff --git a/tests/value/oracle_octagon/partitioning-annots.0.res.oracle b/tests/value/oracle_octagon/partitioning-annots.0.res.oracle index cd64a1b908f..141d3a1f322 100644 --- a/tests/value/oracle_octagon/partitioning-annots.0.res.oracle +++ b/tests/value/oracle_octagon/partitioning-annots.0.res.oracle @@ -1,4 +1,4 @@ -105,106c105,106 +136,137c136,137 < x ∈ [0..44] < y ∈ [0..44] --- diff --git a/tests/value/partitioning-annots.c b/tests/value/partitioning-annots.c index d3ab58aaa50..393b1fe4bbd 100644 --- a/tests/value/partitioning-annots.c +++ b/tests/value/partitioning-annots.c @@ -162,6 +162,61 @@ void test_loop_split() } } +/*@ + assigns \result, *p \from i; + behavior error: + assumes nondet == 0; + assigns \result, *p \from i; + ensures \result == -1; + ensures \initialized(p) && *p == \old(i); + behavior positive: + assumes nondet > 0; + assigns \result \from i; + ensures \result >= 10; + behavior negative: + assumes nondet < 0; + assigns \result \from i; + ensures \result <= -10; + disjoint behaviors; + complete behaviors; +*/ +int spec(int i, int* p); + +int body(int i, int *p) { + int i2 = i / 2; + int absolute = i2 < 0 ? -i2 : i2; + int state = nondet % 2; + //@ split state; + if (state < 0) + return - 10 - absolute; + if (state > 0) + return 10 + absolute; + *p = i; + return -1; +} + +/* Tests the application of multiple splits according to the return value of a + call, to keep in the caller some state partitioning from the callee. + The splits must be defined after the call, so the state partitioning from the + callee must be kept until all splits are performed. + Tests this whether the function body or a specification is used. */ +void test_splits_post_call (void) { + int x, y, error; + int i = Frama_C_interval(-1000, 1000); + int r = spec(i, &x); + //@ split r < -1; + //@ split r > -1; + if (r == -1) + error = x; // There should be no alarm. + Frama_C_show_each_spec(r, x); // There should be three states. + r = body(i, &y); + //@ split r < -1; + //@ split r > -1; + if (r == -1) + error = y; // There should be no alarm. + Frama_C_show_each_body(r, y); // There should be three states. +} + void test_history() { int i = Frama_C_interval(0,1); @@ -225,4 +280,5 @@ void main(void) test_split(); test_dynamic_split(); test_dynamic_split_predicate(); + test_splits_post_call(); } -- GitLab