Skip to content

Commit ff9845c

Browse files
kazutakahiratamahesh-attarde
authored andcommitted
[Support] Clean up Align (llvm#160644)
This patch cleans up the constructors and operator= of Align. - "constexpr Align(LogValue CA)" is a really strange "public:" constructor. It can only be constructed with a private struct LogValue, which wraps the log2 of an alignment. Since nobody uses it outside the class anyway, this patch moves the constructor to "private:" while switching to a tag-based parameter list. In turn, this patch removes LogValue. - The block of comment being deleted is no longer applicable, so this patch marks operator= constexpr. To test operator= in a unit test, this patch makes value() constexpr also. Refer to the unit test to see how operator= and value() are put together.
1 parent 14cc517 commit ff9845c

File tree

2 files changed

+16
-17
lines changed

2 files changed

+16
-17
lines changed

llvm/include/llvm/Support/Alignment.h

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,8 @@ struct Align {
5252
friend unsigned encode(struct MaybeAlign A);
5353
friend struct MaybeAlign decodeMaybeAlign(unsigned Value);
5454

55-
/// A trivial type to allow construction of constexpr Align.
56-
/// This is currently needed to workaround a bug in GCC 5.3 which prevents
57-
/// definition of constexpr assign operators.
58-
/// https://stackoverflow.com/questions/46756288/explicitly-defaulted-function-cannot-be-declared-as-constexpr-because-the-implic
59-
/// FIXME: Remove this, make all assign operators constexpr and introduce user
60-
/// defined literals when we don't have to support GCC 5.3 anymore.
61-
/// https://llvm.org/docs/GettingStarted.html#getting-a-modern-host-c-toolchain
62-
struct LogValue {
63-
uint8_t Log;
64-
};
55+
struct FromShiftValue {};
56+
constexpr Align(FromShiftValue, uint8_t Shift) : ShiftValue(Shift) {}
6557

6658
public:
6759
/// Default is byte-aligned.
@@ -70,8 +62,8 @@ struct Align {
7062
/// checks have been performed when building `Other`.
7163
constexpr Align(const Align &Other) = default;
7264
constexpr Align(Align &&Other) = default;
73-
Align &operator=(const Align &Other) = default;
74-
Align &operator=(Align &&Other) = default;
65+
constexpr Align &operator=(const Align &Other) = default;
66+
constexpr Align &operator=(Align &&Other) = default;
7567

7668
explicit Align(uint64_t Value) {
7769
assert(Value > 0 && "Value must not be 0");
@@ -82,7 +74,7 @@ struct Align {
8274

8375
/// This is a hole in the type system and should not be abused.
8476
/// Needed to interact with C for instance.
85-
uint64_t value() const { return uint64_t(1) << ShiftValue; }
77+
constexpr uint64_t value() const { return uint64_t(1) << ShiftValue; }
8678

8779
// Returns the previous alignment.
8880
Align previous() const {
@@ -94,17 +86,14 @@ struct Align {
9486

9587
/// Allow constructions of constexpr Align.
9688
template <size_t kValue> constexpr static Align Constant() {
97-
return LogValue{static_cast<uint8_t>(ConstantLog2<kValue>())};
89+
return Align(FromShiftValue{}, ConstantLog2<kValue>());
9890
}
9991

10092
/// Allow constructions of constexpr Align from types.
10193
/// Compile time equivalent to Align(alignof(T)).
10294
template <typename T> constexpr static Align Of() {
10395
return Constant<std::alignment_of_v<T>>();
10496
}
105-
106-
/// Constexpr constructor from LogValue type.
107-
constexpr Align(LogValue CA) : ShiftValue(CA.Log) {}
10897
};
10998

11099
/// Treats the value 0 as a 1, so Align is always at least 1.

llvm/unittests/Support/AlignmentTest.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,16 @@ TEST(AlignmentTest, AlignConstexprConstant) {
4444
EXPECT_EQ(Align(alignof(uint64_t)), kConstantAlign);
4545
}
4646

47+
TEST(AlignmentTest, ConstexprAssign) {
48+
constexpr auto assignAndGet = []() constexpr {
49+
Align A = Align::Constant<8>();
50+
Align B = Align::Constant<16>();
51+
A = B;
52+
return A.value();
53+
};
54+
static_assert(assignAndGet() == 16);
55+
}
56+
4757
std::vector<uint64_t> getValidAlignments() {
4858
std::vector<uint64_t> Out;
4959
for (size_t Shift = 0; Shift < 64; ++Shift)

0 commit comments

Comments
 (0)