xref: /llvm-project/clang/test/Sema/init-randomized-struct.c (revision f2639cf3fe46c30ad450cc2533c81eacd4788c33)
1*f2639cf3SBill Wendling // RUN: %clang_cc1 -triple=x86_64-unknown-linux -frandomize-layout-seed=1234567890abcded \
27f31b4a9SBill Wendling // RUN:  -verify -fsyntax-only -Werror %s
37f31b4a9SBill Wendling 
4*f2639cf3SBill Wendling // NOTE: The current seed (1234567890abcded) is specifically chosen because it
5*f2639cf3SBill Wendling // uncovered a bug in diagnostics. With it the randomization of "t9" places the
6*f2639cf3SBill Wendling // "a" element at the end of the record. When that happens, the clang complains
7*f2639cf3SBill Wendling // about excessive initializers, which is confusing, because there aren't
8*f2639cf3SBill Wendling // excessive initializers. It should instead complain about using a
9*f2639cf3SBill Wendling // non-designated initializer on a raqndomized struct.
10*f2639cf3SBill Wendling 
117f31b4a9SBill Wendling // Initializing a randomized structure requires a designated initializer,
127f31b4a9SBill Wendling // otherwise the element ordering will be off. The only exceptions to this rule
137f31b4a9SBill Wendling // are:
147f31b4a9SBill Wendling //
157f31b4a9SBill Wendling //    - A structure with only one element, and
167f31b4a9SBill Wendling //    - A structure initialized with "{0}".
177f31b4a9SBill Wendling //
187f31b4a9SBill Wendling // These are well-defined situations where the field ordering doesn't affect
197f31b4a9SBill Wendling // the result.
207f31b4a9SBill Wendling 
217f31b4a9SBill Wendling typedef void (*func_ptr)();
227f31b4a9SBill Wendling 
237f31b4a9SBill Wendling void foo(void);
247f31b4a9SBill Wendling void bar(void);
257f31b4a9SBill Wendling void baz(void);
267f31b4a9SBill Wendling void gaz(void);
277f31b4a9SBill Wendling 
287f31b4a9SBill Wendling struct test {
297f31b4a9SBill Wendling   func_ptr a;
307f31b4a9SBill Wendling   func_ptr b;
317f31b4a9SBill Wendling   func_ptr c;
327f31b4a9SBill Wendling   func_ptr d;
337f31b4a9SBill Wendling   func_ptr e;
347f31b4a9SBill Wendling   func_ptr f;
357f31b4a9SBill Wendling   func_ptr g;
367f31b4a9SBill Wendling } __attribute__((randomize_layout));
377f31b4a9SBill Wendling 
387f31b4a9SBill Wendling struct test t1 = {}; // This should be fine per WG14 N2900 (in C23) + our extension handling of it in earlier modes
397f31b4a9SBill Wendling struct test t2 = { 0 }; // This should also be fine per C99 6.7.8p19
407f31b4a9SBill Wendling struct test t3 = { .f = baz, .b = bar, .g = gaz, .a = foo }; // Okay
417f31b4a9SBill Wendling struct test t4 = { .a = foo, bar, baz }; // expected-error {{a randomized struct can only be initialized with a designated initializer}}
427f31b4a9SBill Wendling 
437f31b4a9SBill Wendling struct other_test {
447f31b4a9SBill Wendling   func_ptr a;
457f31b4a9SBill Wendling   func_ptr b[3];
467f31b4a9SBill Wendling   func_ptr c;
477f31b4a9SBill Wendling } __attribute__((randomize_layout));
487f31b4a9SBill Wendling 
497f31b4a9SBill Wendling struct other_test t5 = { .a = foo, .b[0] = foo }; // Okay
507f31b4a9SBill Wendling struct other_test t6 = { .a = foo, .b[0] = foo, bar, baz }; // Okay
517f31b4a9SBill Wendling struct other_test t7 = { .a = foo, .b = { foo, bar, baz } }; // Okay
527f31b4a9SBill Wendling struct other_test t8 = { baz, bar, gaz, foo }; // expected-error {{a randomized struct can only be initialized with a designated initializer}}
537f31b4a9SBill Wendling struct other_test t9 = { .a = foo, .b[0] = foo, bar, baz, gaz }; // expected-error {{a randomized struct can only be initialized with a designated initializer}}
547f31b4a9SBill Wendling 
557f31b4a9SBill Wendling struct empty_test {
567f31b4a9SBill Wendling } __attribute__((randomize_layout));
577f31b4a9SBill Wendling 
587f31b4a9SBill Wendling struct empty_test t10 = {}; // Okay
597f31b4a9SBill Wendling 
607f31b4a9SBill Wendling struct degen_test {
617f31b4a9SBill Wendling   func_ptr a;
627f31b4a9SBill Wendling } __attribute__((randomize_layout));
637f31b4a9SBill Wendling 
647f31b4a9SBill Wendling struct degen_test t11 = { foo }; // Okay
65463790bfSBill Wendling 
66463790bfSBill Wendling struct static_assert_test {
67463790bfSBill Wendling   int f;
68463790bfSBill Wendling   _Static_assert(sizeof(int) == 4, "oh no!");
69463790bfSBill Wendling } __attribute__((randomize_layout));
70463790bfSBill Wendling 
71463790bfSBill Wendling struct static_assert_test t12 = { 42 }; // Okay
72463790bfSBill Wendling 
73463790bfSBill Wendling struct enum_decl_test {
74463790bfSBill Wendling   enum e { BORK = 42, FORK = 9 } f;
75463790bfSBill Wendling } __attribute__((randomize_layout));
76463790bfSBill Wendling 
77463790bfSBill Wendling struct enum_decl_test t13 = { BORK }; // Okay
78