[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / Sema / init-randomized-struct.c
blobd421597fa522f3e9093d6330671ff0532645cc48
1 // RUN: %clang_cc1 -triple=x86_64-unknown-linux -frandomize-layout-seed=1234567890abcded \
2 // RUN: -verify -fsyntax-only -Werror %s
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.
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:
15 // - A structure with only one element, and
16 // - A structure initialized with "{0}".
18 // These are well-defined situations where the field ordering doesn't affect
19 // the result.
21 typedef void (*func_ptr)();
23 void foo(void);
24 void bar(void);
25 void baz(void);
26 void gaz(void);
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));
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}}
43 struct other_test {
44 func_ptr a;
45 func_ptr b[3];
46 func_ptr c;
47 } __attribute__((randomize_layout));
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}}
55 struct empty_test {
56 } __attribute__((randomize_layout));
58 struct empty_test t10 = {}; // Okay
60 struct degen_test {
61 func_ptr a;
62 } __attribute__((randomize_layout));
64 struct degen_test t11 = { foo }; // Okay
66 struct static_assert_test {
67 int f;
68 _Static_assert(sizeof(int) == 4, "oh no!");
69 } __attribute__((randomize_layout));
71 struct static_assert_test t12 = { 42 }; // Okay
73 struct enum_decl_test {
74 enum e { BORK = 42, FORK = 9 } f;
75 } __attribute__((randomize_layout));
77 struct enum_decl_test t13 = { BORK }; // Okay