https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68725

--- Comment #3 from Lukas Wunner <lukas at wunner dot de> ---
(In reply to Andrew Pinski from comment #2)
> I think this has now been fixed on the trunk. There is a pass which combines
> stores for constants.

No, unfortunately this is not fixed in trunk.

You're right that trunk uses 2 movabs instead of 16 movb instructions to
generate each GUID on the stack, requiring just 20 bytes instead of 80 bytes.

But that wasn't the point. The point was that constant compound literals
shouldn't be generated on the stack at runtime. They should be put in rodata
instead. That would be even more space efficient (16 bytes), more time
efficient, and also seems preferable from a security perspective: The compound
literals may contain function pointers and as such would be an interesting
target for attackers. Putting them in rodata reduces our attack surface.

The pretty-printed tree in test.c.003t.original looks fine:

{
  const struct efi_guid_t guid1 = <<< Unknown tree: compound_literal_expr
    const struct efi_guid_t D.2566 = {.b={215, 118, 49, 228, 232, 182, 39, 72,
183, 132, 127, 253, 196, 182, 133, 97}}; >>>;
  const struct efi_guid_t guid2 = <<< Unknown tree: compound_literal_expr
    const struct efi_guid_t D.2568 = {.b={29, 145, 250, 220, 235, 38, 159, 70,
162, 32, 56, 183, 220, 70, 18, 32}}; >>>;

    const struct efi_guid_t guid1 = <<< Unknown tree: compound_literal_expr
    const struct efi_guid_t D.2566 = {.b={215, 118, 49, 228, 232, 182, 39, 72,
183, 132, 127, 253, 196, 182, 133, 97}}; >>>;
    const struct efi_guid_t guid2 = <<< Unknown tree: compound_literal_expr
    const struct efi_guid_t D.2568 = {.b={29, 145, 250, 220, 235, 38, 159, 70,
162, 32, 56, 183, 220, 70, 18, 32}}; >>>;
  efi_print_guid_ptr (&guid1);
  efi_print_guid_ptr (&<<< Unknown tree: compound_literal_expr
    const struct efi_guid_t D.2569 = {.b={141, 147, 81, 249, 11, 98, 239, 66,
130, 121, 168, 75, 121, 97, 120, 152}}; >>>);
  efi_print_guid (guid2);
  efi_print_guid (<<< Unknown tree: compound_literal_expr
    const struct efi_guid_t D.2570 = {.b={44, 111, 179, 211, 81, 213, 212, 17,
154, 70, 0, 144, 39, 63, 193, 77}}; >>>);
}

But the gimplified tree in test.c.004t.gimple already generates the GUIDs on
the stack if they're passed by reference:

main ()
{
  const struct efi_guid_t D.2569;
  static const struct efi_guid_t C.0 = {.b={44, 111, 179, 211, 81, 213, 212,
17, 154, 70, 0, 144, 39, 63, 193, 77}};
  const struct efi_guid_t guid1;
  static const struct efi_guid_t guid2 = {.b={29, 145, 250, 220, 235, 38, 159,
70, 162, 32, 56, 183, 220, 70, 18, 32}};

  try
    {
      guid1.b[0] = 215;
      guid1.b[1] = 118;
      guid1.b[2] = 49;
      guid1.b[3] = 228;
      guid1.b[4] = 232;
      guid1.b[5] = 182;
      guid1.b[6] = 39;
      guid1.b[7] = 72;
      guid1.b[8] = 183;
      guid1.b[9] = 132;
      guid1.b[10] = 127;
      guid1.b[11] = 253;
      guid1.b[12] = 196;
      guid1.b[13] = 182;
      guid1.b[14] = 133;
      guid1.b[15] = 97;
      efi_print_guid_ptr (&guid1);
      D.2569.b[0] = 141;
      D.2569.b[1] = 147;
      D.2569.b[2] = 81;
      D.2569.b[3] = 249;
      D.2569.b[4] = 11;
      D.2569.b[5] = 98;
      D.2569.b[6] = 239;
      D.2569.b[7] = 66;
      D.2569.b[8] = 130;
      D.2569.b[9] = 121;
      D.2569.b[10] = 168;
      D.2569.b[11] = 75;
      D.2569.b[12] = 121;
      D.2569.b[13] = 97;
      D.2569.b[14] = 120;
      D.2569.b[15] = 152;
      efi_print_guid_ptr (&D.2569);
      efi_print_guid (guid2);
      efi_print_guid (C.0);
    }
  finally
    {
      guid1 = {CLOBBER};
    }
}

So it looks like the bug is in the gimplification pass. My guess is that
gimplify_compound_literal_expr() initially sets TREE_READONLY(decl) = 1, but
when gimplifying the function call this gets reverted to 0...

Reply via email to