<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/97459>97459</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            The linux kernel expects initializers to FULLY initialize variables". Padding, other union members
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          yabinc
      </td>
    </tr>
</table>

<pre>
    This is a bug first reported in https://github.com/llvm/llvm-project/issues/78034#issuecomment-2183233517.
But fork it here to be clear it's not related to c23 standard.

The problem is about using {} to initialize a static variable with union type in the linux kernel (https://github.com/torvalds/linux/blob/master/net/xfrm/xfrm_state.c#L1142):

typedef union {
        __be32          a4;
        __be32          a6[4];
        struct in6_addr in6;
} xfrm_address_t;

struct xfrm_state* xfrm_state_find() {
  static xfrm_address_t saddr_wildcard = {};
}

Then the code uses all bytes of saddr_wildcard to generate a hash value.

But in llvm IR, saddr_wildcard only has its first field zero initialized, left bits are marked as undef.

@saddr_wildcard = internal global { i32, [12 x i8] } { i32 0, [12 x i8] undef }, align 4, !dbg !9

With some optimization flags (like -O2 with always_inline attribute), clang decides to replace the undef part of saddr_wildcard with undef or poison values (GlobalOptPass), remove instructions for using undef and poison values (InstCombinePass), and give a wrong hash result.

I also reported this problem to the linux kernel. Here is what Linus Torvalds replied in https://www.spinics.net/lists/netdev/msg1007244.html:

> In the kernel, we do expect initializers that always initialize the
whole variable fully.

> This is literally about "the linux kernel expects initializers to
FULLY initialize variables". Padding, other union members, you name
it.

> If clang doesn't do that, then clang is buggy as far as the kernel is
concerned, and no amount of standards reading is relevant.

> And in particular, no amount of "but empty initializer" is relevant.

In my understanding, the Linux kernel expects:
1) When an initailizer is used for variable, it expects all unspecified bytes (including padding) are initialized to zero.
2) It's not limited to union, but also other aggregate types: struct, array.


</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJykVk1v4zYQ_TX0ZbCGTEmxdfAh2dRtgAC7KFIsejIocSRNQ5ECSdnx_vpiJHntfGxRtBczEcnHNzNvHqlCoMYibkV-J_L7hRpi6_z2pEqy1aJ0-rR9aikABVBQDg3U5EMEj73zETWQhTbGPoj0VsidkLuGYjuUy8p1Qu6MOZyHT713f2EVhdxRCAMGIXfrTZJmQqbjh8p1Hdr4Sa42qUzTfLVeiuReJLd3Q4Ta-WegCC16hOigRKgMKg8UhVwHsI45GcWUooNKphCislp5PaNMv08tQu9dabAbQyrdEGEIZBsQ6zuxvufdZCmSMvQdQTFMpAoOypMqDcKRYguDJWchnnrkBMQWwZAdXuAZvUUDQm7-ISnR-YMymhMw7hJyVxpXCrnrVIjohdxZ5Dy91L6bhz3TwGUlZPq4WmVSyILBryJjMhrrmRoHM08W-32JqRRJIZJCZSL9ycyNyO8ykd9fLwjRD1UEsjd7pbUXSUH25rJgfQ8jOZ7DEPbxai__ztsvAQh5e_XfviarhdwIWVwIwznjr5Eh8J_7IxldKa9BpPdzxa7pvCn1VJrKaYQhYABlDJSniAFc_RYwOmjQoleRq96q0MJBmQFfyYelSBZYz_Dwu5Cf36I4a068GSiGuVVqQqPhO_prYWnea7COUPJK5RE65Z9RgwowWI31q3NFlnwQP9mI3ioDjXGlMpwPoFQytMjvVhJegDYi50TdnycheT89nseLeEoZaixk4yq50mXDQ3FN5ht3QHAdgusjdfRdRZZcbVQTWPqGnhE-fZFTqyhzVKewJ2vIIqgYPZUDK6HgIyqjbAMaK9IYuAYee6MqHAs38eqVjx_Ua-5DXuE89I6Cs1PFRhK_jin50sevKoT5MI-dO3DHTrokZwMby9z_E5ay-j3Ygw3xs-tKsngFx0sbOrBcjt7ZZhKNxzCY-Kp6D6BMcBfPjGyoZxeK7p1_LOE3tjkKcGxVhEeyQ4Cn2TXGDNFHzns8HpehJ0tVWE4GYijEMNmJxgMbTGhWSbKWWbZsY2feWIhIf4GHqWcmIhzlEUE7wJceRyM4C9gHiExuKu-1ZcYWJ7hj6wxejLMejDkt3553vlwMRfTKmNPsyULKd7Y6kQhvWLgJbPfH4-Of1zzOBwch5RK-Kq3JNhyRiy362Sc77Er0gT-f3ABWdTN5iu-oPtRnuToMVsh15MxwFnh7ZLuZ5inwTdmcuJdr5Xm45BQoTJCVsxV_0WctWQeqc4Od1D7fXlxvxcwZ1aPBg7Lvqd3aUQ_cKlQNRnnGfIUnpCyHCNj18XSdQCHlT5EfLHSnsS_8SGfOH8fy-EFdfqhpxYb-jfOh7HiWovEsPmgIqMemO5eHESn-qC1b9GBDjxXVrPLJroXckK3MMCaiP5eyGH3zylS5mdho5yj4loSHywPBUEfzA2GsPh_NSRm7c1KFahqPDd8BfJ9ySDCZxVgk79VrBS_0NtVFWqgFblfrVVFkN1JuFu223qSJxs2anzJFvlnVuV7dJJjkVV3nMs8WtJWJzJJ1IlebPJHrpSqKOi3zOk9ulEyqRGQJdorMki-bpfPNYnwlbYt1lhcLo0o0YXy0SWnxCOOkkJLfcH47PrjKoQkiS0YTuKBEiga3T_-yt-B_tdVi8Gb735-HU6iHrfw7AAD__5_gfeQ">