Skip to content

Commit

Permalink
Re-commit r259942 (reverted in r260053) with a different workaround f…
Browse files Browse the repository at this point in the history
…or the MSVC bug.

This fixes undefined behavior in C++14 due to the size of the object being
deleted being different from sizeof(dynamic type) when it is allocated with
trailing objects.

MSVC seems to have several bugs around using-declarations changing the access
of a member inherited from a base class, so use forwarding functions instead of
using-declarations to make TrailingObjects::operator delete accessible where
desired.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@260180 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
zygoloid committed Feb 9, 2016
1 parent 9f15b40 commit bca133d
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 1 deletion.
6 changes: 5 additions & 1 deletion include/llvm/Support/TrailingObjects.h
Original file line number Diff line number Diff line change
Expand Up @@ -290,9 +290,13 @@ class TrailingObjects : private trailing_objects_internal::TrailingObjectsImpl<
}

public:
// make this (privately inherited) class public.
// Make this (privately inherited) member public.
using ParentType::OverloadToken;

/// Disable sized deallocation for all objects with trailing object storage;
/// the inferred size will typically not be correct.
void operator delete(void *P) { return ::operator delete(P); }

/// Returns a pointer to the trailing object array of the given type
/// (which must be one of those specified in the class template). The
/// array may have zero or more elements in it.
Expand Down
4 changes: 4 additions & 0 deletions lib/IR/AttributeImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ class AttributeSetNode final
void operator=(const AttributeSetNode &) = delete;
AttributeSetNode(const AttributeSetNode &) = delete;
public:
void operator delete(void *p) { TrailingObjects::operator delete(p); }

static AttributeSetNode *get(LLVMContext &C, ArrayRef<Attribute> Attrs);

bool hasAttribute(Attribute::AttrKind Kind) const {
Expand Down Expand Up @@ -266,6 +268,8 @@ class AttributeSetImpl final
}
}

void operator delete(void *p) { TrailingObjects::operator delete(p); }

/// \brief Get the context that created this AttributeSetImpl.
LLVMContext &getContext() { return Context; }

Expand Down
2 changes: 2 additions & 0 deletions unittests/Support/TrailingObjectsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class Class1 final : protected TrailingObjects<Class1, short> {
void *Mem = ::operator new(totalSizeToAlloc<short>(NumShorts));
return new (Mem) Class1(ShortArray, NumShorts);
}
void operator delete(void *p) { TrailingObjects::operator delete(p); }

short get(unsigned Num) const { return getTrailingObjects<short>()[Num]; }

Expand Down Expand Up @@ -78,6 +79,7 @@ class Class2 final : protected TrailingObjects<Class2, double, short> {
*C->getTrailingObjects<double>() = D;
return C;
}
void operator delete(void *p) { TrailingObjects::operator delete(p); }

short getShort() const {
if (!HasShort)
Expand Down

0 comments on commit bca133d

Please sign in to comment.