1 // RUN: %clang_cc1 -triple=x86_64-unknown-linux -frandomize-layout-seed=1234567890abcdef \
2 // RUN:  -verify -fsyntax-only -Werror %s
3 
4 // Initializing a randomized structure requires a designated initializer,
5 // otherwise the element ordering will be off. The only exceptions to this rule
6 // are:
7 //
8 //    - A structure with only one element, and
9 //    - A structure initialized with "{0}".
10 //
11 // These are well-defined situations where the field ordering doesn't affect
12 // the result.
13 
14 typedef void (*func_ptr)();
15 
16 void foo(void);
17 void bar(void);
18 void baz(void);
19 void gaz(void);
20 
21 struct test {
22   func_ptr a;
23   func_ptr b;
24   func_ptr c;
25   func_ptr d;
26   func_ptr e;
27   func_ptr f;
28   func_ptr g;
29 } __attribute__((randomize_layout));
30 
31 struct test t1 = {}; // This should be fine per WG14 N2900 (in C23) + our extension handling of it in earlier modes
32 struct test t2 = { 0 }; // This should also be fine per C99 6.7.8p19
33 struct test t3 = { .f = baz, .b = bar, .g = gaz, .a = foo }; // Okay
34 struct test t4 = { .a = foo, bar, baz }; // expected-error {{a randomized struct can only be initialized with a designated initializer}}
35 
36 struct other_test {
37   func_ptr a;
38   func_ptr b[3];
39   func_ptr c;
40 } __attribute__((randomize_layout));
41 
42 struct other_test t5 = { .a = foo, .b[0] = foo }; // Okay
43 struct other_test t6 = { .a = foo, .b[0] = foo, bar, baz }; // Okay
44 struct other_test t7 = { .a = foo, .b = { foo, bar, baz } }; // Okay
45 struct other_test t8 = { baz, bar, gaz, foo }; // expected-error {{a randomized struct can only be initialized with a designated initializer}}
46 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}}
47 
48 struct empty_test {
49 } __attribute__((randomize_layout));
50 
51 struct empty_test t10 = {}; // Okay
52 
53 struct degen_test {
54   func_ptr a;
55 } __attribute__((randomize_layout));
56 
57 struct degen_test t11 = { foo }; // Okay
58