lifting-bits / remill

Library for lifting machine code to LLVM bitcode
Apache License 2.0
1.22k stars 143 forks source link

Designated initializations in C++ files #658

Closed AlwaysPS closed 1 year ago

AlwaysPS commented 1 year ago

There are some heavy uses of designated initializations in remill/Arch/AArch32/Decode.cpp. For example, from line 1479:

static const char *const kHMulAccRRR[] = {
    [0b0000] = "SMLABB",  // (M == 0 && N == 0)
    [0b0010] = "SMLABT",  // (M == 1 && N == 0)
    [0b0001] = "SMLATB",  // (M == 0 && N == 1)
    [0b0011] = "SMLATT",  // (M == 1 && N == 1)
    [0b0100] = "SMLAWB",  [0b0101] = "SMULWB",
    [0b0110] = "SMLAWT",  [0b0111] = "SMULWT",
    [0b1000] = "SMLALBB",  // (M == 0 && N == 0)
    [0b1010] = "SMLALBT",  // (M == 1 && N == 0)
    [0b1001] = "SMLALTB",  // (M == 0 && N == 1)
    [0b1011] = "SMLALTT",  // (M == 1 && N == 1)
    [0b1100] = "SMULBB",  // (M == 0 && N == 0)
    [0b1110] = "SMULBT",  // (M == 1 && N == 0)
    [0b1101] = "SMULTB",  // (M == 0 && N == 1)
    [0b1111] = "SMULTT",  // (M == 1 && N == 1)
};

The thing is, designated initializations are introduced in C99, but are never a part of standard C++. This piece of code is preventing me from compiling from the source (with g++ 9.4.0).

pgoodman commented 1 year ago

Use #pragma GCC diagnostic thing to push a context and disable the error/warning.

AlwaysPS commented 1 year ago

Use #pragma GCC diagnostic thing to push a context and disable the error/warning.

I don't think that will work. g++ (which follows the standard faithfully at this issue) does not allow this syntax at all.

Consider the following simple program test.cpp:

int main()
{
    static const char *const data[] = {
        [0b01] = "0",
        [0b00] = "1"
    };
}

g++ test.cpp will simply give the following error message:

test.cpp: In function 'int main()':
test.cpp:6:5: sorry, unimplemented: non-trivial designated initializers not supported
    6 |     };
      |     ^
test.cpp:6:5: sorry, unimplemented: non-trivial designated initializers not supported

On the other hand, Clang does support this syntax (as an extension). One temporary workaround is just to switch the compiler (which is the default c++) to Clang.

pgoodman commented 1 year ago

Huh, TIL. Can you switch to using Clang?

If you're on macOS, then using AppleClang (the xcode command-line tools provided one) is the ideal.

duk-37 commented 1 year ago

In this case it's just a bad error message by GCC. Swapping the array initializers so they're in-order works fine. Still an extension but.. hey, who cares.

int main()
{
    static const char *const data[] = {
        [0b00] = "1",
        [0b01] = "0"
    };
}

Alternatively, just use Clang or have them as a comment next to each entry in the array.

ekilmer commented 1 year ago

FYI, we now test commits with GCC on Ubuntu 22.04 https://github.com/lifting-bits/remill/pull/672

I'll close this, but please reopen if you still have issues. Thank you!