Example: provenance_union_punning_1_global.c

#include <stdio.h>
#include <string.h>
#include <inttypes.h>
int x=1;
typedef union { uintptr_t ui; int *p; } un;
int main() {
un u;
int *px = &x;
uintptr_t i = (uintptr_t)px;
u.ui = i;
int *p = u.p;
printf("Addresses: p=%p &x=%p\n",(void*)p,(void*)&x);
*p = 11; // is this free of undefined behaviour?
printf("x=%d *p=%d\n",x,*p);
return 0;
}

[link to test in Cerberus and Compiler Explorer]

Experimental data (what does this mean?)

gcc-8.1-O0 Addresses: p=0x6009b8 &x=0x6009b8
x=11 *p=11
gcc-8.1-O2 Addresses: p=0x600980 &x=0x600980
x=11 *p=11
gcc-8.1-O3 Addresses: p=0x600980 &x=0x600980
x=11 *p=11
gcc-8.1-O2-no-strict-aliasing Addresses: p=0x600980 &x=0x600980
x=11 *p=11
gcc-8.1-O3-no-strict-aliasing Addresses: p=0x600980 &x=0x600980
x=11 *p=11
clang-6.0-O0 Addresses: p=0x601038 &x=0x601038
x=11 *p=11
clang-6.0-O2 Addresses: p=0x601038 &x=0x601038
x=11 *p=11
clang-6.0-O3 Addresses: p=0x601038 &x=0x601038
x=11 *p=11
clang-6.0-O2-no-strict-aliasing Addresses: p=0x601038 &x=0x601038
x=11 *p=11
clang-6.0-O3-no-strict-aliasing Addresses: p=0x601038 &x=0x601038
x=11 *p=11
clang-6.0-UBSAN Addresses: p=0x631b50 &x=0x631b50
x=11 *p=11
clang-6.0-ASAN Addresses: p=0x716b60 &x=0x716b60
x=11 *p=11
clang-6.0-MSAN Addresses: p=0x6b7af0 &x=0x6b7af0
x=11 *p=11
icc-19-O0 Addresses: p=0x600ab0 &x=0x600ab0
x=11 *p=11
icc-19-O2 Addresses: p=0x6046c0 &x=0x6046c0
x=11 *p=11
icc-19-O3 Addresses: p=0x6046c0 &x=0x6046c0
x=11 *p=11
icc-19-O2-no-strict-aliasing Addresses: p=0x6046c0 &x=0x6046c0
x=11 *p=11
icc-19-O3-no-strict-aliasing Addresses: p=0x6046c0 &x=0x6046c0
x=11 *p=11
cerberus-concrete BEGIN EXEC[0]
Defined {value: "Specified(0)", stdout: "Addresses: p=<5>:60 &x=<5>:60\nx=11 *p=11\n", blocked: "false"}
END EXEC[0]
Time spent: 0.032592 seconds
cerberus-symbolic exit codes: compile 0 / execute 1 cerberus: internal error, uncaught exception:
Failure("TODO: union punning")

gcc-4.9-shadowprov exit codes: compile 0 / execute 134
CHERI:MIPS-O0 Addresses: p=0x30020 &x=0x30020
x=11 *p=11
CHERI:MIPS-O2 Addresses: p=0x30020 &x=0x30020
x=11 *p=11
CHERI:MIPS-O2-no-strict-aliasing Addresses: p=0x30020 &x=0x30020
x=11 *p=11
CHERI:CHERI-O0-uintcap-addr-exact-equals Addresses: p=0x120020010 &x=0x120020010
x=11 *p=11
CHERI:CHERI-O2-uintcap-addr-exact-equals Addresses: p=0x120020010 &x=0x120020010
x=11 *p=11
CHERI:CHERI-O2-no-strict-aliasing-uintcap-addr-exact-equals Addresses: p=0x120020010 &x=0x120020010
x=11 *p=11
CHERI:CHERI-O0-uintcap-offset-exact-equals Addresses: p=0x120020010 &x=0x120020010
x=11 *p=11
CHERI:CHERI-O2-uintcap-offset-exact-equals Addresses: p=0x120020010 &x=0x120020010
x=11 *p=11
CHERI:CHERI-O2-no-strict-aliasing-uintcap-offset-exact-equals Addresses: p=0x120020010 &x=0x120020010
x=11 *p=11
CHERI:CHERI-O0-uintcap-addr Addresses: p=0x120020010 &x=0x120020010
x=11 *p=11
CHERI:CHERI-O2-uintcap-addr Addresses: p=0x120020010 &x=0x120020010
x=11 *p=11
CHERI:CHERI-O2-no-strict-aliasing-uintcap-addr Addresses: p=0x120020010 &x=0x120020010
x=11 *p=11
CHERI:CHERI-O0-uintcap-offset Addresses: p=0x120020010 &x=0x120020010
x=11 *p=11
CHERI:CHERI-O2-uintcap-offset Addresses: p=0x120020010 &x=0x120020010
x=11 *p=11
CHERI:CHERI-O2-no-strict-aliasing-uintcap-offset Addresses: p=0x120020010 &x=0x120020010
x=11 *p=11
RV-Match Addresses: p=(nil) &x=(nil)
x=11 *p=11
ch2o provenance_union_punning_1_global.c:3:10: fatal error: inttypes.h: No such file or directory
#include <inttypes.h>
^~~~~~~~~~~~
compilation terminated.
compcert-3.2 Addresses: p=0x601038 &x=0x601038
x=11 *p=11
compcert-3.2-O Addresses: p=0x601038 &x=0x601038
x=11 *p=11
compcert-3.2-interp Time 0: calling main()
--[step_internal_function]-->
Time 1: in function main, statement
px = &x;
i = (unsigned int) px;
u.ui = i;
p = u.p;
printf(__stringlit_1, (void *) p, (void *) &x);
*p = 11;
printf(__stringlit_2, x, *p);
return 0;
return 0;
--[step_seq]-->
Time 2: in function main, statement
px = &x;
i = (unsigned int) px;
u.ui = i;
p = u.p;
printf(__stringlit_1, (void *) p, (void *) &x);
*p = 11;
printf(__stringlit_2, x, *p);
return 0;
--[step_seq]-->
Time 3: in function main, statement px = &x;
--[step_do_1]-->
Time 4: in function main, expression px = &x
--[red_var_local]-->
Time 5: in function main, expression <loc px> = &x
--[red_var_global]-->
Time 6: in function main, expression <loc px> = &<loc x>
--[red_addrof]-->
Time 7: in function main, expression <loc px> = <ptr x>
--[red_assign]-->
Time 8: in function main, expression <ptr x>
--[step_do_2]-->
Time 9: in function main, statement /*skip*/;
--[step_skip_seq]-->
Time 10: in function main, statement
i = (unsigned int) px;
u.ui = i;
p = u.p;
printf(__stringlit_1, (void *) p, (void *) &x);
*p = 11;
printf(__stringlit_2, x, *p);
return 0;
--[step_seq]-->
Time 11: in function main, statement i = (unsigned int) px;
--[step_do_1]-->
Time 12: in function main, expression i = (unsigned int) px
--[red_var_local]-->
Time 13: in function main, expression <loc i> = (unsigned int) px
--[red_var_local]-->
Time 14: in function main, expression <loc i> = (unsigned int) <loc px>
--[red_rvalof]-->
Time 15: in function main, expression <loc i> = (unsigned int) <ptr x>
--[red_cast]-->
Time 16: in function main, expression <loc i> = <ptr x>
--[red_assign]-->
Time 17: in function main, expression <ptr x>
--[step_do_2]-->
Time 18: in function main, statement /*skip*/;
--[step_skip_seq]-->
Time 19: in function main, statement
u.ui = i;
p = u.p;
printf(__stringlit_1, (void *) p, (void *) &x);
*p = 11;
printf(__stringlit_2, x, *p);
return 0;
--[step_seq]-->
Time 20: in function main, statement u.ui = i;
--[step_do_1]-->
Time 21: in function main, expression u.ui = i
--[red_var_local]-->
Time 22: in function main, expression <loc u>.ui = i
--[red_rvalof]-->
Time 23: in function main, expression <ptr u>.ui = i
--[red_field_union]-->
Time 24: in function main, expression <loc u> = i
--[red_var_local]-->
Time 25: in function main, expression <loc u> = <loc i>
--[red_rvalof]-->
Time 26: in function main, expression <loc u> = <ptr x>
--[red_assign]-->
Time 27: in function main, expression <ptr x>
--[step_do_2]-->
Time 28: in function main, statement /*skip*/;
--[step_skip_seq]-->
Time 29: in function main, statement
p = u.p;
printf(__stringlit_1, (void *) p, (void *) &x);
*p = 11;
printf(__stringlit_2, x, *p);
return 0;
--[step_seq]-->
Time 30: in function main, statement p = u.p;
--[step_do_1]-->
Time 31: in function main, expression p = u.p
--[red_var_local]-->
Time 32: in function main, expression <loc p> = u.p
--[red_var_local]-->
Time 33: in function main, expression <loc p> = <loc u>.p
--[red_rvalof]-->
Time 34: in function main, expression <loc p> = <ptr u>.p
--[red_field_union]-->
Time 35: in function main, expression <loc p> = <loc u>
--[red_rvalof]-->
Time 36: in function main, expression <loc p> = <ptr x>
--[red_assign]-->
Time 37: in function main, expression <ptr x>
--[step_do_2]-->
Time 38: in function main, statement /*skip*/;
--[step_skip_seq]-->
Time 39: in function main, statement
printf(__stringlit_1, (void *) p, (void *) &x);
*p = 11;
printf(__stringlit_2, x, *p);
return 0;
--[step_seq]-->
Time 40: in function main, statement
printf(__stringlit_1, (void *) p, (void *) &x);
--[step_do_1]-->
Time 41: in function main, expression
printf(__stringlit_1, (void *) p, (void *) &x)
--[red_var_global]-->
Time 42: in function main, expression
printf(<loc __stringlit_1>, (void *) p, (void *) &x)
--[red_rvalof]-->
Time 43: in function main, expression
printf(<ptr __stringlit_1>, (void *) p, (void *) &x)
--[red_var_local]-->
Time 44: in function main, expression
printf(<ptr __stringlit_1>, (void *) <loc p>, (void *) &x)
--[red_rvalof]-->
Time 45: in function main, expression
printf(<ptr __stringlit_1>, (void *) <ptr x>, (void *) &x)
--[red_cast]-->
Time 46: in function main, expression
printf(<ptr __stringlit_1>, <ptr x>, (void *) &x)
--[red_var_global]-->
Time 47: in function main, expression
printf(<ptr __stringlit_1>, <ptr x>, (void *) &<loc x>)
--[red_addrof]-->
Time 48: in function main, expression
printf(<ptr __stringlit_1>, <ptr x>, (void *) <ptr x>)
--[red_cast]-->
Time 49: in function main, expression
printf(<ptr __stringlit_1>, <ptr x>, <ptr x>)
Addresses: p=<55+0> &x=<55+0>
Time 49: observable event:
extcall printf(& __stringlit_1, & x, & x) -> 30
--[red_builtin]-->
Time 50: in function main, expression 30
--[step_do_2]-->
Time 51: in function main, statement /*skip*/;
--[step_skip_seq]-->
Time 52: in function main, statement
*p = 11; printf(__stringlit_2, x, *p); return 0;
--[step_seq]-->
Time 53: in function main, statement *p = 11;
--[step_do_1]-->
Time 54: in function main, expression *p = 11
--[red_var_local]-->
Time 55: in function main, expression *<loc p> = 11
--[red_rvalof]-->
Time 56: in function main, expression *<ptr x> = 11
--[red_deref]-->
Time 57: in function main, expression <loc x> = 11
--[red_assign]-->
Time 58: in function main, expression 11
--[step_do_2]-->
Time 59: in function main, statement /*skip*/;
--[step_skip_seq]-->
Time 60: in function main, statement printf(__stringlit_2, x, *p); return 0;
--[step_seq]-->
Time 61: in function main, statement printf(__stringlit_2, x, *p);
--[step_do_1]-->
Time 62: in function main, expression printf(__stringlit_2, x, *p)
--[red_var_global]-->
Time 63: in function main, expression printf(<loc __stringlit_2>, x, *p)
--[red_rvalof]-->
Time 64: in function main, expression printf(<ptr __stringlit_2>, x, *p)
--[red_var_global]-->
Time 65: in function main, expression
printf(<ptr __stringlit_2>, <loc x>, *p)
--[red_rvalof]-->
Time 66: in function main, expression printf(<ptr __stringlit_2>, 11, *p)
--[red_var_local]-->
Time 67: in function main, expression
printf(<ptr __stringlit_2>, 11, *<loc p>)
--[red_rvalof]-->
Time 68: in function main, expression
printf(<ptr __stringlit_2>, 11, *<ptr x>)
--[red_deref]-->
Time 69: in function main, expression
printf(<ptr __stringlit_2>, 11, <loc x>)
--[red_rvalof]-->
Time 70: in function main, expression printf(<ptr __stringlit_2>, 11, 11)
x=11 *p=11
Time 70: observable event: extcall printf(& __stringlit_2, 11,
11) -> 11
--[red_builtin]-->
Time 71: in function main, expression 11
--[step_do_2]-->
Time 72: in function main, statement /*skip*/;
--[step_skip_seq]-->
Time 73: in function main, statement return 0;
--[step_return_1]-->
Time 74: in function main, expression 0
--[step_return_2]-->
Time 75: returning 0
Time 75: program terminated (exit code = 0)
In file included from provenance_union_punning_1_global.c:1:
In file included from /usr/include/stdio.h:64:
In file included from /usr/include/_stdio.h:68:
/usr/include/sys/cdefs.h:81:2: warning: "Unsupported compiler detected" [-W#warnings]
#warning "Unsupported compiler detected"
^
1 warning generated.