Example: provenance_tag_bits_via_uintptr_t_1.c

up: index
prev: pointer_offset_xor_auto.c
next: pointer_arith_algebraic_properties_2_global.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    #include <assert.h>
    #include <stdio.h>
    #include <stdint.h>
    int x=1;
    int main() {
      int *p = &x;
      // cast &x to an integer 
      uintptr_t i = (uintptr_t) p;
      // check the bottom two bits of an int* are not used
      assert(_Alignof(int) >= 4);
      assert((i & 3u) == 0u);
      // construct an integer like &x with low-order bit set
      i = i | 1u;  
      // cast back to a pointer
      int *q = (int *) i; // does this have defined behaviour?
      // cast to integer and mask out the low-order two bits
      uintptr_t j = ((uintptr_t)q) & ~((uintptr_t)3u);  
      // cast back to a pointer
      int *r = (int *) j; 
      // are r and p now equivalent?  
      *r = 11;           //  does this have defined behaviour? 
      _Bool b = (r==p);  //  is this true?
      printf("x=%i *r=%i (r==p)=%s\n",x,*r,b?"true":"false");  
    }
[link to run test in Cerberus]

Experimental data (what does this mean?)

cerberus-concrete-PVI x=11 *r=11 (r==p)=true
cerberus-concrete-PNVI x=11 *r=11 (r==p)=true
gcc-8.1-O0 x=11 *r=11 (r==p)=true
gcc-8.1-O2 x=11 *r=11 (r==p)=true
gcc-8.1-O3 x=11 *r=11 (r==p)=true
gcc-8.1-O2-no-strict-aliasing x=11 *r=11 (r==p)=true
gcc-8.1-O3-no-strict-aliasing x=11 *r=11 (r==p)=true
clang-6.0-O0 x=11 *r=11 (r==p)=true
clang-6.0-O2 x=11 *r=11 (r==p)=true
clang-6.0-O3 x=11 *r=11 (r==p)=true
clang-6.0-O2-no-strict-aliasing x=11 *r=11 (r==p)=true
clang-6.0-O3-no-strict-aliasing x=11 *r=11 (r==p)=true
clang-6.0-UBSAN x=11 *r=11 (r==p)=true
clang-6.0-ASAN x=11 *r=11 (r==p)=true
clang-6.0-MSAN x=11 *r=11 (r==p)=true
icc-19-O0 x=11 *r=11 (r==p)=true
icc-19-O2 x=11 *r=11 (r==p)=true
icc-19-O3 x=11 *r=11 (r==p)=true
icc-19-O2-no-strict-aliasing x=11 *r=11 (r==p)=true
icc-19-O3-no-strict-aliasing x=11 *r=11 (r==p)=true
compcert-3.4 x=11 *r=11 (r==p)=true
compcert-3.4-O x=11 *r=11 (r==p)=true
kcc-1.0 x=11 *r=11 (r==p)=true
Conversion from an integer to non-null pointer:
> in main at provenance_tag_bits_via_uintptr_t_1.c:15:3

Implementation defined behavior (IMPL-CCV13):
see C11 section 6.3.2.3:5 http://rvdoc.org/C11/6.3.2.3
see CERT section INT36-C http://rvdoc.org/CERT/INT36-C

Conversion from an integer to non-null pointer:
> in main at provenance_tag_bits_via_uintptr_t_1.c:19:3

Implementation defined behavior (IMPL-CCV13):
see C11 section 6.3.2.3:5 http://rvdoc.org/C11/6.3.2.3
see CERT section INT36-C http://rvdoc.org/CERT/INT36-C