Skip to content

Commit a5617d0

Browse files
committed
Using unreachable, and adding assume
1 parent d482365 commit a5617d0

12 files changed

Lines changed: 79 additions & 48 deletions

File tree

include/mdcomp/bigendian_io.hh

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@
4646
#endif
4747

4848
#if defined(_MSC_VER)
49-
# define INLINE __forceinline
50-
# define CONST_INLINE __forceinline
51-
# define PURE_INLINE __forceinline
49+
# define INLINE [[msvc::forceinline]]
50+
# define CONST_INLINE [[msvc::forceinline]]
51+
# define PURE_INLINE [[msvc::forceinline]]
5252
#elif defined(__GNUG__)
5353
# define INLINE [[gnu::always_inline]]
5454
# define CONST_INLINE [[using gnu: const, always_inline]]
@@ -59,14 +59,6 @@
5959
# define PURE_INLINE
6060
#endif
6161

62-
#ifdef _MSC_VER
63-
# ifndef __clang__
64-
[[noreturn]] inline void __builtin_unreachable() {
65-
__assume(false);
66-
}
67-
# endif
68-
#endif
69-
7062
namespace detail {
7163
// Meta-programming stuff.
7264

include/mdcomp/lzss.hh

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include "mdcomp/bigendian_io.hh"
2323
#include "mdcomp/bitstream.hh"
24+
#include "mdcomp/unreachable.hh"
2425

2526
#include <algorithm>
2627
#include <cassert>
@@ -344,14 +345,9 @@ auto find_optimal_lzss_parse(std::span<uint8_t const> data_in, Adaptor adaptor)
344345
"Adaptor::desc_bits() is not noexcept");
345346
static_assert(
346347
noexcept(Adaptor::get_padding(0)), "Adaptor::get_padding() is not noexcept");
347-
constexpr auto assume = [](bool result) {
348-
if (!result) {
349-
__builtin_unreachable();
350-
}
351-
};
352-
assume(data.size() >= Adaptor::first_match_position);
348+
utils::assume(data.size() >= Adaptor::first_match_position);
353349
size_t num_nodes = data.size() - Adaptor::first_match_position;
354-
assume(num_nodes <= std::numeric_limits<size_t>::max() - 1);
350+
utils::assume(num_nodes <= std::numeric_limits<size_t>::max() - 1);
355351
// Auxiliary data structures:
356352
// * The parent of a node is the node that reaches that node with the
357353
// lowest cost from the start of the file.

include/mdcomp/options_lib.hh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#ifndef LIB_OPTIONS_LIB_HH
1919
#define LIB_OPTIONS_LIB_HH
2020

21+
#include "mdcomp/unreachable.hh"
22+
2123
#include <getopt.h>
2224

2325
#include <boost/io/ios_state.hpp>
@@ -85,7 +87,7 @@ consteval auto make_short_options() {
8587
intermediate[length++] = ':';
8688
break;
8789
default:
88-
__builtin_unreachable();
90+
utils::unreachable();
8991
}
9092
}
9193
return std::pair{intermediate, length};

include/mdcomp/unreachable.hh

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) Flamewing 2016 <flamewing.sonic@gmail.com>
2+
* Copyright (C) Flamewing 2025 <flamewing.sonic@gmail.com>
33
*
44
* This program is free software: you can redistribute it and/or modify it
55
* under the terms of the GNU Lesser General Public License as published
@@ -18,12 +18,44 @@
1818
#ifndef LIB_UNREACHABLE_HH
1919
#define LIB_UNREACHABLE_HH
2020

21-
#ifdef _MSC_VER
22-
# ifndef __clang__
23-
[[noreturn]] inline void __builtin_unreachable() {
24-
__assume(false);
25-
}
21+
namespace utils {
22+
#if defined(_MSC_VER)
23+
# define INLINE [[msvc::forceinline]]
24+
#elif defined(__GNUG__)
25+
# define INLINE [[gnu::always_inline]] inline
26+
#else
27+
# define INLINE inline
28+
#endif
29+
#if defined(__cpp_lib_unreachable) && __cpp_lib_unreachable >= 202202L
30+
# include <utility>
31+
using std::unreachable;
32+
#else
33+
[[noreturn]] INLINE void unreachable() {
34+
// Uses compiler specific extensions if possible.
35+
// Even if no extension is used, undefined behavior is still raised by
36+
// an empty function body and the noreturn attribute.
37+
# if defined(_MSC_VER) && !defined(__clang__) // MSVC
38+
__assume(false);
39+
# else // GCC, Clang
40+
__builtin_unreachable();
2641
# endif
42+
}
43+
#endif
44+
45+
INLINE void assume(bool condition) {
46+
// Uses compiler specific extensions if possible.
47+
// Even if no extension is used, undefined behavior is still raised by
48+
// an empty function body and the noreturn attribute.
49+
#if defined(_MSC_VER) && !defined(__clang__) // MSVC
50+
__assume(condition);
51+
#else // GCC, Clang
52+
if (!condition) {
53+
__builtin_unreachable();
54+
}
2755
#endif
56+
}
57+
58+
#undef INLINE
59+
} // namespace utils
2860

2961
#endif // LIB_UNREACHABLE_HH

src/lib/comper.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "mdcomp/bitstream.hh"
2323
#include "mdcomp/ignore_unused_variable_warning.hh"
2424
#include "mdcomp/lzss.hh"
25+
#include "mdcomp/unreachable.hh"
2526

2627
#include <array>
2728
#include <cstddef>
@@ -102,7 +103,7 @@ class comper_internal {
102103
case invalid:
103104
return std::numeric_limits<size_t>::max();
104105
}
105-
__builtin_unreachable();
106+
utils::unreachable();
106107
}
107108

108109
// Comper finds no additional matches over normal LZSS.
@@ -187,7 +188,7 @@ class comper_internal {
187188
// This should be unreachable.
188189
std::cerr << "Compression produced invalid edge type "
189190
<< static_cast<size_t>(edge.get_type()) << '\n';
190-
__builtin_unreachable();
191+
utils::unreachable();
191192
}
192193
}
193194
}

src/lib/comperx.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "mdcomp/bitstream.hh"
2323
#include "mdcomp/ignore_unused_variable_warning.hh"
2424
#include "mdcomp/lzss.hh"
25+
#include "mdcomp/unreachable.hh"
2526

2627
#include <array>
2728
#include <cstddef>
@@ -102,7 +103,7 @@ class comperx_internal {
102103
case invalid:
103104
return std::numeric_limits<size_t>::max();
104105
}
105-
__builtin_unreachable();
106+
utils::unreachable();
106107
}
107108

108109
// ComperX finds no additional matches over normal LZSS.
@@ -191,7 +192,7 @@ class comperx_internal {
191192
// This should be unreachable.
192193
std::cerr << "Compression produced invalid edge type "
193194
<< static_cast<size_t>(edge.get_type()) << '\n';
194-
__builtin_unreachable();
195+
utils::unreachable();
195196
}
196197
}
197198
}

src/lib/enigma.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include "mdcomp/bigendian_io.hh"
2323
#include "mdcomp/bitstream.hh"
24+
#include "mdcomp/unreachable.hh"
2425

2526
#include <algorithm>
2627
#include <array>
@@ -187,7 +188,7 @@ class enigma_internal {
187188
break;
188189
}
189190
default:
190-
__builtin_unreachable();
191+
utils::unreachable();
191192
}
192193
} else {
193194
auto const mode = bits.pop();

src/lib/kosinski.cc

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "mdcomp/bitstream.hh"
2323
#include "mdcomp/ignore_unused_variable_warning.hh"
2424
#include "mdcomp/lzss.hh"
25+
#include "mdcomp/unreachable.hh"
2526

2627
#include <array>
2728
#include <cstddef>
@@ -100,7 +101,7 @@ class kosinski_internal {
100101
case invalid:
101102
return std::numeric_limits<size_t>::max();
102103
}
103-
__builtin_unreachable();
104+
utils::unreachable();
104105
}
105106

106107
// Given an edge type, computes how many bits are used in total by this
@@ -129,7 +130,7 @@ class kosinski_internal {
129130
case invalid:
130131
return std::numeric_limits<size_t>::max();
131132
}
132-
__builtin_unreachable();
133+
utils::unreachable();
133134
}
134135

135136
// Kosinski finds no additional matches over normal LZSS.
@@ -200,7 +201,7 @@ class kosinski_internal {
200201
distance = std::streamoff{0x100} - source.get_byte();
201202
}
202203

203-
auto const length = static_cast<diff_t>(count);
204+
auto const length = static_cast<diff_t>(count);
204205
lzss_copy<kosinski_adaptor>(dest, distance, length);
205206
}
206207
}
@@ -264,7 +265,7 @@ class kosinski_internal {
264265
// This should be unreachable.
265266
std::cerr << "Compression produced invalid edge type "
266267
<< static_cast<size_t>(edge.get_type()) << '\n';
267-
__builtin_unreachable();
268+
utils::unreachable();
268269
}
269270
}
270271
}

src/lib/kosplus.cc

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "mdcomp/bitstream.hh"
2323
#include "mdcomp/ignore_unused_variable_warning.hh"
2424
#include "mdcomp/lzss.hh"
25+
#include "mdcomp/unreachable.hh"
2526

2627
#include <array>
2728
#include <cstddef>
@@ -100,7 +101,7 @@ class kosplus_internal {
100101
case invalid:
101102
return std::numeric_limits<size_t>::max();
102103
}
103-
__builtin_unreachable();
104+
utils::unreachable();
104105
}
105106

106107
// Given an edge type, computes how many bits are used in total by this
@@ -129,7 +130,7 @@ class kosplus_internal {
129130
case invalid:
130131
return std::numeric_limits<size_t>::max();
131132
}
132-
__builtin_unreachable();
133+
utils::unreachable();
133134
}
134135

135136
// KosPlus finds no additional matches over normal LZSS.
@@ -196,7 +197,7 @@ class kosplus_internal {
196197
count = ((high << 1U) | low) + 2;
197198
}
198199

199-
auto const length = static_cast<diff_t>(count);
200+
auto const length = static_cast<diff_t>(count);
200201
lzss_copy<kos_plus_adaptor>(dest, distance, length);
201202
}
202203
}
@@ -260,7 +261,7 @@ class kosplus_internal {
260261
// This should be unreachable.
261262
std::cerr << "Compression produced invalid edge type "
262263
<< static_cast<size_t>(edge.get_type()) << '\n';
263-
__builtin_unreachable();
264+
utils::unreachable();
264265
}
265266
}
266267
}

src/lib/lzkn1.cc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "mdcomp/bitstream.hh"
2323
#include "mdcomp/ignore_unused_variable_warning.hh"
2424
#include "mdcomp/lzss.hh"
25+
#include "mdcomp/unreachable.hh"
2526

2627
#include <algorithm>
2728
#include <array>
@@ -113,7 +114,7 @@ class lzkn1_internal {
113114
case invalid:
114115
return std::numeric_limits<size_t>::max();
115116
}
116-
__builtin_unreachable();
117+
utils::unreachable();
117118
}
118119

119120
// lzkn1 finds no additional matches over normal LZSS.
@@ -195,7 +196,7 @@ class lzkn1_internal {
195196
count = (data >> 4U) - 6U;
196197
}
197198

198-
auto const length = static_cast<diff_t>(count);
199+
auto const length = static_cast<diff_t>(count);
199200
lzss_copy<lzkn1_adaptor>(dest, distance, length);
200201
bytes_written += count;
201202
}
@@ -271,7 +272,7 @@ class lzkn1_internal {
271272
// This should be unreachable.
272273
std::cerr << "Compression produced invalid edge type "
273274
<< static_cast<size_t>(edge.get_type()) << '\n';
274-
__builtin_unreachable();
275+
utils::unreachable();
275276
}
276277
}
277278
}

0 commit comments

Comments
 (0)