Am Donnerstag, dem 25.09.2025 um 20:02 -0700 schrieb Kees Cook: > > An important aspect of the C++ typeinfo behavior that is retained here > is that typedefs are treated as pass-through except when the underlying > type lacks a tag (i.e. anonymous struct, union, or enum). This provides a > distinction between those typedefs and typedefs used to provide _aliases_ > (u8, uint16_t). > > In the future, an additional "strict mode" builtin helper pair could > also be added to follow strict ISO C type equivalency instead of the > existing typeinfo used here, but that is out of scope for this patch.
The ISO C mode would be *less* strict. Or in other words, the current version would reject valid C programs at run-time. I try to point out the differences below. > + > + /* Test pointer types */ > + TEST_STRING(char*, "Pc"); > + TEST_STRING(int*, "Pi"); > + TEST_STRING(void*, "Pv"); > + TEST_STRING(const char*, "PKc"); > + > + /* Test array types */ > + TEST_STRING(int[10], "A10_i"); > + TEST_STRING(char[20], "A20_c"); > + TEST_STRING(short[], "A_s"); > + > + /* Test basic function types */ > + extern void func_void(void); > + extern void func_char(char x); > + extern void func_short(short x); > + extern void func_int(int x); > + extern void func_long(long x); > + TEST_STRING(func_void, "FvvE"); > + TEST_STRING(func_char, "FvcE"); > + TEST_STRING(func_short, "FvsE"); > + TEST_STRING(func_int, "FviE"); > + TEST_STRING(func_long, "FvlE"); > + > + /* Test functions with unsigned types */ > + extern void func_unsigned_char(unsigned char x); > + extern void func_unsigned_short(unsigned short x); > + extern void func_unsigned_int(unsigned int x); > + TEST_STRING(func_unsigned_char, "FvhE"); > + TEST_STRING(func_unsigned_short, "FvtE"); > + TEST_STRING(func_unsigned_int, "FvjE"); > + > + /* Test functions with signed types */ > + extern void func_signed_char(signed char x); > + extern void func_signed_short(signed short x); > + extern void func_signed_int(signed int x); > + TEST_STRING(func_signed_char, "FvaE"); > + TEST_STRING(func_signed_short, "FvsE"); > + TEST_STRING(func_signed_int, "FviE"); > + > + /* Test functions with pointer types */ > + extern void func_void_ptr(void *x); > + extern void func_char_ptr(char *x); > + extern void func_short_ptr(short *x); > + extern void func_int_ptr(int *x); > + extern void func_int_array(int arr[]); /* Decays to "int *". */ > + extern void func_long_ptr(long *x); > + TEST_STRING(func_void_ptr, "FvPvE"); > + TEST_STRING(func_char_ptr, "FvPcE"); > + TEST_STRING(func_short_ptr, "FvPsE"); > + TEST_STRING(func_int_ptr, "FvPiE"); > + TEST_STRING(func_int_array, "FvPiE"); > + TEST_STRING(func_long_ptr, "FvPlE"); > + > + /* Test functions with const qualifiers */ > + extern void func_const_void_ptr(const void *x); > + extern void func_const_char_ptr(const char *x); > + extern void func_const_short_ptr(const short *x); > + extern void func_const_int_ptr(const int *x); > + extern void func_const_long_ptr(const long *x); > + TEST_STRING(func_const_void_ptr, "FvPKvE"); > + TEST_STRING(func_const_char_ptr, "FvPKcE"); > + TEST_STRING(func_const_short_ptr, "FvPKsE"); > + TEST_STRING(func_const_int_ptr, "FvPKiE"); > + TEST_STRING(func_const_long_ptr, "FvPKlE"); This ok, but there is a proposal to relax the rules for qualifiers, so in the future preserving all qualifiers might be too strict for C. > + /* Test 2D VLA with fixed dimension: should be all the same. */ > + extern void func_vla_2d_first(int n, int arr[n][10]); > + extern void func_vla_2d_empty(int n, int arr[][10]); > + extern void func_vla_2d_ptr(int n, int (*arr)[10]); > + TEST_STRING(func_vla_2d_first, "FviPA10_iE"); > + TEST_STRING(func_vla_2d_empty, "FviPA10_iE"); > + TEST_STRING(func_vla_2d_ptr, "FviPA10_iE"); > + > + /* Test 2D VLA with both dimensions variable: should be all the same. */ > + extern void func_vla_2d_both(int rows, int cols, int arr[rows][cols]); > + extern void func_vla_2d_second(int rows, int cols, int arr[][cols]); > + extern void func_vla_2d_star(int rows, int cols, int arr[*][cols]); > + TEST_STRING(func_vla_2d_both, "FviiPA_iE"); > + TEST_STRING(func_vla_2d_second, "FviiPA_iE"); > + TEST_STRING(func_vla_2d_star, "FviiPA_iE"); While the top-most decays to a pointer, the deeper arrays are stay but are compatible between the fixed and variable case. So according to C rules, they would all need to be canonicalized to the same. Martin
