Skip to content

Commit 0d17f23

Browse files
committed
Fix incorrect union member usage
See build failure https://lab.llvm.org/buildbot/#/builders/5/builds/41428. Memory sanitizer detects usage of `RawData` union member which is not filled directly. Instead, the code relies on filling `Data` union member, which is a struct consisting of signing schema parameters. According to https://en.cppreference.com/w/cpp/language/union, this is UB: "It is undefined behavior to read from the member of the union that wasn't most recently written". Instead of relying on compiler allowing us to do dirty things, do not use union and only store `RawData`. Particular ptrauth parameters are obtained on demand via bit operations.
1 parent 06a0bc4 commit 0d17f23

File tree

2 files changed

+20
-25
lines changed

2 files changed

+20
-25
lines changed

llvm/include/llvm/IR/DebugInfoMetadata.h

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -975,34 +975,29 @@ class DIDerivedType : public DIType {
975975
public:
976976
/// Pointer authentication (__ptrauth) metadata.
977977
struct PtrAuthData {
978-
union {
979-
struct {
980-
unsigned Key : 4;
981-
unsigned IsAddressDiscriminated : 1;
982-
unsigned ExtraDiscriminator : 16;
983-
unsigned IsaPointer : 1;
984-
unsigned AuthenticatesNullValues : 1;
985-
} Data;
986-
unsigned RawData;
987-
} Payload;
988-
989-
PtrAuthData(unsigned FromRawData) { Payload.RawData = FromRawData; }
978+
unsigned RawData;
979+
980+
PtrAuthData(unsigned FromRawData) : RawData(FromRawData) {}
990981
PtrAuthData(unsigned Key, bool IsDiscr, unsigned Discriminator,
991982
bool IsaPointer, bool AuthenticatesNullValues) {
992983
assert(Key < 16);
993984
assert(Discriminator <= 0xffff);
994-
Payload.Data.Key = Key;
995-
Payload.Data.IsAddressDiscriminated = IsDiscr;
996-
Payload.Data.ExtraDiscriminator = Discriminator;
997-
Payload.Data.IsaPointer = IsaPointer;
998-
Payload.Data.AuthenticatesNullValues = AuthenticatesNullValues;
985+
RawData = (Key << 0) | (IsDiscr ? (1 << 4) : 0) | (Discriminator << 5) |
986+
(IsaPointer ? (1 << 21) : 0) |
987+
(AuthenticatesNullValues ? (1 << 22) : 0);
999988
}
1000989
bool operator==(struct PtrAuthData Other) const {
1001-
return Payload.RawData == Other.Payload.RawData;
990+
return RawData == Other.RawData;
1002991
}
1003992
bool operator!=(struct PtrAuthData Other) const {
1004993
return !(*this == Other);
1005994
}
995+
996+
unsigned Key() { return (RawData >> 0) & 0b1111; }
997+
bool IsAddressDiscriminated() { return (RawData >> 4) & 1; }
998+
unsigned ExtraDiscriminator() { return (RawData >> 5) & 0xffff; }
999+
bool IsaPointer() { return (RawData >> 21) & 1; }
1000+
bool AuthenticatesNullValues() { return (RawData >> 22) & 1; }
10061001
};
10071002

10081003
private:
@@ -1023,7 +1018,7 @@ class DIDerivedType : public DIType {
10231018
AlignInBits, OffsetInBits, Flags, Ops),
10241019
DWARFAddressSpace(DWARFAddressSpace) {
10251020
if (PtrAuthData)
1026-
SubclassData32 = PtrAuthData->Payload.RawData;
1021+
SubclassData32 = PtrAuthData->RawData;
10271022
}
10281023
~DIDerivedType() = default;
10291024
static DIDerivedType *
@@ -1098,31 +1093,31 @@ class DIDerivedType : public DIType {
10981093
/// \returns The PointerAuth key.
10991094
std::optional<unsigned> getPtrAuthKey() const {
11001095
if (auto PtrAuthData = getPtrAuthData())
1101-
return (unsigned)PtrAuthData->Payload.Data.Key;
1096+
return PtrAuthData->Key();
11021097
return std::nullopt;
11031098
}
11041099
/// \returns The PointerAuth address discrimination bit.
11051100
std::optional<bool> isPtrAuthAddressDiscriminated() const {
11061101
if (auto PtrAuthData = getPtrAuthData())
1107-
return (bool)PtrAuthData->Payload.Data.IsAddressDiscriminated;
1102+
return PtrAuthData->IsAddressDiscriminated();
11081103
return std::nullopt;
11091104
}
11101105
/// \returns The PointerAuth extra discriminator.
11111106
std::optional<unsigned> getPtrAuthExtraDiscriminator() const {
11121107
if (auto PtrAuthData = getPtrAuthData())
1113-
return (unsigned)PtrAuthData->Payload.Data.ExtraDiscriminator;
1108+
return PtrAuthData->ExtraDiscriminator();
11141109
return std::nullopt;
11151110
}
11161111
/// \returns The PointerAuth IsaPointer bit.
11171112
std::optional<bool> isPtrAuthIsaPointer() const {
11181113
if (auto PtrAuthData = getPtrAuthData())
1119-
return (bool)PtrAuthData->Payload.Data.IsaPointer;
1114+
return PtrAuthData->IsaPointer();
11201115
return std::nullopt;
11211116
}
11221117
/// \returns The PointerAuth authenticates null values bit.
11231118
std::optional<bool> getPtrAuthAuthenticatesNullValues() const {
11241119
if (auto PtrAuthData = getPtrAuthData())
1125-
return (bool)PtrAuthData->Payload.Data.AuthenticatesNullValues;
1120+
return PtrAuthData->AuthenticatesNullValues();
11261121
return std::nullopt;
11271122
}
11281123

llvm/lib/Bitcode/Writer/BitcodeWriter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1805,7 +1805,7 @@ void ModuleBitcodeWriter::writeDIDerivedType(const DIDerivedType *N,
18051805
Record.push_back(VE.getMetadataOrNullID(N->getAnnotations().get()));
18061806

18071807
if (auto PtrAuthData = N->getPtrAuthData())
1808-
Record.push_back(PtrAuthData->Payload.RawData);
1808+
Record.push_back(PtrAuthData->RawData);
18091809
else
18101810
Record.push_back(0);
18111811

0 commit comments

Comments
 (0)