Skip to content

Commit

Permalink
[Support] Workaround a GCC 4.8 bug on constant expression evaluation.
Browse files Browse the repository at this point in the history
Summary:
- The following stripped code trigger a gcc-4.8 bug. To work that
  around, move the alignment evaluation into template parameter.

```
// https://godbolt.org/z/58p5_X
//

enum { aligned = 0, unaligned = 1 };

template <typename T, int alignment> struct PickAlignment {
  enum { value = alignment == 0 ? alignof(T) : alignment };
};

template <typename ValueType, std::size_t Alignment> struct packed {
private:
  struct {
    alignas(
        PickAlignment<ValueType, Alignment>::value) char buffer[sizeof(int)];
  } Value;
};

using ule16_t = packed<uint16_t, unaligned>;

ule16_t x;
```

- Also, replace `alignas` with `LLVMALIGN_AS` to improve the compiler
  compatibility.

Reviewers: jfb

Subscribers: dexonsmith, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D65452

llvm-svn: 367329
  • Loading branch information
darkbuck committed Jul 30, 2019
1 parent 5ed3d14 commit 0d6615c
Showing 1 changed file with 3 additions and 3 deletions.
6 changes: 3 additions & 3 deletions llvm/include/llvm/Support/Endian.h
Expand Up @@ -205,7 +205,8 @@ namespace detail {

template<typename ValueType,
endianness Endian,
std::size_t Alignment>
std::size_t Alignment,
std::size_t ALIGN = PickAlignment<ValueType, Alignment>::value>
struct packed_endian_specific_integral {
using value_type = ValueType;
static constexpr endianness endian = Endian;
Expand Down Expand Up @@ -247,8 +248,7 @@ struct packed_endian_specific_integral {

private:
struct {
alignas(PickAlignment<value_type,
alignment>::value) char buffer[sizeof(value_type)];
LLVM_ALIGNAS(ALIGN) char buffer[sizeof(value_type)];
} Value;

public:
Expand Down

0 comments on commit 0d6615c

Please sign in to comment.