From 778ba37f1cb383495ed1a7c3da82c2c3413e72aa Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Fri, 27 Mar 2020 09:17:49 +0100 Subject: [PATCH] [Instantiate] Test related to enums for memset/calloc --- src/plugins/instantiate/tests/stdlib/calloc.c | 3 + .../tests/stdlib/oracle/calloc.res.oracle | 91 ++++++++++++++++++- .../instantiate/tests/string/memset_0.c | 6 ++ .../instantiate/tests/string/memset_FF.c | 6 ++ .../instantiate/tests/string/memset_value.c | 6 ++ .../tests/string/oracle/memset_0.res.oracle | 66 +++++++++++++- .../tests/string/oracle/memset_FF.res.oracle | 66 +++++++++++++- .../string/oracle/memset_value.res.oracle | 42 +++++++-- 8 files changed, 273 insertions(+), 13 deletions(-) diff --git a/src/plugins/instantiate/tests/stdlib/calloc.c b/src/plugins/instantiate/tests/stdlib/calloc.c index 87b1f9338cc..d87508ad415 100644 --- a/src/plugins/instantiate/tests/stdlib/calloc.c +++ b/src/plugins/instantiate/tests/stdlib/calloc.c @@ -11,8 +11,11 @@ struct Flex { int f[] ; } ; +enum E { A, B, C }; + int main(void){ int* pi = calloc(10, sizeof(int)) ; + enum E* pe = calloc(10, sizeof(enum E)) ; float* pf = calloc(10, sizeof(float)) ; struct X* px = calloc(10, sizeof(struct X)) ; char* pc = calloc(10, sizeof(char)) ; diff --git a/src/plugins/instantiate/tests/stdlib/oracle/calloc.res.oracle b/src/plugins/instantiate/tests/stdlib/oracle/calloc.res.oracle index 28d42c036e3..cc72848fd62 100644 --- a/src/plugins/instantiate/tests/stdlib/oracle/calloc.res.oracle +++ b/src/plugins/instantiate/tests/stdlib/oracle/calloc.res.oracle @@ -1,6 +1,6 @@ [kernel] Parsing tests/stdlib/calloc.c (with preprocessing) -[instantiate] tests/stdlib/calloc.c:21: Warning: Ignore call: not well typed -[instantiate] tests/stdlib/calloc.c:22: Warning: Ignore call: not well typed +[instantiate] tests/stdlib/calloc.c:24: Warning: Ignore call: not well typed +[instantiate] tests/stdlib/calloc.c:25: Warning: Ignore call: not well typed /* Generated by Frama-C */ #include "stdlib.h" struct X { @@ -12,6 +12,11 @@ struct Flex { char c ; int f[] ; }; +enum E { + A = 0, + B = 1, + C = 2 +}; struct incomplete; /*@ requires correct_size: 0 ≤ size - 8 ∧ 0 ≡ (size - 8) % 4; requires only_one: num ≡ 1; @@ -216,6 +221,43 @@ float *calloc_float(size_t num, size_t size) return __retres; } +/*@ requires correct_size: 0 ≡ size % 4; + assigns \result, __fc_heap_status; + assigns \result \from __fc_heap_status, num, size; + assigns __fc_heap_status \from __fc_heap_status, num, size; + allocates \result; + + behavior allocation: + assumes allocable: is_allocable(num * size); + ensures fresh_result: \fresh{Old, Here}(\result,num * size); + ensures + zero_initialization: + ∀ ℤ j0; 0 ≤ j0 < num ⇒ *(\result + j0) ≡ 0; + ensures + initialization: + ∀ ℤ j0; 0 ≤ j0 < num ⇒ \initialized(\result + j0); + assigns \result, __fc_heap_status; + assigns \result \from __fc_heap_status, num, size; + assigns __fc_heap_status \from __fc_heap_status, num, size; + allocates \result; + + behavior no_allocation: + assumes allocable: ¬is_allocable(num * size); + ensures null_result: \result ≡ \null; + assigns \result; + assigns \result \from \nothing; + allocates \nothing; + + complete behaviors no_allocation, allocation; + disjoint behaviors no_allocation, allocation; + */ +enum E *calloc_e_E(size_t num, size_t size) +{ + enum E *__retres; + __retres = (enum E *)calloc(num,size); + return __retres; +} + /*@ requires correct_size: 0 ≡ size % 4; assigns \result, __fc_heap_status; assigns \result \from __fc_heap_status, num, size; @@ -257,6 +299,7 @@ int main(void) { int __retres; int *pi = calloc_int((unsigned int)10,sizeof(int)); + enum E *pe = calloc_e_E((unsigned int)10,sizeof(enum E)); float *pf = calloc_float((unsigned int)10,sizeof(float)); struct X *px = calloc_st_X((unsigned int)10,sizeof(struct X)); char *pc = calloc_char((unsigned int)10,sizeof(char)); @@ -283,6 +326,11 @@ struct Flex { char c ; int f[] ; }; +enum E { + A = 0, + B = 1, + C = 2 +}; struct incomplete; /*@ requires correct_size: 0 ≤ size - 8 ∧ 0 ≡ (size - 8) % 4; requires only_one: num ≡ 1; @@ -490,6 +538,44 @@ float *calloc_float(size_t num, size_t size) return __retres; } +/*@ requires correct_size: 0 ≡ size % 4; + assigns \result, __fc_heap_status; + assigns \result \from __fc_heap_status, num, size; + assigns __fc_heap_status \from __fc_heap_status, num, size; + allocates \result; + + behavior allocation: + assumes allocable: is_allocable(num * size); + ensures + fresh_result: \fresh{Old, Here}(\result,\old(num) * \old(size)); + ensures + zero_initialization: + ∀ ℤ j0; 0 ≤ j0 < \old(num) ⇒ *(\result + j0) ≡ 0; + ensures + initialization: + ∀ ℤ j0; 0 ≤ j0 < \old(num) ⇒ \initialized(\result + j0); + assigns \result, __fc_heap_status; + assigns \result \from __fc_heap_status, num, size; + assigns __fc_heap_status \from __fc_heap_status, num, size; + allocates \result; + + behavior no_allocation: + assumes allocable: ¬is_allocable(num * size); + ensures null_result: \result ≡ \null; + assigns \result; + assigns \result \from \nothing; + allocates \nothing; + + complete behaviors no_allocation, allocation; + disjoint behaviors no_allocation, allocation; + */ +enum E *calloc_e_E(size_t num, size_t size) +{ + enum E *__retres; + __retres = (enum E *)calloc(num,size); + return __retres; +} + /*@ requires correct_size: 0 ≡ size % 4; assigns \result, __fc_heap_status; assigns \result \from __fc_heap_status, num, size; @@ -532,6 +618,7 @@ int main(void) { int __retres; int *pi = calloc_int((unsigned int)10,sizeof(int)); + enum E *pe = calloc_e_E((unsigned int)10,sizeof(enum E)); float *pf = calloc_float((unsigned int)10,sizeof(float)); struct X *px = calloc_st_X((unsigned int)10,sizeof(struct X)); char *pc = calloc_char((unsigned int)10,sizeof(char)); diff --git a/src/plugins/instantiate/tests/string/memset_0.c b/src/plugins/instantiate/tests/string/memset_0.c index ffd73cad6a7..f87d8629005 100644 --- a/src/plugins/instantiate/tests/string/memset_0.c +++ b/src/plugins/instantiate/tests/string/memset_0.c @@ -27,6 +27,12 @@ void integer(int dest[10]){ memset(res, 0, 10 * sizeof(int)); } +enum E { A, B, C } ; +void with_enum(enum E dest[10]){ + enum E * res = memset(dest, 0, 10 * sizeof(enum E)); + memset(res, 0, 10 * sizeof(enum E)); +} + void floats(float dest[10]){ float * res = memset(dest, 0, 10 * sizeof(float)); memset(res, 0, 10 * sizeof(float)); diff --git a/src/plugins/instantiate/tests/string/memset_FF.c b/src/plugins/instantiate/tests/string/memset_FF.c index 17c8260b516..45b8e49cd11 100644 --- a/src/plugins/instantiate/tests/string/memset_FF.c +++ b/src/plugins/instantiate/tests/string/memset_FF.c @@ -27,6 +27,12 @@ void integer(int dest[10]){ memset(res, 0xFF, 10 * sizeof(int)); } +enum E { A, B, C } ; +void with_enum(enum E dest[10]){ + enum E * res = memset(dest, 0xFF, 10 * sizeof(enum E)); + memset(res, 0xFF, 10 * sizeof(enum E)); +} + void unsigned_integer(unsigned dest[10]){ unsigned * res = memset(dest, 0xFF, 10 * sizeof(unsigned)); memset(res, 0xFF, 10 * sizeof(unsigned)); diff --git a/src/plugins/instantiate/tests/string/memset_value.c b/src/plugins/instantiate/tests/string/memset_value.c index 432b8ed6a6d..654466dbc2f 100644 --- a/src/plugins/instantiate/tests/string/memset_value.c +++ b/src/plugins/instantiate/tests/string/memset_value.c @@ -27,6 +27,12 @@ void integer(int dest[10], int value){ memset(res, value, 10 * sizeof(int)); } +enum E { A, B, C } ; +void with_enum(enum E dest[10], int value){ + enum E * res = memset(dest, value, 10 * sizeof(enum E)); + memset(res, value, 10 * sizeof(enum E)); +} + void with_named(named dest[10], int value){ named * res = memset(dest, value, 10 * sizeof(named)); memset(res, value, 10 * sizeof(named)); diff --git a/src/plugins/instantiate/tests/string/oracle/memset_0.res.oracle b/src/plugins/instantiate/tests/string/oracle/memset_0.res.oracle index 1b7efe66ddf..368076b562a 100644 --- a/src/plugins/instantiate/tests/string/oracle/memset_0.res.oracle +++ b/src/plugins/instantiate/tests/string/oracle/memset_0.res.oracle @@ -1,6 +1,6 @@ [kernel] Parsing tests/string/memset_0.c (with preprocessing) -[instantiate] tests/string/memset_0.c:56: Warning: Ignore call: not well typed -[instantiate] tests/string/memset_0.c:57: Warning: Ignore call: not well typed +[instantiate] tests/string/memset_0.c:62: Warning: Ignore call: not well typed +[instantiate] tests/string/memset_0.c:63: Warning: Ignore call: not well typed /* Generated by Frama-C */ #include "stddef.h" #include "string.h" @@ -10,6 +10,11 @@ struct X { int y ; }; typedef int named; +enum E { + A = 0, + B = 1, + C = 2 +}; /*@ requires in_bounds_value: -128 ≤ value < 128; requires valid_dest: \valid(ptr + (0 .. len - 1)); ensures @@ -111,6 +116,32 @@ void integer(int * /*[10]*/ dest) return; } +/*@ requires aligned_end: len % 4 ≡ 0; + requires + valid_dest: \let __fc_len = len / 4; \valid(ptr + (0 .. __fc_len - 1)); + ensures + set_content: + \let __fc_len = len / 4; + ∀ ℤ j0; 0 ≤ j0 < __fc_len ⇒ *(ptr + j0) ≡ 0; + ensures result: \result ≡ ptr; + assigns *(ptr + (0 .. len / 4 - 1)), \result; + assigns *(ptr + (0 .. len / 4 - 1)) \from \nothing; + assigns \result \from ptr; + */ +enum E *memset_e_E_0(enum E *ptr, size_t len) +{ + enum E *__retres; + __retres = (enum E *)memset((void *)ptr,0,len); + return __retres; +} + +void with_enum(enum E * /*[10]*/ dest) +{ + enum E *res = memset_e_E_0(dest,(unsigned int)10 * sizeof(enum E)); + memset_e_E_0(res,(unsigned int)10 * sizeof(enum E)); + return; +} + /*@ requires aligned_end: len % 4 ≡ 0; requires valid_dest: \let __fc_len = len / 4; \valid(ptr + (0 .. __fc_len - 1)); @@ -244,6 +275,11 @@ struct X { int y ; }; typedef int named; +enum E { + A = 0, + B = 1, + C = 2 +}; /*@ requires in_bounds_value: -128 ≤ value < 128; requires valid_dest: \valid(ptr + (0 .. len - 1)); ensures @@ -350,6 +386,32 @@ void integer(int *dest) return; } +/*@ requires aligned_end: len % 4 ≡ 0; + requires + valid_dest: \let __fc_len = len / 4; \valid(ptr + (0 .. __fc_len - 1)); + ensures + set_content: + \let __fc_len = \old(len) / 4; + ∀ ℤ j0; 0 ≤ j0 < __fc_len ⇒ *(\old(ptr) + j0) ≡ 0; + ensures result: \result ≡ \old(ptr); + assigns *(ptr + (0 .. len / 4 - 1)), \result; + assigns *(ptr + (0 .. len / 4 - 1)) \from \nothing; + assigns \result \from ptr; + */ +enum E *memset_e_E_0(enum E *ptr, size_t len) +{ + enum E *__retres; + __retres = (enum E *)memset((void *)ptr,0,len); + return __retres; +} + +void with_enum(enum E *dest) +{ + enum E *res = memset_e_E_0(dest,(unsigned int)10 * sizeof(enum E)); + memset_e_E_0(res,(unsigned int)10 * sizeof(enum E)); + return; +} + /*@ requires aligned_end: len % 4 ≡ 0; requires valid_dest: \let __fc_len = len / 4; \valid(ptr + (0 .. __fc_len - 1)); diff --git a/src/plugins/instantiate/tests/string/oracle/memset_FF.res.oracle b/src/plugins/instantiate/tests/string/oracle/memset_FF.res.oracle index ffe160d7caa..7495743e8a2 100644 --- a/src/plugins/instantiate/tests/string/oracle/memset_FF.res.oracle +++ b/src/plugins/instantiate/tests/string/oracle/memset_FF.res.oracle @@ -1,6 +1,6 @@ [kernel] Parsing tests/string/memset_FF.c (with preprocessing) -[instantiate] tests/string/memset_FF.c:82: Warning: Ignore call: not well typed -[instantiate] tests/string/memset_FF.c:83: Warning: Ignore call: not well typed +[instantiate] tests/string/memset_FF.c:88: Warning: Ignore call: not well typed +[instantiate] tests/string/memset_FF.c:89: Warning: Ignore call: not well typed /* Generated by Frama-C */ #include "stddef.h" #include "string.h" @@ -10,6 +10,11 @@ struct X { int y ; }; typedef int named; +enum E { + A = 0, + B = 1, + C = 2 +}; /*@ requires in_bounds_value: -128 ≤ value < 128; requires valid_dest: \valid(ptr + (0 .. len - 1)); ensures @@ -112,6 +117,32 @@ void integer(int * /*[10]*/ dest) return; } +/*@ requires aligned_end: len % 4 ≡ 0; + requires + valid_dest: \let __fc_len = len / 4; \valid(ptr + (0 .. __fc_len - 1)); + ensures + set_content: + \let __fc_len = len / 4; + ∀ ℤ j0; 0 ≤ j0 < __fc_len ⇒ *(ptr + j0) ≡ 4294967295; + ensures result: \result ≡ ptr; + assigns *(ptr + (0 .. len / 4 - 1)), \result; + assigns *(ptr + (0 .. len / 4 - 1)) \from \nothing; + assigns \result \from ptr; + */ +enum E *memset_e_E_FF(enum E *ptr, size_t len) +{ + enum E *__retres; + __retres = (enum E *)memset((void *)ptr,255,len); + return __retres; +} + +void with_enum(enum E * /*[10]*/ dest) +{ + enum E *res = memset_e_E_FF(dest,(unsigned int)10 * sizeof(enum E)); + memset_e_E_FF(res,(unsigned int)10 * sizeof(enum E)); + return; +} + /*@ requires aligned_end: len % 4 ≡ 0; requires valid_dest: \let __fc_len = len / 4; \valid(ptr + (0 .. __fc_len - 1)); @@ -382,6 +413,11 @@ struct X { int y ; }; typedef int named; +enum E { + A = 0, + B = 1, + C = 2 +}; /*@ requires in_bounds_value: -128 ≤ value < 128; requires valid_dest: \valid(ptr + (0 .. len - 1)); ensures @@ -489,6 +525,32 @@ void integer(int *dest) return; } +/*@ requires aligned_end: len % 4 ≡ 0; + requires + valid_dest: \let __fc_len = len / 4; \valid(ptr + (0 .. __fc_len - 1)); + ensures + set_content: + \let __fc_len = \old(len) / 4; + ∀ ℤ j0; 0 ≤ j0 < __fc_len ⇒ *(\old(ptr) + j0) ≡ 4294967295; + ensures result: \result ≡ \old(ptr); + assigns *(ptr + (0 .. len / 4 - 1)), \result; + assigns *(ptr + (0 .. len / 4 - 1)) \from \nothing; + assigns \result \from ptr; + */ +enum E *memset_e_E_FF(enum E *ptr, size_t len) +{ + enum E *__retres; + __retres = (enum E *)memset((void *)ptr,255,len); + return __retres; +} + +void with_enum(enum E *dest) +{ + enum E *res = memset_e_E_FF(dest,(unsigned int)10 * sizeof(enum E)); + memset_e_E_FF(res,(unsigned int)10 * sizeof(enum E)); + return; +} + /*@ requires aligned_end: len % 4 ≡ 0; requires valid_dest: \let __fc_len = len / 4; \valid(ptr + (0 .. __fc_len - 1)); diff --git a/src/plugins/instantiate/tests/string/oracle/memset_value.res.oracle b/src/plugins/instantiate/tests/string/oracle/memset_value.res.oracle index 462fc372857..f68d49c8e42 100644 --- a/src/plugins/instantiate/tests/string/oracle/memset_value.res.oracle +++ b/src/plugins/instantiate/tests/string/oracle/memset_value.res.oracle @@ -3,30 +3,34 @@ Ignore call: not well typed [instantiate] tests/string/memset_value.c:27: Warning: Ignore call: not well typed -[instantiate] tests/string/memset_value.c:31: Warning: - Ignore call: not well typed [instantiate] tests/string/memset_value.c:32: Warning: Ignore call: not well typed -[instantiate] tests/string/memset_value.c:36: Warning: +[instantiate] tests/string/memset_value.c:33: Warning: Ignore call: not well typed [instantiate] tests/string/memset_value.c:37: Warning: Ignore call: not well typed -[instantiate] tests/string/memset_value.c:41: Warning: +[instantiate] tests/string/memset_value.c:38: Warning: Ignore call: not well typed [instantiate] tests/string/memset_value.c:42: Warning: Ignore call: not well typed -[instantiate] tests/string/memset_value.c:46: Warning: +[instantiate] tests/string/memset_value.c:43: Warning: Ignore call: not well typed [instantiate] tests/string/memset_value.c:47: Warning: Ignore call: not well typed -[instantiate] tests/string/memset_value.c:51: Warning: +[instantiate] tests/string/memset_value.c:48: Warning: Ignore call: not well typed [instantiate] tests/string/memset_value.c:52: Warning: Ignore call: not well typed -[instantiate] tests/string/memset_value.c:56: Warning: +[instantiate] tests/string/memset_value.c:53: Warning: Ignore call: not well typed [instantiate] tests/string/memset_value.c:57: Warning: Ignore call: not well typed +[instantiate] tests/string/memset_value.c:58: Warning: + Ignore call: not well typed +[instantiate] tests/string/memset_value.c:62: Warning: + Ignore call: not well typed +[instantiate] tests/string/memset_value.c:63: Warning: + Ignore call: not well typed /* Generated by Frama-C */ #include "stddef.h" #include "string.h" @@ -36,6 +40,11 @@ struct X { int y ; }; typedef int named; +enum E { + A = 0, + B = 1, + C = 2 +}; struct incomplete; /*@ requires in_bounds_value: -128 ≤ value < 128; requires valid_dest: \valid(ptr + (0 .. len - 1)); @@ -119,6 +128,13 @@ void integer(int * /*[10]*/ dest, int value) return; } +void with_enum(enum E * /*[10]*/ dest, int value) +{ + enum E *res = memset((void *)dest,value,(unsigned int)10 * sizeof(enum E)); + memset((void *)res,value,(unsigned int)10 * sizeof(enum E)); + return; +} + void with_named(named * /*[10]*/ dest, int value) { named *res = memset((void *)dest,value,(unsigned int)10 * sizeof(named)); @@ -174,6 +190,11 @@ struct X { int y ; }; typedef int named; +enum E { + A = 0, + B = 1, + C = 2 +}; struct incomplete; /*@ requires in_bounds_value: -128 ≤ value < 128; requires valid_dest: \valid(ptr + (0 .. len - 1)); @@ -262,6 +283,13 @@ void integer(int *dest, int value) return; } +void with_enum(enum E *dest, int value) +{ + enum E *res = memset((void *)dest,value,(unsigned int)10 * sizeof(enum E)); + memset((void *)res,value,(unsigned int)10 * sizeof(enum E)); + return; +} + void with_named(named *dest, int value) { named *res = memset((void *)dest,value,(unsigned int)10 * sizeof(named)); -- GitLab