1 // RUN: %clang_cc1 -triple=x86_64-unknown-linux -frandomize-layout-seed=1234567890abcded \ 2 // RUN: -verify -fsyntax-only -Werror %s 3 4 // NOTE: The current seed (1234567890abcded) is specifically chosen because it 5 // uncovered a bug in diagnostics. With it the randomization of "t9" places the 6 // "a" element at the end of the record. When that happens, the clang complains 7 // about excessive initializers, which is confusing, because there aren't 8 // excessive initializers. It should instead complain about using a 9 // non-designated initializer on a raqndomized struct. 10 11 // Initializing a randomized structure requires a designated initializer, 12 // otherwise the element ordering will be off. The only exceptions to this rule 13 // are: 14 // 15 // - A structure with only one element, and 16 // - A structure initialized with "{0}". 17 // 18 // These are well-defined situations where the field ordering doesn't affect 19 // the result. 20 21 typedef void (*func_ptr)(); 22 23 void foo(void); 24 void bar(void); 25 void baz(void); 26 void gaz(void); 27 28 struct test { 29 func_ptr a; 30 func_ptr b; 31 func_ptr c; 32 func_ptr d; 33 func_ptr e; 34 func_ptr f; 35 func_ptr g; 36 } __attribute__((randomize_layout)); 37 38 struct test t1 = {}; // This should be fine per WG14 N2900 (in C23) + our extension handling of it in earlier modes 39 struct test t2 = { 0 }; // This should also be fine per C99 6.7.8p19 40 struct test t3 = { .f = baz, .b = bar, .g = gaz, .a = foo }; // Okay 41 struct test t4 = { .a = foo, bar, baz }; // expected-error {{a randomized struct can only be initialized with a designated initializer}} 42 43 struct other_test { 44 func_ptr a; 45 func_ptr b[3]; 46 func_ptr c; 47 } __attribute__((randomize_layout)); 48 49 struct other_test t5 = { .a = foo, .b[0] = foo }; // Okay 50 struct other_test t6 = { .a = foo, .b[0] = foo, bar, baz }; // Okay 51 struct other_test t7 = { .a = foo, .b = { foo, bar, baz } }; // Okay 52 struct other_test t8 = { baz, bar, gaz, foo }; // expected-error {{a randomized struct can only be initialized with a designated initializer}} 53 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}} 54 55 struct empty_test { 56 } __attribute__((randomize_layout)); 57 58 struct empty_test t10 = {}; // Okay 59 60 struct degen_test { 61 func_ptr a; 62 } __attribute__((randomize_layout)); 63 64 struct degen_test t11 = { foo }; // Okay 65 66 struct static_assert_test { 67 int f; 68 _Static_assert(sizeof(int) == 4, "oh no!"); 69 } __attribute__((randomize_layout)); 70 71 struct static_assert_test t12 = { 42 }; // Okay 72 73 struct enum_decl_test { 74 enum e { BORK = 42, FORK = 9 } f; 75 } __attribute__((randomize_layout)); 76 77 struct enum_decl_test t13 = { BORK }; // Okay 78