From 8a310a69eaa5ce2b48357428a0da44224ad3cbc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Fri, 2 Aug 2024 16:42:25 +0200 Subject: [PATCH] [Eva] Adds a test for the evaluation of "calls" annotations. --- tests/value/calls_annotation.i | 101 +++++++++ .../value/oracle/calls_annotation.res.oracle | 209 ++++++++++++++++++ .../oracle_apron/calls_annotation.res.oracle | 81 +++++++ 3 files changed, 391 insertions(+) create mode 100644 tests/value/calls_annotation.i create mode 100644 tests/value/oracle/calls_annotation.res.oracle create mode 100644 tests/value/oracle_apron/calls_annotation.res.oracle diff --git a/tests/value/calls_annotation.i b/tests/value/calls_annotation.i new file mode 100644 index 00000000000..3a9b799aa1d --- /dev/null +++ b/tests/value/calls_annotation.i @@ -0,0 +1,101 @@ +/* run.config* + STDOPT: +*/ + +/* This file tests the evaluation of the logical status of "calls" annotations, + and the reduction of called functions accordingly. */ + +volatile unsigned int nondet; + +int incr(int x) { + return x+1; +} + +int decr(int x) { + return x-1; +} + +int square(int x) { + return x*x; +} + +/* Should be never called according to "calls" annotations. */ +int error(int x) { + return x / 0; +} + +int unreachable(int x) { + return 0; +} + +typedef int (*fptr)(int); + +fptr funs[4] = { &incr, &decr, &square, &error }; + +int apply(fptr fp, int a) { + int x; + //@ calls incr, decr, square; // unknown: error could also be called + x = (*fp)(a); + //@ calls incr, decr, square; // valid as consequence of the previous one + x = (*fp)(x); + return x; +} + +void main(void) { + int a = 1, i = 0; + + /* Valid "calls" annotations. */ + //@ calls decr; // valid singleton + a = (*funs[1])(a); + i = nondet % 3; + //@ calls incr, decr, square; // valid + a = (*funs[i])(a); + //@ calls incr, decr, square, unreachable; // valid but contains unreachable + a = (*funs[i])(a); + + /* Unknown "calls" annotations: Eva can reduce the called functions. */ + i = nondet % 4; + //@ calls incr, decr; // unknown: square and error could also be called + a = (*funs[i])(a); + Frama_C_show_each_0_1(i); // i can be reduced to {0; 1} + + /* Invalid "calls" annotations. */ + if (nondet) { + //@ calls incr; // invalid + a = (*funs[1])(a); + Frama_C_show_each_UNREACHABLE(); + } + if (nondet) { + i = nondet % 2; + //@ calls square, unreachable; // invalid + a = (*funs[i])(a); + Frama_C_show_each_UNREACHABLE(i); + } + + /* "calls" annotations evaluated in multiple states. */ + //@ loop unroll 4; + for (int j = 0; j < 4; j++) { + a = 0; + //@ calls incr; // valid at each iteration + a = (*funs[0])(a); + //@ calls incr, decr; // valid at each iteration + a = (*funs[j % 2])(a); + i = nondet % (j+1); + //@ calls incr, decr, square; // valid then unknown at the last iteration + a = (*funs[i])(a); + if (nondet) { + //@ calls incr, decr, square; // invalid at the last iteration + a = (*funs[j])(a); + if (j == 3) Frama_C_show_each_UNREACHABLE(j); // j == 3 is impossible here. + } + if (nondet) { + a = apply(funs[j], a); // invalid at the last iteration + if (j == 3) Frama_C_show_each_UNREACHABLE(j); // j == 3 is impossible here. + } + if (nondet) { + //@ calls unreachable; // invalid at each iteration + a = (*funs[j])(a); + Frama_C_show_each_UNREACHABLE(a); + } + } +} diff --git a/tests/value/oracle/calls_annotation.res.oracle b/tests/value/oracle/calls_annotation.res.oracle new file mode 100644 index 00000000000..e22c92eeaa0 --- /dev/null +++ b/tests/value/oracle/calls_annotation.res.oracle @@ -0,0 +1,209 @@ +[kernel] Parsing calls_annotation.i (no preprocessing) +[eva] Analyzing a complete application starting at main +[eva] Computing initial state +[eva] Initial state computed +[eva:initial-state] Values of globals at initialization + nondet ∈ [--..--] + funs[0] ∈ {{ &incr }} + [1] ∈ {{ &decr }} + [2] ∈ {{ &square }} + [3] ∈ {{ &error }} +[eva] calls_annotation.i:49: calls annotation got status valid. +[eva] computing for function decr <- main. + Called from calls_annotation.i:49. +[eva] Recording results for decr +[eva] Done for function decr +[eva] calls_annotation.i:52: calls annotation got status valid. +[eva] computing for function square <- main. + Called from calls_annotation.i:52. +[eva] Recording results for square +[eva] Done for function square +[eva] computing for function decr <- main. + Called from calls_annotation.i:52. +[eva] Recording results for decr +[eva] Done for function decr +[eva] computing for function incr <- main. + Called from calls_annotation.i:52. +[eva] Recording results for incr +[eva] Done for function incr +[eva] calls_annotation.i:54: calls annotation got status valid. +[eva] computing for function square <- main. + Called from calls_annotation.i:54. +[eva] Recording results for square +[eva] Done for function square +[eva] computing for function decr <- main. + Called from calls_annotation.i:54. +[eva] Recording results for decr +[eva] Done for function decr +[eva] computing for function incr <- main. + Called from calls_annotation.i:54. +[eva] Recording results for incr +[eva] Done for function incr +[eva:alarm] calls_annotation.i:59: Warning: calls annotation got status unknown. +[eva] computing for function decr <- main. + Called from calls_annotation.i:59. +[eva] Recording results for decr +[eva] Done for function decr +[eva] computing for function incr <- main. + Called from calls_annotation.i:59. +[eva] Recording results for incr +[eva] Done for function incr +[eva] calls_annotation.i:60: Frama_C_show_each_0_1: {0; 1} +[eva:alarm] calls_annotation.i:65: Warning: + calls annotation got status invalid (stopping propagation). +[eva:alarm] calls_annotation.i:71: Warning: + calls annotation got status invalid (stopping propagation). +[eva] calls_annotation.i:80: calls annotation got status valid. +[eva] calls_annotation.i:80: Reusing old results for call to incr +[eva] calls_annotation.i:82: calls annotation got status valid. +[eva] computing for function incr <- main. + Called from calls_annotation.i:82. +[eva] Recording results for incr +[eva] Done for function incr +[eva] calls_annotation.i:85: calls annotation got status valid. +[eva] computing for function incr <- main. + Called from calls_annotation.i:85. +[eva] Recording results for incr +[eva] Done for function incr +[eva] calls_annotation.i:88: calls annotation got status valid. +[eva] computing for function incr <- main. + Called from calls_annotation.i:88. +[eva] Recording results for incr +[eva] Done for function incr +[eva] computing for function apply <- main. + Called from calls_annotation.i:92. +[eva] calls_annotation.i:38: calls annotation got status valid. +[eva] computing for function incr <- apply <- main. + Called from calls_annotation.i:38. +[eva] Recording results for incr +[eva] Done for function incr +[eva] calls_annotation.i:40: calls annotation got status valid. +[eva] computing for function incr <- apply <- main. + Called from calls_annotation.i:40. +[eva] Recording results for incr +[eva] Done for function incr +[eva] Recording results for apply +[eva] Done for function apply +[eva:alarm] calls_annotation.i:97: Warning: + calls annotation got status invalid (stopping propagation). +[eva] calls_annotation.i:80: Reusing old results for call to incr +[eva] calls_annotation.i:82: Reusing old results for call to decr +[eva] calls_annotation.i:85: Reusing old results for call to decr +[eva] calls_annotation.i:85: Reusing old results for call to incr +[eva] computing for function decr <- main. + Called from calls_annotation.i:88. +[eva] Recording results for decr +[eva] Done for function decr +[eva] computing for function apply <- main. + Called from calls_annotation.i:92. +[eva] computing for function decr <- apply <- main. + Called from calls_annotation.i:38. +[eva] Recording results for decr +[eva] Done for function decr +[eva] computing for function decr <- apply <- main. + Called from calls_annotation.i:40. +[eva] Recording results for decr +[eva] Done for function decr +[eva] Recording results for apply +[eva] Done for function apply +[eva] calls_annotation.i:80: Reusing old results for call to incr +[eva] calls_annotation.i:82: Reusing old results for call to incr +[eva] computing for function square <- main. + Called from calls_annotation.i:85. +[eva] Recording results for square +[eva] Done for function square +[eva] computing for function decr <- main. + Called from calls_annotation.i:85. +[eva] Recording results for decr +[eva] Done for function decr +[eva] calls_annotation.i:85: Reusing old results for call to incr +[eva] computing for function square <- main. + Called from calls_annotation.i:88. +[eva] Recording results for square +[eva] Done for function square +[eva] computing for function apply <- main. + Called from calls_annotation.i:92. +[eva] computing for function square <- apply <- main. + Called from calls_annotation.i:38. +[eva] Recording results for square +[eva] Done for function square +[eva] computing for function square <- apply <- main. + Called from calls_annotation.i:40. +[eva] Recording results for square +[eva] Done for function square +[eva] Recording results for apply +[eva] Done for function apply +[eva] calls_annotation.i:80: Reusing old results for call to incr +[eva] calls_annotation.i:82: Reusing old results for call to decr +[eva:alarm] calls_annotation.i:85: Warning: calls annotation got status unknown. +[eva] calls_annotation.i:85: Reusing old results for call to square +[eva] calls_annotation.i:85: Reusing old results for call to decr +[eva] calls_annotation.i:85: Reusing old results for call to incr +[eva:alarm] calls_annotation.i:88: Warning: + calls annotation got status invalid (stopping propagation). +[eva] computing for function apply <- main. + Called from calls_annotation.i:92. +[eva:alarm] calls_annotation.i:38: Warning: + calls annotation got status invalid (stopping propagation). +[eva] Recording results for apply +[eva] Done for function apply +[eva] Recording results for main +[eva] Done for function main +[eva] ====== VALUES COMPUTED ====== +[eva:final-states] Values at end of function decr: + __retres ∈ {-4; -3; -2; -1; 0; 1} +[eva:final-states] Values at end of function incr: + __retres ∈ {-1; 0; 1; 2; 3; 4; 5; 6} +[eva:final-states] Values at end of function square: + __retres ∈ [-1..65536] +[eva:final-states] Values at end of function apply: + x ∈ [-4..65536] +[eva:final-states] Values at end of function main: + a ∈ {-1; 0; 1} + i ∈ {0; 1; 2} +[from] Computing for function decr +[from] Done for function decr +[from] Computing for function incr +[from] Done for function incr +[from] Computing for function square +[from] Done for function square +[from] Computing for function apply +[from] Computing for function error <-apply +[from] Non-terminating function error (no dependencies) +[from] Done for function error +[from] Done for function apply +[from] Computing for function main +[from] Done for function main +[from] ====== DEPENDENCIES COMPUTED ====== + These dependencies hold at termination for the executions that terminate: +[from] Function decr: + \result FROM x +[from] Function incr: + \result FROM x +[from] Function square: + \result FROM x +[from] Function apply: + \result FROM fp; a +[from] Function main: + NO EFFECTS +[from] ====== END OF DEPENDENCIES ====== +[inout] Out (internal) for function decr: + __retres +[inout] Inputs for function decr: + \nothing +[inout] Out (internal) for function incr: + __retres +[inout] Inputs for function incr: + \nothing +[inout] Out (internal) for function square: + __retres +[inout] Inputs for function square: + \nothing +[inout] Out (internal) for function apply: + x +[inout] Inputs for function apply: + \nothing +[inout] Out (internal) for function main: + a; i; j +[inout] Inputs for function main: + nondet; funs[0..3] diff --git a/tests/value/oracle_apron/calls_annotation.res.oracle b/tests/value/oracle_apron/calls_annotation.res.oracle new file mode 100644 index 00000000000..2b7f3f96a5e --- /dev/null +++ b/tests/value/oracle_apron/calls_annotation.res.oracle @@ -0,0 +1,81 @@ +57c57,60 +< [eva] calls_annotation.i:80: Reusing old results for call to incr +--- +> [eva] computing for function incr <- main. +> Called from calls_annotation.i:80. +> [eva] Recording results for incr +> [eva] Done for function incr +89,92c92,107 +< [eva] calls_annotation.i:80: Reusing old results for call to incr +< [eva] calls_annotation.i:82: Reusing old results for call to decr +< [eva] calls_annotation.i:85: Reusing old results for call to decr +< [eva] calls_annotation.i:85: Reusing old results for call to incr +--- +> [eva] computing for function incr <- main. +> Called from calls_annotation.i:80. +> [eva] Recording results for incr +> [eva] Done for function incr +> [eva] computing for function decr <- main. +> Called from calls_annotation.i:82. +> [eva] Recording results for decr +> [eva] Done for function decr +> [eva] computing for function decr <- main. +> Called from calls_annotation.i:85. +> [eva] Recording results for decr +> [eva] Done for function decr +> [eva] computing for function incr <- main. +> Called from calls_annotation.i:85. +> [eva] Recording results for incr +> [eva] Done for function incr +109,110c124,131 +< [eva] calls_annotation.i:80: Reusing old results for call to incr +< [eva] calls_annotation.i:82: Reusing old results for call to incr +--- +> [eva] computing for function incr <- main. +> Called from calls_annotation.i:80. +> [eva] Recording results for incr +> [eva] Done for function incr +> [eva] computing for function incr <- main. +> Called from calls_annotation.i:82. +> [eva] Recording results for incr +> [eva] Done for function incr +119c140,143 +< [eva] calls_annotation.i:85: Reusing old results for call to incr +--- +> [eva] computing for function incr <- main. +> Called from calls_annotation.i:85. +> [eva] Recording results for incr +> [eva] Done for function incr +136,137c160,167 +< [eva] calls_annotation.i:80: Reusing old results for call to incr +< [eva] calls_annotation.i:82: Reusing old results for call to decr +--- +> [eva] computing for function incr <- main. +> Called from calls_annotation.i:80. +> [eva] Recording results for incr +> [eva] Done for function incr +> [eva] computing for function decr <- main. +> Called from calls_annotation.i:82. +> [eva] Recording results for decr +> [eva] Done for function decr +139,141c169,180 +< [eva] calls_annotation.i:85: Reusing old results for call to square +< [eva] calls_annotation.i:85: Reusing old results for call to decr +< [eva] calls_annotation.i:85: Reusing old results for call to incr +--- +> [eva] computing for function square <- main. +> Called from calls_annotation.i:85. +> [eva] Recording results for square +> [eva] Done for function square +> [eva] computing for function decr <- main. +> Called from calls_annotation.i:85. +> [eva] Recording results for decr +> [eva] Done for function decr +> [eva] computing for function incr <- main. +> Called from calls_annotation.i:85. +> [eva] Recording results for incr +> [eva] Done for function incr +158c197 +< __retres ∈ [-1..65536] +--- +> __retres ∈ [0..65536] -- GitLab