Skip to content

Commit 16c859b

Browse files
committed
Add proper abstraction for the inlined dynamic array inside the AbstractMemoryLocationImpl
1 parent f31fe83 commit 16c859b

4 files changed

Lines changed: 40 additions & 44 deletions

File tree

include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Problems/ExtendedTaintAnalysis/AbstractMemoryLocation.h

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "llvm/IR/DataLayout.h"
2525
#include "llvm/IR/Instructions.h"
2626
#include "llvm/IR/Value.h"
27+
#include "llvm/Support/TrailingObjects.h"
2728
#include "llvm/Support/raw_ostream.h"
2829

2930
#include "phasar/PhasarLLVM/DataFlowSolver/IfdsIde/LLVMZeroValue.h"
@@ -34,21 +35,14 @@ namespace psr {
3435

3536
namespace detail {
3637

37-
struct AbstractMemoryLoactionStorage : public llvm::FoldingSetNode {
38+
struct AbstractMemoryLocationStorage : public llvm::FoldingSetNode {
3839
const llvm::Value *Baseptr;
3940
uint32_t Lifetime;
4041
uint32_t NumOffsets;
41-
/// The actual length of Offsets is a runtime-constant determined by
42-
/// NumOffsets. Note, that NumOffsets can be larger than 1
43-
ptrdiff_t Offsets[1]; // NOLINT
4442

4543
protected:
46-
AbstractMemoryLoactionStorage(
47-
const llvm::Value *Baseptr, uint32_t Lifetime,
48-
const llvm::ArrayRef<ptrdiff_t> &Offsets) noexcept;
49-
50-
AbstractMemoryLoactionStorage(const llvm::Value *Baseptr,
51-
uint32_t Lifetime) noexcept;
44+
AbstractMemoryLocationStorage(const llvm::Value *Baseptr, uint32_t Lifetime,
45+
uint32_t NumOffsets = 0) noexcept;
5246
};
5347

5448
/// \brief A Memorylocation abstraction represented by a base-pointer and an
@@ -57,7 +51,14 @@ struct AbstractMemoryLoactionStorage : public llvm::FoldingSetNode {
5751
/// The byte offsets are applied to the base-pointer alternating
5852
/// with memory loads in order to represent indirect memory locations in a
5953
/// canonical way.
60-
class AbstractMemoryLocationImpl final : public AbstractMemoryLoactionStorage {
54+
class AbstractMemoryLocationImpl final
55+
: public AbstractMemoryLocationStorage,
56+
private llvm::TrailingObjects<AbstractMemoryLocationImpl, ptrdiff_t> {
57+
58+
// The factory is responsible for allocation, so it needs access to the
59+
// private inherited members from llvm::TrailingObjects
60+
friend class AbstractMemoryLocationFactoryBase;
61+
friend TrailingObjects;
6162

6263
[[nodiscard]] bool
6364
equivalentOffsets(const AbstractMemoryLocationImpl &TV) const;

include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Problems/ExtendedTaintAnalysis/AbstractMemoryLocationFactory.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "llvm/ADT/DenseMap.h"
1818
#include "llvm/ADT/FoldingSet.h"
1919
#include "llvm/ADT/SmallVector.h"
20+
#include "llvm/Support/TrailingObjects.h"
2021

2122
#include "phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Problems/ExtendedTaintAnalysis/AbstractMemoryLocation.h"
2223

@@ -35,9 +36,9 @@ class AbstractMemoryLocationFactoryBase {
3536

3637
private:
3738
struct Allocator {
38-
struct Block {
39+
struct Block final : public llvm::TrailingObjects<Block, void *> {
40+
3941
Block *Next = nullptr;
40-
void *Data[1]; // NOLINT
4142

4243
static Block *create(Block *Next, size_t NumPointerEntries);
4344
static void destroy(Block *Blck);
@@ -65,7 +66,7 @@ class AbstractMemoryLocationFactoryBase {
6566
private:
6667
constexpr static size_t ExpectedNumAmLsPerBlock = 1024;
6768
constexpr static size_t MinNumPointersPerAML =
68-
offsetof(AbstractMemoryLocationImpl, Offsets) / sizeof(void *);
69+
sizeof(AbstractMemoryLocationImpl) / sizeof(void *);
6970
constexpr static size_t NumPointersPerBlock =
7071
(MinNumPointersPerAML + 3) * ExpectedNumAmLsPerBlock;
7172
};

lib/PhasarLLVM/DataFlowSolver/IfdsIde/Problems/ExtendedTaintAnalysis/AbstractMemoryLocation.cpp

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "llvm/ADT/ArrayRef.h"
1111
#include "llvm/IR/Operator.h"
1212
#include "llvm/Support/raw_os_ostream.h"
13+
#include <cstddef>
1314

1415
#include "phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Problems/ExtendedTaintAnalysis/AbstractMemoryLocation.h"
1516
#include "phasar/PhasarLLVM/Utils/BasicBlockOrdering.h"
@@ -19,42 +20,37 @@
1920

2021
namespace psr::detail {
2122

22-
AbstractMemoryLoactionStorage::AbstractMemoryLoactionStorage(
23-
const llvm::Value *Baseptr, uint32_t Lifetime,
24-
const llvm::ArrayRef<ptrdiff_t> &Offsets) noexcept
25-
: Baseptr(Baseptr), Lifetime(Lifetime),
26-
NumOffsets(uint32_t(Offsets.size())) {
27-
assert(Baseptr && "The baseptr must not be null!");
28-
memcpy(this->Offsets, Offsets.begin(), Offsets.size() * sizeof(ptrdiff_t));
29-
}
30-
31-
AbstractMemoryLoactionStorage::AbstractMemoryLoactionStorage(
32-
const llvm::Value *Baseptr, uint32_t Lifetime) noexcept
33-
: Baseptr(Baseptr), Lifetime(Lifetime), NumOffsets(0) {
23+
AbstractMemoryLocationStorage::AbstractMemoryLocationStorage(
24+
const llvm::Value *Baseptr, uint32_t Lifetime, uint32_t NumOffsets) noexcept
25+
: Baseptr(Baseptr), Lifetime(Lifetime), NumOffsets(NumOffsets) {
3426
assert(Baseptr && "The baseptr must not be null!");
3527
}
3628

3729
AbstractMemoryLocationImpl::AbstractMemoryLocationImpl()
38-
: AbstractMemoryLoactionStorage(LLVMZeroValue::getInstance(), 0) {}
30+
: AbstractMemoryLocationStorage(LLVMZeroValue::getInstance(), 0) {}
3931

4032
AbstractMemoryLocationImpl::AbstractMemoryLocationImpl(
4133
const llvm::Value *Baseptr, unsigned Lifetime) noexcept
42-
: AbstractMemoryLoactionStorage(Baseptr, Lifetime) {}
34+
: AbstractMemoryLocationStorage(Baseptr, Lifetime) {}
4335
AbstractMemoryLocationImpl::AbstractMemoryLocationImpl(
4436
const llvm::Value *Baseptr, llvm::SmallVectorImpl<ptrdiff_t> &&Offsets,
4537
unsigned Lifetime) noexcept
46-
: AbstractMemoryLoactionStorage(Baseptr, Lifetime, Offsets) {}
38+
: AbstractMemoryLocationImpl(Baseptr, llvm::makeArrayRef(Offsets),
39+
Lifetime) {}
4740
AbstractMemoryLocationImpl::AbstractMemoryLocationImpl(
4841
const llvm::Value *Baseptr, llvm::ArrayRef<ptrdiff_t> Offsets,
4942
unsigned Lifetime) noexcept
50-
: AbstractMemoryLoactionStorage(Baseptr, Lifetime, Offsets) {}
43+
: AbstractMemoryLocationStorage(Baseptr, Lifetime, Offsets.size()) {
44+
memcpy(this->getTrailingObjects<ptrdiff_t>(), Offsets.data(),
45+
Offsets.size() * sizeof(ptrdiff_t));
46+
}
5147

5248
bool AbstractMemoryLocationImpl::isZero() const {
5349
return LLVMZeroValue::getInstance()->isLLVMZeroValue(Baseptr);
5450
}
5551

5652
llvm::ArrayRef<ptrdiff_t> AbstractMemoryLocationImpl::offsets() const {
57-
return llvm::makeArrayRef(Offsets, NumOffsets);
53+
return llvm::makeArrayRef(this->getTrailingObjects<ptrdiff_t>(), NumOffsets);
5854
}
5955

6056
auto AbstractMemoryLocationImpl::computeOffset(

lib/PhasarLLVM/DataFlowSolver/IfdsIde/Problems/ExtendedTaintAnalysis/AbstractMemoryLocationFactory.cpp

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include <exception>
1111
#include <limits>
12+
#include <new>
1213

1314
#include "llvm/IR/Instructions.h"
1415

@@ -17,9 +18,6 @@
1718

1819
namespace psr::detail {
1920

20-
/// We intentionally don't initialize the Data member as it will be a dynamic
21-
/// array at runtime
22-
// NOLINTNEXTLINE (cppcoreguidelines-pro-type-member-init)
2321
AbstractMemoryLocationFactoryBase::Allocator::Block::Block(Block *Next)
2422
: Next(Next) {}
2523

@@ -37,19 +35,16 @@ auto AbstractMemoryLocationFactoryBase::Allocator::Block::create(
3735
std::terminate();
3836
}
3937

40-
static_assert(
41-
alignof(AbstractMemoryLocationImpl) == alignof(size_t),
42-
"The alignment of the AbstractMemoryLocationImpl allocation cannot be "
43-
"guaranteed as it differs from the alignment of size_t");
44-
45-
auto *Ret = reinterpret_cast<Block *>(new size_t[1 + NumPointerEntries]);
38+
auto *Ret = reinterpret_cast<Block *>(new (std::align_val_t{
39+
alignof(AbstractMemoryLocationImpl)}) size_t[1 + NumPointerEntries]);
4640

4741
new (Ret) Block(Next);
4842
return Ret;
4943
}
5044

5145
void AbstractMemoryLocationFactoryBase::Allocator::Block::destroy(Block *Blck) {
52-
delete[] reinterpret_cast<size_t *>(Blck);
46+
::operator delete (Blck,
47+
std::align_val_t{alignof(AbstractMemoryLocationImpl)});
5348
}
5449

5550
AbstractMemoryLocationFactoryBase::Allocator::Allocator(
@@ -61,7 +56,7 @@ AbstractMemoryLocationFactoryBase::Allocator::Allocator(
6156
const auto NumPointersPerInitialBlock =
6257
(MinNumPointersPerAML + 3) * InitialCapacity;
6358
Root = Block::create(nullptr, NumPointersPerInitialBlock);
64-
Pos = Root->Data;
59+
Pos = Root->getTrailingObjects<void *>();
6560
End = Pos + NumPointersPerInitialBlock;
6661
}
6762

@@ -98,13 +93,16 @@ AbstractMemoryLocationFactoryBase::Allocator::create(
9893
llvm::ArrayRef<ptrdiff_t> Offsets) {
9994

10095
// All fields inside AML have pointer size, so there is no padding at all
101-
auto NumPointersRequired = MinNumPointersPerAML + Offsets.size();
96+
97+
auto NumPointersRequired =
98+
AbstractMemoryLocationImpl::totalSizeToAlloc<ptrdiff_t>(Offsets.size()) /
99+
sizeof(void *);
102100
auto *Rt = Root;
103101
auto *Curr = Pos;
104102

105103
if (End - Curr < ptrdiff_t(NumPointersRequired)) {
106104
Root = Rt = Block::create(Rt, NumPointersPerBlock);
107-
Pos = Curr = Rt->Data;
105+
Pos = Curr = Rt->getTrailingObjects<void *>();
108106
End = Curr + NumPointersPerBlock;
109107
}
110108

0 commit comments

Comments
 (0)