Skip to content

Commit 40b8fd5

Browse files
committed
Remove copy constructors and assignment operators from RelativeDirectPointerImpl.
There were places were RelativeDirectPointers were copied using bitwise copies, which is semantically wrong. This patch makes sure it cannot happen anymore.
1 parent 75e10a6 commit 40b8fd5

File tree

4 files changed

+37
-16
lines changed

4 files changed

+37
-16
lines changed

include/swift/Basic/RelativePointer.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,15 @@ class RelativeDirectPointerImpl {
276276
/// RelativePointers should appear in statically-generated metadata. They
277277
/// shouldn't be constructed or copied.
278278
RelativeDirectPointerImpl() = delete;
279+
/// RelativePointers should appear in statically-generated metadata. They
280+
/// shouldn't be constructed or copied.
281+
RelativeDirectPointerImpl(RelativeDirectPointerImpl &&) = delete;
282+
RelativeDirectPointerImpl(const RelativeDirectPointerImpl &) = delete;
283+
RelativeDirectPointerImpl &operator=(RelativeDirectPointerImpl &&)
284+
= delete;
285+
RelativeDirectPointerImpl &operator=(const RelativeDirectPointerImpl &)
286+
= delete;
287+
279288

280289
public:
281290
using ValueTy = T;
@@ -305,12 +314,6 @@ class RelativeDirectPointerImpl {
305314
: detail::measureRelativeOffset<Offset>(absolute, this);
306315
return *this;
307316
}
308-
309-
// Can copy-construct by recalculating the relative offset at the new
310-
// position.
311-
RelativeDirectPointerImpl(const RelativeDirectPointerImpl &p) {
312-
*this = p.get();
313-
}
314317

315318
PointerTy get() const & {
316319
// Check for null.

include/swift/Runtime/Metadata.h

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <string>
2626
#include <type_traits>
2727
#include <utility>
28+
#include <string.h>
2829
#include "swift/Runtime/Config.h"
2930
#include "swift/ABI/MetadataValues.h"
3031
#include "swift/ABI/System.h"
@@ -1089,6 +1090,13 @@ template <typename Runtime> struct TargetOpaqueMetadata;
10891090
#pragma clang diagnostic push
10901091
#pragma clang diagnostic ignored "-Winvalid-offsetof"
10911092

1093+
extern uint64_t RelativeDirectPointerNullPtr;
1094+
1095+
#define RelativeDirectPointerNullPtrRef \
1096+
*reinterpret_cast<ConstTargetFarRelativeDirectPointer< \
1097+
Runtime, TargetNominalTypeDescriptor, /*nullable*/ true> *>( \
1098+
&RelativeDirectPointerNullPtr)
1099+
10921100
/// The common structure of all type metadata.
10931101
template <typename Runtime>
10941102
struct TargetMetadata {
@@ -1221,16 +1229,17 @@ struct TargetMetadata {
12211229

12221230
/// Get the nominal type descriptor if this metadata describes a nominal type,
12231231
/// or return null if it does not.
1224-
ConstTargetFarRelativeDirectPointer<Runtime, TargetNominalTypeDescriptor,
1225-
/*nullable*/ true>
1232+
const ConstTargetFarRelativeDirectPointer<Runtime,
1233+
TargetNominalTypeDescriptor,
1234+
/*nullable*/ true> &
12261235
getNominalTypeDescriptor() const {
12271236
switch (getKind()) {
12281237
case MetadataKind::Class: {
12291238
const auto cls = static_cast<const TargetClassMetadata<Runtime> *>(this);
12301239
if (!cls->isTypeMetadata())
1231-
return 0;
1240+
return RelativeDirectPointerNullPtrRef;
12321241
if (cls->isArtificialSubclass())
1233-
return 0;
1242+
return RelativeDirectPointerNullPtrRef;
12341243
return cls->getDescription();
12351244
}
12361245
case MetadataKind::Struct:
@@ -1248,7 +1257,7 @@ struct TargetMetadata {
12481257
case MetadataKind::HeapLocalVariable:
12491258
case MetadataKind::HeapGenericLocalVariable:
12501259
case MetadataKind::ErrorObject:
1251-
return 0;
1260+
return RelativeDirectPointerNullPtrRef;
12521261
}
12531262
}
12541263

@@ -1559,6 +1568,11 @@ struct TargetClassMetadata : public TargetHeapMetadata<Runtime> {
15591568
Reserved(0), ClassSize(classSize), ClassAddressPoint(classAddressPoint),
15601569
Description(nullptr), IVarDestroyer(ivarDestroyer) {}
15611570

1571+
TargetClassMetadata(const TargetClassMetadata& other): Description(other.getDescription().get()) {
1572+
memcpy(this, &other, sizeof(*this));
1573+
setDescription(other.getDescription().get());
1574+
}
1575+
15621576
/// The metadata for the superclass. This is null for the root class.
15631577
ConstTargetMetadataPointer<Runtime, swift::TargetClassMetadata> SuperClass;
15641578

@@ -1634,8 +1648,10 @@ struct TargetClassMetadata : public TargetHeapMetadata<Runtime> {
16341648
// - "tabulated" virtual methods
16351649

16361650
public:
1637-
ConstTargetFarRelativeDirectPointer<Runtime, TargetNominalTypeDescriptor,
1638-
/*nullable*/ true> getDescription() const {
1651+
const ConstTargetFarRelativeDirectPointer<Runtime,
1652+
TargetNominalTypeDescriptor,
1653+
/*nullable*/ true> &
1654+
getDescription() const {
16391655
assert(isTypeMetadata());
16401656
assert(!isArtificialSubclass());
16411657
return Description;

stdlib/public/runtime/Metadata.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1576,7 +1576,7 @@ static ClassMetadata *_swift_initializeSuperclass(ClassMetadata *theClass,
15761576
auto *classWords = reinterpret_cast<uintptr_t *>(theClass);
15771577
auto *superWords = reinterpret_cast<const uintptr_t *>(theSuperclass);
15781578
while (ancestor && ancestor->isTypeMetadata()) {
1579-
auto description = ancestor->getDescription();
1579+
auto &description = ancestor->getDescription();
15801580
auto &genericParams = description->GenericParams;
15811581

15821582
// Copy the parent type.
@@ -2486,7 +2486,7 @@ swift::swift_getForeignTypeMetadata(ForeignTypeMetadata *nonUnique) {
24862486

24872487
template<> const GenericMetadata *
24882488
Metadata::getGenericPattern() const {
2489-
auto ntd = getNominalTypeDescriptor();
2489+
auto &ntd = getNominalTypeDescriptor();
24902490
if (!ntd)
24912491
return nullptr;
24922492
return ntd->getGenericMetadataPattern();
@@ -2713,3 +2713,5 @@ swift::swift_getGenericWitnessTable(GenericWitnessTable *genericTable,
27132713

27142714
return entry->get(genericTable);
27152715
}
2716+
2717+
uint64_t swift::RelativeDirectPointerNullPtr = 0;

stdlib/public/runtime/ProtocolConformance.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ template<> void ProtocolConformanceRecord::dump() const {
6565
printf("%s direct type ",
6666
kind == TypeMetadataRecordKind::UniqueDirectType
6767
? "unique" : "nonunique");
68-
if (auto ntd = getDirectType()->getNominalTypeDescriptor()) {
68+
if (auto &ntd = getDirectType()->getNominalTypeDescriptor()) {
6969
printf("%s", ntd->Name.get());
7070
} else {
7171
printf("<structural type>");

0 commit comments

Comments
 (0)