Add UNREACHABLE macro #26504

pull hebasto wants to merge 3 commits into bitcoin:master from hebasto:221115-enum changing 33 files +107 −81
  1. hebasto commented at 12:47 pm on November 15, 2022: member

    The UNREACHABLE macro was suggested in #24812, but during reviewing it has been dropped:

    This is unused and on a second thought I wonder if there is any value in it. The current code can already use assert(false) just fine. Introducing another way to write assert(false) will just lead to bike-shedding without any benefit.

    This macro prevents compiler warnings – -Wreturn-type (GCC) and C4715 (MSVC) – when building for/on Windows.

  2. hebasto commented at 12:47 pm on November 15, 2022: member
  3. DrahtBot commented at 0:16 am on November 16, 2022: contributor

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    Concept NACK fanquake
    Concept ACK aureleoules, MarcoFalke

    If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #27385 (net, refactor: extract Network and BIP155Network logic to node/network by jonatack)
    • #27231 (Fix logging RPC and -debugexclude with 0/none values, add test coverage, improve docs by jonatack)
    • #26697 (logging: use bitset for categories by LarryRuane)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

  4. in src/util/check.h:104 in 05ffaf4591 outdated
     99+ * UNREACHABLE is a macro that is used to mark unreachable code. It aborts the program.
    100+ * This is used to mark code that is not yet implemented or is not yet reachable.
    101+ */
    102+#define UNREACHABLE()                                                                                                                                   \
    103+    do {                                                                                                                                                \
    104+        std::cerr << format_internal_error("Unreachable code reached (fatal, aborting)", __FILE__, __LINE__, __func__, PACKAGE_BUGREPORT) << std::endl; \
    


    MarcoFalke commented at 9:12 am on November 16, 2022:
    Maybe move the implementation/formatting to the cpp file?

    hebasto commented at 9:16 am on November 16, 2022:
    Is it worth for a line of code?

    MarcoFalke commented at 9:29 am on November 16, 2022:
    No, but maybe for the dependencies: tinyformat, config, stdlib. See #25112

    hebasto commented at 12:33 pm on November 16, 2022:

    This approach requires that libbitcoinconsensus.la being linked against libbitcoin_util.a. The latter, in turn, must be converted into a Libtool archive.

    Therefore, I’d prefer to keep this in the header.


    MarcoFalke commented at 12:42 pm on November 16, 2022:
    It can also be treated like support/cleanse.cpp, at least that way the dependency on the macro is obvious
  5. aureleoules commented at 12:25 pm on November 16, 2022: member
    Concept ACK
  6. fanquake commented at 12:26 pm on November 16, 2022: member

    ~0 - agree with the earlier discussion in #24812. Why do we need to redefine assert(), because Windows compilers are broken? We’ll have an unintuitive split where assert() is used, except in a switch, because we’re trying to suppress randomly (the warnings aren’t emitted consistently from switches with mingw-w64) happening warnings.

    This will be another thing developers have to look up, rather than seeing assert(), and knowing what it means.

    If we were going to introduce an unreachable macro, we could at least use __builtin_unreachable (GCC, Clang, ICC). Of course MSVC doesn’t implement that, and instead has __assume() (not to be confused with our own Assume()).

  7. hebasto commented at 2:26 pm on November 16, 2022: member

    because Windows compilers are broken

    They are not broken, as they do not violate the C++ standard. Of course, the way how they consider warnings for int f(){ assert(false); } differs from other popular compilers.

    We’ll have an unintuitive split where assert() is used, except in a switch, because we’re trying to suppress randomly (the warnings aren’t emitted consistently from switches with mingw-w64) happening warnings.

    For non-Windows targets warnings are inconsistent between GCC and Clang as well (remove assert(false); statement to see it).

    If we were going to introduce an unreachable macro, we could at least use __builtin_unreachable (GCC, Clang, ICC). Of course MSVC doesn’t implement that, and instead has __assume() (not to be confused with our own Assume()).

    That could be like an implementation of std::unreachable from C++23.

    But the suggested macro is safer when it comes to handle, for example, non-defined-explicitly enumeration values, as std::abort is better than UB.

  8. hebasto force-pushed on Nov 16, 2022
  9. hebasto commented at 2:30 pm on November 16, 2022: member

    Updated 05ffaf4591911b3c19ce6ab347538642765190c0 -> 39d681e1c741880f96ef5c2f4c0ae2e93e5ddbcc (pr26504.01 -> pr26504.02):

  10. in src/util/check.h:98 in 39d681e1c7 outdated
    94@@ -95,4 +95,12 @@ T&& inline_assertion_check(LIFETIMEBOUND T&& val, [[maybe_unused]] const char* f
    95         format_internal_error("Unreachable code reached (non-fatal)", \
    96                               __FILE__, __LINE__, __func__, PACKAGE_BUGREPORT))
    97 
    98+[[noreturn]] void inline_unreachable(const char* file, int line, const char* func);
    


    MarcoFalke commented at 2:38 pm on November 16, 2022:
    nit: I don’t think this is inline. Maybe call it unreachable_fail for symmetry?

    hebasto commented at 4:24 pm on November 16, 2022:
    Thanks! Updated.
  11. in src/netaddress.cpp:691 in 39d681e1c7 outdated
    695@@ -695,7 +696,7 @@ uint32_t CNetAddr::GetLinkedIPv4() const
    696         // Teredo tunneled IPv4: the IPv4 address is in the last 4 bytes of the address, but bitflipped
    697         return ~ReadBE32(Span{m_addr}.last(ADDR_IPV4_SIZE).data());
    698     }
    699-    assert(false);
    700+    UNREACHABLE();
    


    fanquake commented at 3:25 pm on November 16, 2022:
    This is now also changing code that does not use switch statements, and I assume doesn’t warn under mingw-w64, becoming inconsistent with the rest of the codebase. If we are going to change some of these, we should be changing all, otherwise this is just random refactoring.

    hebasto commented at 4:21 pm on November 16, 2022:

    I assume doesn’t warn under mingw-w64

    It does when compiling with -O0.


    MarcoFalke commented at 11:18 am on November 17, 2022:
    There’d be test/lint/lint-assertions.py if this is a goal

    hebasto commented at 2:02 pm on November 29, 2022:

    @fanquake

    we should be changing all, otherwise this is just random refactoring.

    In that case, what macro name could be appropriate?

  12. hebasto force-pushed on Nov 16, 2022
  13. hebasto commented at 4:24 pm on November 16, 2022: member

    Updated 39d681e1c741880f96ef5c2f4c0ae2e93e5ddbcc -> dd47e2aaf869806455289d55222dd981ee8cea3f (pr26504.02 -> pr26504.03):

  14. in src/util/check.cpp:34 in 965f142dac outdated
    27@@ -27,3 +28,9 @@ void assertion_fail(const char* file, int line, const char* func, const char* as
    28     fwrite(str.data(), 1, str.size(), stderr);
    29     std::abort();
    30 }
    31+
    32+void unreachable_fail(const char* file, int line, const char* func)
    33+{
    34+    std::cerr << strprintf("Internal bug detected: Unreachable code reached (fatal, aborting)\n%s:%d (%s)\nPlease report this issue here: %s\n", file, line, func, PACKAGE_BUGREPORT) << std::endl;
    


    MarcoFalke commented at 3:59 pm on December 10, 2022:
    could rebase and use the existing string template?

    hebasto commented at 6:31 pm on December 10, 2022:
    Done.
  15. hebasto force-pushed on Dec 10, 2022
  16. hebasto commented at 6:30 pm on December 10, 2022: member

    Updated dd47e2aaf869806455289d55222dd981ee8cea3f -> 426d6bed7318ad38e0932498d3730af04993ca94 (pr26504.03 -> pr26504.04):

    To make this PR compatible with the recently merged #26645, the CopyrightHolders() and LicenseInfo() functions have been moved from clientversion.{h,cpp}' to util/string.{h,cpp}.

  17. hebasto force-pushed on Dec 12, 2022
  18. hebasto commented at 3:38 pm on December 12, 2022: member
    Rebased on top of the #26688 and drafted until the latter is being reviewed.
  19. hebasto marked this as a draft on Dec 12, 2022
  20. hebasto force-pushed on Dec 12, 2022
  21. DrahtBot added the label Needs rebase on Mar 7, 2023
  22. hebasto closed this on Apr 27, 2023

  23. hebasto added the label Up for grabs on Apr 27, 2023
  24. in src/Makefile.am:976 in f140ea5931 outdated
    972@@ -973,7 +973,7 @@ if BUILD_BITCOIN_LIBS
    973 lib_LTLIBRARIES += $(LIBBITCOINCONSENSUS)
    974 
    975 include_HEADERS = script/bitcoinconsensus.h
    976-libbitcoinconsensus_la_SOURCES = support/cleanse.cpp $(crypto_libbitcoin_crypto_base_la_SOURCES) $(libbitcoin_consensus_a_SOURCES)
    977+libbitcoinconsensus_la_SOURCES = clientversion.cpp support/cleanse.cpp util/check.cpp $(crypto_libbitcoin_crypto_base_la_SOURCES) $(libbitcoin_consensus_a_SOURCES)
    


    MarcoFalke commented at 10:44 am on July 14, 2023:
    Maybe drop this change and the one to src/script/interpreter.cpp for now and only use the second and third commit?
  25. MarcoFalke commented at 10:53 am on July 14, 2023: member

    Concept ACK on UNREACHABLE. I find it frustrating to play compiler golf against g++ in the CI on every code push that uses a switch-case on an enum class.

    First push is -Werror=return-type, the second push is Assert(false);, but g++ failing to understand it, then the third push is assert(false);

  26. util: Add `UNREACHABLE` macro
    Co-authored-by: Aurèle Oulès <aurele@oules.com>
    Co-authored-by: MacroFake <falke.marco@gmail.com>
    0ef8f1b78f
  27. MarcoFalke commented at 1:11 pm on July 14, 2023: member
    @hebasto Let us know if you’ll pick this up again or if you want someone else to do it?
  28. hebasto commented at 1:11 pm on July 14, 2023: member

    @hebasto Let us know if you’ll pick this up again or if you want someone else to do it?

    Almost ready :)

  29. hebasto reopened this on Jul 14, 2023

  30. hebasto force-pushed on Jul 14, 2023
  31. hebasto commented at 1:20 pm on July 14, 2023: member

    re #26504 (review)

    Maybe drop this change and the one to src/script/interpreter.cpp for now and only use the second and third commit?

    Done. Rebased.

  32. hebasto marked this as ready for review on Jul 14, 2023
  33. hebasto removed the label Up for grabs on Jul 14, 2023
  34. in src/net.h:495 in 5f7af01ae7 outdated
    492@@ -493,7 +493,7 @@ class CNode
    493                 return true;
    494         } // no default case, so the compiler can warn about missing cases
    495 
    


    MarcoFalke commented at 1:22 pm on July 14, 2023:
    nit: Can remove the empty lines in this file, and other files?

    hebasto commented at 1:58 pm on July 14, 2023:
    Done.
  35. MarcoFalke approved
  36. MarcoFalke commented at 1:24 pm on July 14, 2023: member
    Nice. Review lgtm
  37. MarcoFalke commented at 1:27 pm on July 14, 2023: member

    Looks like you forgot to include the doc change? https://github.com/bitcoin/bitcoin/commit/abacaef3f3b541ead566532eaae9f5db31ccb7ff#diff-5e319039d67254bed6ca82562ec5f560f102004aa4806e4ca77f5d0065c65fbb

    Also, could update title, description and commit message?

  38. in src/chainparams.cpp:15 in 5f7af01ae7 outdated
    11@@ -12,6 +12,7 @@
    12 #include <logging.h>
    13 #include <tinyformat.h>
    14 #include <util/chaintype.h>
    15+#include <util/check.h>
    


    jonatack commented at 1:39 pm on July 14, 2023:
    A potential downside with this change is the util/check.h code is added to a fair number of compilation units (unless the header was already missing). Also, it looks like some cases haven’t been updated. Maybe only use it for new or touched code going forward?
  39. jonatack commented at 1:42 pm on July 14, 2023: contributor
    If this is done, IIUC the developer notes should be updated.
  40. Use `UNREACHABLE` macro in non-RPC code
    This change prevents `-Wreturn-type` and `C4715` warnings when building
    for/on Windows.
    924f45d48c
  41. hebasto force-pushed on Jul 14, 2023
  42. DrahtBot added the label CI failed on Jul 14, 2023
  43. hebasto renamed this:
    Add `UNREACHABLE` macro and drop `-Wreturn-type`/`C4715` warnings suppressions
    Add `UNREACHABLE` macro
    on Jul 14, 2023
  44. hebasto commented at 1:59 pm on July 14, 2023: member

    @MarcoFalke

    Also, could update title, description and commit message?

    The title an the description have been updated. What update for commit messages would you like to see?

  45. doc: Amend enumerations chapter in Developer Notes 1544bae5a6
  46. in doc/developer-notes.md:851 in a87e153831 outdated
    848+    UNREACHABLE();
    849 }
    850 ```
    851 
    852-*Rationale*: The comment documents skipping `default:` label, and it complies with `clang-format` rules. The assertion prevents firing of `-Wreturn-type` warning on some compilers.
    853+*Rationale*: The comment documents skipping `default:` label, and it complies with `clang-format` rules. The `UNREACHABLE` macro prevents firing of `-Wreturn-type`/`C4715` warning on some compilers. In RPC code the `NONFATAL_UNREACHABLE` macro might be more appropriate instead.
    


    jonatack commented at 2:03 pm on July 14, 2023:
    0*Rationale*: The comment documents skipping the `default:` case and it complies with `clang-format` rules. The `UNREACHABLE` macro prevents firing of `-Wreturn-type`/`C4715` warnings on some compilers. In the RPC code, the `NONFATAL_UNREACHABLE` macro might be more appropriate instead.
    

    hebasto commented at 2:06 pm on July 14, 2023:
    Thanks! Updated.
  47. hebasto force-pushed on Jul 14, 2023
  48. fanquake commented at 2:35 pm on July 14, 2023: member

    Apparently, this macro prevents compiler warnings

    Either it does or it doesn’t? If it does, then any workarounds should be removed, and warnings re-enabled.

    If it doesn’t, there’s no point to this refactoring at all, if it doesn’t even acheive the stated goals.

    I find it frustrating to play compiler golf against g++ in the CI on every code push that uses a switch-case on an enum class.

    Which CI is this? The only one where it is an issue has the warnings disabled?

  49. DrahtBot removed the label Needs rebase on Jul 14, 2023
  50. MarcoFalke commented at 3:33 pm on July 14, 2023: member

    Which CI is this? The only one where it is an issue has the warnings disabled?

    I don’t use g++, nor Windows, locally, so this is a general problem of not knowing which function is marked noreturn by g++ or msvc internally. Having a macro that is known to work on all compilers is helpful, I think.

    I don’t care about updating the existing code, but I think having a macro for those that find it helpful, can’t hurt, can it?

  51. DrahtBot removed the label CI failed on Jul 14, 2023
  52. fanquake commented at 2:26 pm on July 17, 2023: member

    but I think having a macro for those that find it helpful, can’t hurt, can it?

    I agree that having a macro could be useful.

    Separately, note that upstream, the missing noreturn attributes have been added to assert in the mingw-w64 headers, https://github.com/mingw-w64/mingw-w64/commit/1690994f515910a31b9fb7c7bd3a52d4ba987abe, so beginning with 11.0.0, there are no-longer -Wreturn-type warnings with assert(false) usage. See #28092 where I’ve updated the docs.

  53. fanquake commented at 10:13 am on July 19, 2023: member

    I don’t care about updating the existing code,

    To be clear, I agree, and am still a NACK to any code changes here.

  54. hebasto closed this on Jul 20, 2023


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2024-07-03 07:12 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me