nicocvn / cppreg

A C++11 header-only library for MMIO registers
https://nicocvn.github.io/cppreg/
Other
60 stars 6 forks source link

Fails to compile for PowerPC GCC 4.8.5 #2

Closed hak8or closed 6 years ago

hak8or commented 6 years ago

As of 5cf8a851d879d96790d26dadd9cc5ca2af38874c it seems we fail to compile on PowerPC GCC 4.8.5 according to GodBolt as shown here.

with the following compiler error:

<source>:138:40: error: redeclaration 'cppreg::Shadow<Register, true>::use_shadow' differs in 'constexpr'
     const bool Shadow<Register, true>::use_shadow;
                                        ^
<source>:133:37: error: from previous declaration 'cppreg::Shadow<Register, true>::use_shadow'
         constexpr static const bool use_shadow = true;
                                     ^
<source>:138:40: error: declaration of 'constexpr const bool cppreg::Shadow<Register, true>::use_shadow' outside of class is not definition [-fpermissive]
     const bool Shadow<Register, true>::use_shadow;
                                        ^
Compiler returned: 1
sendyne-nicocvn commented 6 years ago

Godbolt

hak8or commented 6 years ago

If the issue is that other compilers were not error-ing when they should be, maybe it would be worthwhile to file a bug report for clang and a regression in gcc? A simpler case would be needed though, in which case I would suggest creating an issue for it.

On Feb 22, 2018 5:04 PM, "Sendyne Principal Scientist" < notifications@github.com> wrote:

Godbolt https://godbolt.org/#z:OYLghAFBqd5QCxAYwPYBMCmBRdBLAF1QCcAaPECAKxAEZSAbAQwDtRkBSAJgCFufSAZ1QBXYskwgA5AHoZYMAGpkABxXFMwRQzwAjYk2IBPAHQcADAEEZAKhsXLim4oACAMzwNMin79XrNAFomBgYTBAcnVyYRAgQSX0UAOTw0ZkFFAGFmEQA3TB0WRQgWZBz8wpdBTBZ0IxZMEzQAWwBKSOcXNBUjYjxgBAIs1B6%2BgaGuc1pzQMnaAA5FAGUauobh4hUTRUtQxTHBjI1q4nz0MysnGQcbrgBmPFKGESxFDjvM5EECfBYCd%2BwtweTxe3nemQIRhUmAA%2BgQDIRBACgY8yqC3h83CJSgQ8KgWCFkVYHHJlGoNMAYQARTAeBqCcIoty1WlZAAKbIAStgAOIwzIc7l8qnYABiAEkktgljCABJArB07wCrm8/mCtUiiVSmXyqwE5qYQQqJgSMkBLQcADsfEuvhEgkeWks6HQx0EcIxVMU33QIBAIkeBBU8Lh71tjntjrYigA6nh0HFPe9vb7/YG/vMw3cI4kHU7FAB5NxuaoEZN3VM/dNBrP/HM3K1UoGrPBuHw3KykyzICSCQRs1A6ZCmCLE%2B5tlntlVCmGWTKZaVLNmFgAy4syAE05QraY9lRq%2BfPF0tl2uN9u9ZYDUaTWb/BS3jbIr5vsQRMghhomOgYfiGEYT65okvgEJgzQqMwYEYhCUI1EwhqKAAskh4qFnCpCKJC0I3ooAAqRKRiBiiPIU3jfEwuLIPh%2ByYD%2BEBoCw3zIah6EEM4jHMc0zR4jCWC5KkmCkC%2BxGiWJxGcUMeGKM0TCCAA1sJdriSpYmSUWJZlp6qCaZgBCtIoLCoJgAAeEghkBIniRoBBiEUFFUTCyByfWmQEXc2BQDY3G8fxglvFwABsMlyfJBnIh5ig6aWentA2ykgdazbxURT7JcBPhvh%2BX50b%2BADufTQSAtE/n%2BLAAZZCWJGBEFQWCHzYfBiEoWhGFYXBuHuYCVW%2BKR%2B4%2BgQlGpIouSoAmigFYQmAQC1bEcfiXE8agfGYAJEhKalqlbRJC1SSFCkbdtR07UxQzFjF5ZDNFZaHcdd3KLtNG5CEIiYAZRmmeZQzWhl4neUtK1rfVVZDcgTkueCXVeT5y1%2BWa3DBQAfrJCnhVamRWfdWO%2BFAz3PPVGMfFFun6QFwUo2FcW/YkSXhpjoHgZBlEE41uGzW1rMId4XX0z4fXrA5w2jeNZYzaxcLzadMkA3DQkPVL0kU%2B0PU%2BB9ZmYBZP28yB/2%2Bat/kpgNoPg98kMAtDMv6xIaOZPtYV0yraUO5tDO1czMGc814sEJhnvc4RYn8%2BRg1USNY3oMoXiGGLrXsfLi160DmHqYroXKy7qvGermvPo7iS67DVvA0bjnOabHxQxABeA4J4VBYoyNp87Ym0ylYk1Uz0Hgn7LGx77HVc/hAeiUHJdC%2BHWGoMAwBeDHc3x0MMM1%2BtC80Ur2tq19lUZzrS%2By16Y9g2XrmV9XsvhQArNgdtU9rre/ffVlZZ%2BE2FbC/6AVrjsd3VHsD17fd2o4UHjzR2o9BbUWFhHSaYE54S1XnvIut1sZbRTnbZBKCVLqXOlpK6JMMGYLUo9aSeNXrvSzlvL%2BO986IKBgfXGL0CbgmJhdOu5Mm5t1Eo/BK3DLC03HHcVs7Y3jEi7DIfCCICAMjHHwiczJFTslVHyPCnJLDijwrqXcSpFGzhUWojRO59Rc2NKabwD5NDb2qozX%2B4J4yJgQJ6JYeAABemBh6ZXhNlRQnJNB4G%2BJgYgeE4LN1dp3JhkVn5DB8cAPxYFAnBI%2BPMEQAIgKKHzDGRqB80wBlrNmHgTtOE%2BB/u7cEKTIneN8f4%2BJ0JwS0ECskyKP00nRi0Jkw22SMwEDqXkgpv1ildw%2BGUzxL9omxICUEmpHw7hcAadfJp6TWlwSydWHJfxpk9N4fw2Rgjahtg7KI6w4jCz5GIG4BgqA8qMgEZOBRM41SFgAGrYE5KKVchZYyGO2Yqfqdy%2BSPOea895nybwmPvOSCxVCQV3m8EGAJBIGAZCoVYt2AyMaOzsUmIYsYCGgX/t4UZVSJluI%2BLGAE/pMmkKEtrHuBK4lEtsWSkAmSdA8X%2BDwjyT9hlDGQAgTAyB5J/hOWci5ljRILNooIEQDBvqVmpXigafoQCwuAAYBgTldqsFcroVAQ5MKUpgobFlhBGWNRCR2JszstlWvuEI/ZfCxHIVClc7ZNzWS/JhEhSwSwADSnzuB3G%2Besd1nqfXAuMdC80j4kWhJsQ1eVSFQrZm6qlSSpl1COoUp6WS8lYQUwYo9DFDihh5QTHEchn0NbfVzjvGydkJqloQF6Q25gMSim1qJcwyS873RAO24iECTauQTZm%2Bsnk%2B3iQgNm3NoVwTDoFaOiAha4QQBLfYxQgRFC0FaOFQZRMt1PltrQcdiRb48ItYUrC1iSlxuAc1RNo6rKppMumudWamA5phIIBAbYwK/jzepJdxaG04sIapbBJNtIk3LdnKt1NfC1uIPZEOqRB2zvvebKdMIKZoZHebVdZaDVE2urFM1vTGzNgEbakR9rDnLAQD%2BC5DzGHOv9a66ch4YRLFlJYKk7yHmWFXAAVWwH6%2B4gaDxKM49x3jsZ%2BNCZE1eKFpjI0QurcisJf9b34sqXEzC2qhyKEE9UJY9H0AXPcQNd8L8TMMbyqKk6/jn3EEPqvfTDBmmwi/bZg%2BbgQjVFI7w9TsbYJaYqTEqpFnyk2bM3lcEtKAm%2B3fMSuZanRIQKAU1bT4W4nkqWZS0jiQn3pvS%2BpNzHnP2mZFYbTxxKH7nr6Ve1FNKdMBIs817LATcvQjo7ZuLLWyBYSS4y/Vht4vEH9McPSlqLWUd2cIzstGkIBOAJgWMb8WNyKnDotUSFnk8mwLGTk6iFNaJ%2BRx3bnJ9uHeO2Gw0oKzHgstKlopjWWbyrGxZsockMhLeICttbU17OKBUCIXQw5e2O3FboOSsI2mVgy7hMbXXava3S79/7b9lDfjAjCR4FFSjTVKzDuEeXGEgdA6gx60Pqgk%2B60rQyFDK1A7Euj1bmPmixYvWJDnJgYSmmQCIZoUrma/hG/D/LXPRI8/Vc0XQ%2B4/2hQPthyXxEENFA5wV3wgXRKs4B7A3Xb8EYIxknlaDX1j3FT572QXwvf0wkpZOy5VuBdC7qqLxhrRyfERl3LhoCuFKO95y0X3mB/dhWZ1r%2Br2sDdTXzVLGPYEEY7u9FgLwieVfIWW2zqaxuRgBMoiQFMcfmIJ7cUFZPihU96RR47RGpeIBozg8RdrYzxsgHZnHdStCDayu7cRJHIBiB5Sw%2BBGEKgxp/ACQ3zXxEz5F2WcbY%2B4Jqew4SWOvvIEq7d/hvXRGPv5dYbTge49iQoDO5t27%2B3HuyaKH337w/qNj2np3tr5vr3NOZcUG2jljtS9G/riWnEMXkMCvrTt4JSmwsbpvEztGipAOt9gEgQBANkn4p%2BlzKUhvljD3KKP6CaBoH8DCBSK3l7pgh9pgRThiNgP6JSiQXdNwFwB4AUBHH4gzkMG4MQKgM0FhLyj6IPEQVUiROrlnjCDAmXlwM/ltDgSAOPsOEYP6KIRAAjOfq7iLlfvjLQVjFIRTBofdFIcRj7CfndBATPiBHfqHg/vJAfGYWHgel/v6Mrk3iBGrgqvYagPkFXHEH4hIVwlHt/O/hgdQriqFqKBoaARSmTsej3NJIbH/o7BZtVPKtkvBGDrCG2AEVtBALCohn5v6DynygKm4QEsKpzmioEf3v1v6I6K4nqmTsUFoYrhFNfHoVBoYRToyscFKgQNQR7hoQROQfdCasEkFEbo7IAQgA3mTFAYzjnI4YkM4dks0IUR4d%2BoIK0CYP0t4GMeCN/p5MYRnq/sDn0M9GBBDjvPAf2IgRAAoAPl5jFumDTrcRcjoeJPQYaH9psZjiwUZEMEwM9J4EwCkYoG4AkI8XZvqvwXEvQd4cRPXgZJbvzhfqoQ7p2p7q0WJNYRYRACiZZL4TvGEUssobbuYRLo4fid1hiQ4VZJsjNtslRgtqSGNhtg8PIm6hxkKOKEsHhM8qJgGnuEGmybyByVyZyLdreMpuYk9g1iikwo7C6G6EaB6FEpoHKe6OToBmFoWuTi3oSgkpkNEoWoMd1j4mWExvjAfOYCZOYOTmVkZpgNFlVvDr5gim4uysmokOUmNhHj4OKnDt6NqXSrqfqQ2oaTXjvOKh3gfKNFBJ4N4KahnkVs5iVo9CqQqZ6KAT%2BPKf2AfNEimf2CYQmS5gBg2p6FUcXEGfYvmbtGmomchtROpJkpNjKt6MaXpKaa9CYeKqCQfPaSUWNphLaT2RFI4Wjt7M4EPiPs0GPhPnEhMbAdZHpHWhoFkQEOWEvh8B3pLOXJ5Oma6O6NCYlLiWJEmfHqOfsMtIaJOePlkbOc9vObZIhrRMuTZKhh8OpBuQvObDuZmasSYQcUFteiFp/jsdrOArWZnu8XrsSoBbhFIXgTUOWBCa1j/jvG8StiIW/MAQjoPFIeEfjGbjAbeWJGrmiX/jekBbgYYPBYQf1vEapLkdjqkadKwBIFABAGLoTLbM0awjfvUajJhLxfbPsYeaJBsQahvtgRobha9JJfKtEfDqRdBdhRRfgQhTRchS3OpSPOVP1BAnKqFkkQSCkbjm4OkapFkfCoILkbyvyoKkUeciUWiaWTUeoXUfYQ0RypFFxWWOnBQVtO0UaJ0d0eocen0WUSgiGdrKhbCAofhTMcesRf0eBRjjnmRTBcpVRYhcQLRSpPRXRDjnjoNATqxexcwl5bFDxW5XxXYSAOvEJelKjrWXzhccQEgeWXEIoAoM2iIM8S3FwFwIGgWEwGFq3hlsTPWmup2iRBkN8YoCEPZaHlCQFridajsvgPNgcqSKKHgEwUyWxttnyOyZyQCuKNgKuFSDyeJvtTCIdcKRKKdedYpuGuKY9kDqJaZc3vKjwDDn2drOqVtUwZqdrDgnpJ6P9QwOgMDQYd/PKj2H2AOEOKkEYFSZpR4lZkMGDRHHOXmC0sDpRQQZlQfF9dUB9hnj6UstVvKnBfjRUUygko4eGd7AfD3FTapR1m3h3pWadNWYWQWsWUBmuobBjQafGVWU5jzVLJDZBhdAfBjZDR2TjTIYjQfLDQqYOLIZzY5sVmBfWUshTEru%2Bp5t%2Bm4HbsroBXhsBmib5RQfofuf%2BU1qTvjNlZZl4nkTZYUacvZV6SBAWcecxGVh0dKk2oleZTkSgNZQUUKvZe9fdCzdRWzZUS4lSolYkDQZbTjHrY0Swt5WnaBv5ZKtKkFe2XVSYaBaDKNd%2BOgBMdAXFRvglWFYkCrf2GrYjRNrlBALHZlRNueaPleZPsQA3j1SgtoTnXdDbb%2BcJW/tKR/p1EzWviBdpQLGBVAtrAoTrfpSsskV4MZdHWJAoB3TTaCfcYbbZphKFVbXQR5MjiNNftXbBseo3fDbIfIRhfvfHYPsPheVOdeaicncdMPb/UdPoYPUYR7uPfVX4VPd3LJbPZMm6VpWRC5svaMRhWvZ/gZQCVvWkYMhvq/a3pUZVnlEfRVifUPAA20ZfbTd1hAQzhWjXWFbg1Uvg7ZoXcDGie3XjazXgyAIfSACNrvvTtaKUXdAwmaaUkRlBjfrVbMb4A/c3SOM/bHgwzlu/ROV/X3QPSPVtIjFiSID/fXdjJ2sA8dEo51twwQyw7bZHuAzvG9WRdfS5VEZGeHE7aXVRHpWgxvYZZgyZdg2FVcWACY23jww6MfTFj5apP/oFMeq7RHXZeZh8BLlQYPgFdKr0ZoypBFcg7HrFXfRvgoXsY4X%2BTGgBVJXLI44bMvSjSBK46kO47hOg0ZVg0I6pIE0w3cQGA8QQ8epE9E%2BHbZR7fE5kIk63fnVDWFWfefR2BQ6alk7Ajk17YkPk6A8XRnjU5AhPKLPM1jaJLIwjfI9w3pOwypXHVw%2BOZ/b3TOZ7jfGAyXQvcHGXVApHHRP3Vs4RTs72KrXs3ISgFHP3a0yo%2Bc9OVPlc1I3fBPdU3c4gxPEQNPLPK89Iz4Ls0/UylPDPNNP82cz3UCy85hKC3EeC3bW9qFnJd6G5i45C%2Blj3A0949sdteDYWk2vDvQEPNM8EmAh6JszQzBgs/BguQ%2BRABja3fRMnobLQLozcxnrY4pYhCS4oGS1U4kGs1hYhNS6kT45kELQ2oy96My11MjiBR6GUM81XdMbk2Fc4QK3S4qhXbObKvDiiRK8OY1QgS1UcxlQfYnZQYbPhggEYzTH1YweDeNe1SwcwO8c5nEKwLjSpbRGzT6InYtRnucScEgf86WV6/Dj6wFPkkA%2Bk/Qfodm8G42qG4YCthG/RkUCzbGyNaWYm068bC60gZq2up1fa91Xm31QNTGENRjaNTpEW4oJNV8agD8aEBcgtX1fudSRRrSXNnag4FIJ7gwNIBfFIKQCwNIOYGu6gNIBjLwPwD6KIOIGCPcLQGu10VIFu9uqQPJCAAACwXwmB3C0BcBWh3tTBBRTDzC0B3uMDSB3trsbuXvbvSBruWVWkXtXukBwCwBIAtAqAxlkAUD5oQSIfSEqDIDAB3vzCkAeDSoBKWUQC6Cbtru%2B6GByFSBnukAtCGh/CFjlQUdbukBYCyRsBeAkfMd4AaCfh4D5CWXAekCmR8qxCSCUdruwrLsCfwh4DNAkdLusDsD8D8CMB6CWWQCe4jC4gLTSCBC%2BgpicD7u8C0BUfCBiASB0BLsruAccc7tSCDh5QBJsi2zAC9iKB3smDzAmAXzFC4CEAJD%2BrMuZCcEIdeDOYBcGR7t8C8Dntyee63sXzueBTzBWhcAXwACcyXdwGXCwgUgUf7UgAH67NnoHQgIAEHsX%2BXXA1nAntnMXwH17Jyjo%2BI97QAA%3D%3D%3D

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/sendyne/cppreg/issues/2#issuecomment-367838181, or mute the thread https://github.com/notifications/unsubscribe-auth/AA5gCqyCPO7JZy32qkCA_wcsjoq2XuK2ks5tXeSCgaJpZM4SPxFh .

sendyne-nicocvn commented 6 years ago

This is a bit long ... my original explanation was inadequate so here is the full story.

Preamble

The issue is a bit more ... subtle (and unfortunately this manifests itself as a linking issue so godbolt is not a good candidate for investigating).

Consider the following code:

#include <vector>

struct NS {
    constexpr static const int n = 1;
};

int main() {
    std::vector<int> v(10, NS::n);
}

At first glance it should compile fine, but compilation with GCC or Clang (I only tested x86 and ARM) using C++11 or C++14 will fail (C++17 and above will compile; more on that later) because of an undefined reference for the symbol NS::n. A few remarks:

Now a few comments/explanations ...

In the original code:

int main() {
    std::vector<int> v(10, NS::n);  // ctor: vector(size_type count,const T&)
}

we take a const reference to NS::n and that is sufficient for it to be ODR-used [1]. And therefore the following from C++11 standard applies: If a const static data member or a constexpr static data member (since C++11) is odr-used, a definition at namespace scope is still required, but it cannot have an initializer. This definition is deprecated for constexpr data members (since C++17) [2].

So:

  1. This is why the original code compiles for C++17 and above.

  2. The following fix is required in the original code:

    struct NS {
        constexpr static const int n = 1;
    };
    const int NS::n;    // now it will be resolved during linking
  3. This also explains why std::vector<int> v(NS::n, 10) would compile without the fix: the first argument to the vector constructor is by value and that does not make NS::n ODR-used.

  4. Enabling optimization was fixing the problem because the const reference step was (most likely) wiped away.

Now let's go back to cppreg original issue.

Going back to cppreg

The issue was exactly about that.

This was the code prior to 11734b0bf48b926a5f25d8db9e5b8f471fb48e35:

template <typename Register>
struct Shadow<Register, true> {
    static typename Register::type value;
    constexpr static const bool use_shadow = true;
};
template <typename Register>
typename Register::type Shadow<Register, true>::value = Register::reset;
template <typename Register>
const bool Shadow<Register, true>::use_shadow;

The twist in the story is that the namespace scope definition of use_shadow was not due to cppreg. Some unit testing code (not part of the project) was taking a const rerence to use_shadow thus making it ODR-used thus requiring the definition.

So this is not a (re)definition nor a re-definition. And this is valid C++11 code.

Regarding the original issue:

A link to this discussion should be included in the code for reference purposes.

Question: do we want to support GCC 4.8.5? If yes, 11734b0bf48b926a5f25d8db9e5b8f471fb48e35 is a fix. If not, we should revert the change.

hak8or commented 6 years ago

Opened again because there is still discussion.

Fantastic writeup! I will re-read this later tomorrow to make sure I am understanding it correctly, but I am still not quite clear on why the discrepancy across GCC versions even though the same flags saying to use C++11 were used. Is it due to a differing interpretation of what you copied from within 9.4 Static members [class.static] across the GCC versions?

Since I see the fix (11734b0bf48b926a5f25d8db9e5b8f471fb48e35) has been committed to master, I assume everything is still compiling and therefore the mentioned side effect does/did not present any large issues regarding unit tests?

GCC 4.9 seems to be from August 3, 2016 and GCC 4.8.5 is from June 23rd, 2015, so it's not that old, and therefore I do think it's pertinent to have it working. Furthermore, as you said, use_shadow is for internal purposes only, so this change wouldn't be considered breaking anyways and therefore I say 11734b0bf48b926a5f25d8db9e5b8f471fb48e35 should be kept.

sendyne-nicocvn commented 6 years ago

Since I see the fix (11734b0) has been committed to master, I assume everything is still compiling and therefore the mentioned side effect does/did not present any large issues regarding unit tests?

No significant issue. The only one was (Googletest is used for unit testing) related to a test using:

EXPECT_TRUE(some_reg_with_shadow::shadow::use_shadow);

Under the hood EXPECT_TRUE evaluates to a type named AssertionResult which will copy construct from a bool (and hence taking a const reference and hence triggering the linking error). This was fixed with:

EXPECT_TRUE(bool(some_reg_with_shadow::shadow::use_shadow));

This performs a lvalue-to-rvalue conversion and therefore use_shadow is not ODR-used anymore.

Is it due to a differing interpretation of what you copied from within 9.4 Static members [class.static] across the GCC versions?

I am not really sure. There is the exact same issue on SO here. And the latest recipient of the Draper prize agrees that our code prior to the fix is valid.

However ... a glimmer of hope.

This:

struct NS {
    constexpr static const int n = 1;
};
const int NS::n;

fails to compile with GCC 4.8.5 (Godbolt) but the error message complains about the fact the re-declaration differs in constexpr-ness. So this is apparently bogus and we also know from the discussion above that this is valid code.

The fix is:

#include <vector>

struct NS {
    constexpr static const int n = 1;
};
constexpr const int NS::n;

int main() {
    std::vector<int> v(10, NS::n);
};

This compiles and runs with GCC 4.8.5 (Clang was always fine by the way).

This will be implemented shortly and tested.