[clang] Resign function pointer (PR #98847)
Akira Hatanaka via cfe-commits
cfe-commits at lists.llvm.org
Sun Jul 14 17:20:45 PDT 2024
https://github.com/ahatanak updated https://github.com/llvm/llvm-project/pull/98847
>From 938d8f030a12a18c1a316aaa8dbc5c24a2c69296 Mon Sep 17 00:00:00 2001
From: Ahmed Bougacha <ahmed at bougacha.org>
Date: Mon, 27 Sep 2021 08:00:00 -0700
Subject: [PATCH 1/4] [clang][CodeGen] Teach RawAddress/Address about ptrauth.
---
clang/lib/CodeGen/Address.h | 43 ++++++++++++++++++++++++++---
clang/lib/CodeGen/CGBlocks.cpp | 4 +--
clang/lib/CodeGen/CGBuilder.h | 46 ++++++++++++++++++++++---------
clang/lib/CodeGen/CGCall.cpp | 13 +++++----
clang/lib/CodeGen/CGException.cpp | 4 +--
clang/lib/CodeGen/CGObjCMac.cpp | 2 +-
6 files changed, 85 insertions(+), 27 deletions(-)
diff --git a/clang/lib/CodeGen/Address.h b/clang/lib/CodeGen/Address.h
index 35ec370a139c9..3b677c9159e22 100644
--- a/clang/lib/CodeGen/Address.h
+++ b/clang/lib/CodeGen/Address.h
@@ -108,6 +108,22 @@ class RawAddress {
/// Like RawAddress, an abstract representation of an aligned address, but the
/// pointer contained in this class is possibly signed.
+///
+/// This is designed to be an IR-level abstraction, carrying just the
+/// information necessary to perform IR operations on an address like loads and
+/// stores. In particular, it doesn't carry C type information or allow the
+/// representation of things like bit-fields; clients working at that level
+/// should generally be using `LValue`.
+///
+/// An address may be either *raw*, meaning that it's an ordinary machine
+/// pointer, or *signed*, meaning that the pointer carries an embedded
+/// pointer-authentication signature. Representing signed pointers directly in
+/// this abstraction allows the authentication to be delayed as long as possible
+/// without forcing IRGen to use totally different code paths for signed and
+/// unsigned values or to separately propagate signature information through
+/// every API that manipulates addresses. Pointer arithmetic on signed addresses
+/// (e.g. drilling down to a struct field) is accumulated into a separate offset
+/// which is applied when the address is finally accessed.
class Address {
friend class CGBuilderTy;
@@ -117,6 +133,10 @@ class Address {
/// The expected IR type of the pointer. Carrying accurate element type
/// information in Address makes it more convenient to work with Address
/// values and allows frontend assertions to catch simple mistakes.
+ ///
+ /// When the address is a raw pointer, this is currently redundant with the
+ /// pointer's type, but for signed pointers it is useful if the pointer has
+ /// been offsetted or cast from the original type.
llvm::Type *ElementType = nullptr;
CharUnits Alignment;
@@ -153,6 +173,11 @@ class Address {
static Address invalid() { return Address(nullptr); }
bool isValid() const { return Pointer.getPointer() != nullptr; }
+ llvm::Value *getPointerIfNotSigned() const {
+ assert(isValid() && "pointer isn't valid");
+ return Pointer.getPointer();
+ }
+
/// This function is used in situations where the caller is doing some sort of
/// opaque "laundering" of the pointer.
void replaceBasePointer(llvm::Value *P) {
@@ -172,6 +197,8 @@ class Address {
return Pointer.getPointer();
}
+ llvm::Value *getUnsignedPointer() const { return getBasePointer(); }
+
/// Return the type of the pointer value.
llvm::PointerType *getType() const {
return llvm::PointerType::get(
@@ -211,6 +238,14 @@ class Address {
return *this;
}
+ /// Add a constant offset.
+ void addOffset(CharUnits V, llvm::Type *Ty, CGBuilderTy &Builder);
+
+ /// Add a variable offset.
+ /// \param V An llvm value holding a variable offset.
+ void addOffset(llvm::Value *V, llvm::Type *Ty, CGBuilderTy &Builder,
+ CharUnits NewAlignment);
+
bool hasOffset() const { return Offset; }
llvm::Value *getOffset() const { return Offset; }
@@ -218,7 +253,7 @@ class Address {
/// Return the pointer contained in this class after authenticating it and
/// adding offset to it if necessary.
llvm::Value *emitRawPointer(CodeGenFunction &CGF) const {
- return getBasePointer();
+ return getUnsignedPointer();
}
/// Return address with different pointer, but same element type and
@@ -249,9 +284,9 @@ class Address {
};
inline RawAddress::RawAddress(Address Addr)
- : PointerAndKnownNonNull(Addr.isValid() ? Addr.getBasePointer() : nullptr,
- Addr.isValid() ? Addr.isKnownNonNull()
- : NotKnownNonNull),
+ : PointerAndKnownNonNull(
+ Addr.isValid() ? Addr.getUnsignedPointer() : nullptr,
+ Addr.isValid() ? Addr.isKnownNonNull() : NotKnownNonNull),
ElementType(Addr.isValid() ? Addr.getElementType() : nullptr),
Alignment(Addr.isValid() ? Addr.getAlignment() : CharUnits::Zero()) {}
diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp
index 066139b1c78c7..2affd93c6b9a2 100644
--- a/clang/lib/CodeGen/CGBlocks.cpp
+++ b/clang/lib/CodeGen/CGBlocks.cpp
@@ -1974,8 +1974,8 @@ CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) {
// it. It's not quite worth the annoyance to avoid creating it in the
// first place.
if (!needsEHCleanup(captureType.isDestructedType()))
- if (auto *I =
- cast_or_null<llvm::Instruction>(dstField.getBasePointer()))
+ if (auto *I = cast_or_null<llvm::Instruction>(
+ dstField.getPointerIfNotSigned()))
I->eraseFromParent();
}
break;
diff --git a/clang/lib/CodeGen/CGBuilder.h b/clang/lib/CodeGen/CGBuilder.h
index 0bc4fda62979c..752bfc6c0c058 100644
--- a/clang/lib/CodeGen/CGBuilder.h
+++ b/clang/lib/CodeGen/CGBuilder.h
@@ -15,6 +15,7 @@
#include "llvm/Analysis/Utils/Local.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
namespace clang {
@@ -56,7 +57,24 @@ class CGBuilderTy : public CGBuilderBaseTy {
CodeGenFunction *getCGF() const { return getInserter().CGF; }
llvm::Value *emitRawPointerFromAddress(Address Addr) const {
- return Addr.getBasePointer();
+ return Addr.getUnsignedPointer();
+ }
+
+ /// Helper function to compute a GEP's offset and add it to Addr.
+ Address addGEPOffset(Address Addr, ArrayRef<llvm::Value *> IdxList,
+ CharUnits Align, bool IsInBounds, const Twine &Name) {
+ typedef ArrayRef<llvm::Value *>::const_iterator IdxItTy;
+ typedef llvm::generic_gep_type_iterator<IdxItTy> GEPTypeIt;
+ const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
+ GEPTypeIt GTI = GEPTypeIt::begin(Addr.getElementType(), IdxList.begin());
+ IdxItTy IdxBegin = IdxList.begin(), IdxEnd = IdxList.end();
+ llvm::Type *GEPType = Addr.getType();
+ SmallString<12> Buffer;
+ StringRef GEPName = Name.toStringRef(Buffer);
+ std::pair<llvm::Value *, llvm::Type *> OffsetAndType = llvm::EmitGEPOffset(
+ this, DL, GTI, IdxBegin, IdxEnd, GEPType, GEPName, IsInBounds, false);
+ Addr.addOffset(OffsetAndType.first, OffsetAndType.second, *this, Align);
+ return Addr;
}
template <bool IsInBounds>
@@ -222,8 +240,8 @@ class CGBuilderTy : public CGBuilderBaseTy {
const llvm::StructLayout *Layout = DL.getStructLayout(ElTy);
auto Offset = CharUnits::fromQuantity(Layout->getElementOffset(Index));
- return Address(CreateStructGEP(Addr.getElementType(), Addr.getBasePointer(),
- Index, Name),
+ return Address(CreateStructGEP(Addr.getElementType(),
+ Addr.getUnsignedPointer(), Index, Name),
ElTy->getElementType(Index),
Addr.getAlignment().alignmentAtOffset(Offset),
Addr.isKnownNonNull());
@@ -245,7 +263,7 @@ class CGBuilderTy : public CGBuilderBaseTy {
CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy->getElementType()));
return Address(
- CreateInBoundsGEP(Addr.getElementType(), Addr.getBasePointer(),
+ CreateInBoundsGEP(Addr.getElementType(), Addr.getUnsignedPointer(),
{getSize(CharUnits::Zero()), getSize(Index)}, Name),
ElTy->getElementType(),
Addr.getAlignment().alignmentAtOffset(Index * EltSize),
@@ -263,10 +281,10 @@ class CGBuilderTy : public CGBuilderBaseTy {
const llvm::DataLayout &DL = BB->getDataLayout();
CharUnits EltSize = CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy));
- return Address(
- CreateInBoundsGEP(ElTy, Addr.getBasePointer(), getSize(Index), Name),
- ElTy, Addr.getAlignment().alignmentAtOffset(Index * EltSize),
- Addr.isKnownNonNull());
+ return Address(CreateInBoundsGEP(ElTy, Addr.getUnsignedPointer(),
+ getSize(Index), Name),
+ ElTy, Addr.getAlignment().alignmentAtOffset(Index * EltSize),
+ Addr.isKnownNonNull());
}
/// Given
@@ -280,9 +298,10 @@ class CGBuilderTy : public CGBuilderBaseTy {
const llvm::DataLayout &DL = BB->getDataLayout();
CharUnits EltSize = CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy));
- return Address(CreateGEP(ElTy, Addr.getBasePointer(), getSize(Index), Name),
- Addr.getElementType(),
- Addr.getAlignment().alignmentAtOffset(Index * EltSize));
+ return Address(
+ CreateGEP(ElTy, Addr.getUnsignedPointer(), getSize(Index), Name),
+ Addr.getElementType(),
+ Addr.getAlignment().alignmentAtOffset(Index * EltSize));
}
/// Create GEP with single dynamic index. The address alignment is reduced
@@ -305,7 +324,7 @@ class CGBuilderTy : public CGBuilderBaseTy {
const llvm::Twine &Name = "") {
assert(Addr.getElementType() == TypeCache.Int8Ty);
return Address(
- CreateInBoundsGEP(Addr.getElementType(), Addr.getBasePointer(),
+ CreateInBoundsGEP(Addr.getElementType(), Addr.getUnsignedPointer(),
getSize(Offset), Name),
Addr.getElementType(), Addr.getAlignment().alignmentAtOffset(Offset),
Addr.isKnownNonNull());
@@ -314,7 +333,8 @@ class CGBuilderTy : public CGBuilderBaseTy {
Address CreateConstByteGEP(Address Addr, CharUnits Offset,
const llvm::Twine &Name = "") {
assert(Addr.getElementType() == TypeCache.Int8Ty);
- return Address(CreateGEP(Addr.getElementType(), Addr.getBasePointer(),
+
+ return Address(CreateGEP(Addr.getElementType(), Addr.getUnsignedPointer(),
getSize(Offset), Name),
Addr.getElementType(),
Addr.getAlignment().alignmentAtOffset(Offset));
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index a38484941ba24..333771160cabf 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -3508,7 +3508,8 @@ static llvm::Value *tryRemoveRetainOfSelf(CodeGenFunction &CGF,
llvm::LoadInst *load =
dyn_cast<llvm::LoadInst>(retainedValue->stripPointerCasts());
if (!load || load->isAtomic() || load->isVolatile() ||
- load->getPointerOperand() != CGF.GetAddrOfLocalVar(self).getBasePointer())
+ load->getPointerOperand() !=
+ CGF.GetAddrOfLocalVar(self).getPointerIfNotSigned())
return nullptr;
// Okay! Burn it all down. This relies for correctness on the
@@ -3545,7 +3546,8 @@ static llvm::Value *emitAutoreleaseOfResult(CodeGenFunction &CGF,
/// Heuristically search for a dominating store to the return-value slot.
static llvm::StoreInst *findDominatingStoreToReturnValue(CodeGenFunction &CGF) {
- llvm::Value *ReturnValuePtr = CGF.ReturnValue.getBasePointer();
+ // This function shouldn't be called when ReturnValue is signed.
+ llvm::Value *ReturnValuePtr = CGF.ReturnValue.getUnsignedPointer();
// Check if a User is a store which pointerOperand is the ReturnValue.
// We are looking for stores to the ReturnValue, not for stores of the
@@ -4133,7 +4135,8 @@ static bool isProvablyNull(llvm::Value *addr) {
}
static bool isProvablyNonNull(Address Addr, CodeGenFunction &CGF) {
- return llvm::isKnownNonZero(Addr.getBasePointer(), CGF.CGM.getDataLayout());
+ return llvm::isKnownNonZero(Addr.getUnsignedPointer(),
+ CGF.CGM.getDataLayout());
}
/// Emit the actual writing-back of a writeback.
@@ -4141,7 +4144,7 @@ static void emitWriteback(CodeGenFunction &CGF,
const CallArgList::Writeback &writeback) {
const LValue &srcLV = writeback.Source;
Address srcAddr = srcLV.getAddress();
- assert(!isProvablyNull(srcAddr.getBasePointer()) &&
+ assert(!isProvablyNull(srcAddr.getPointerIfNotSigned()) &&
"shouldn't have writeback for provably null argument");
llvm::BasicBlock *contBB = nullptr;
@@ -4258,7 +4261,7 @@ static void emitWritebackArg(CodeGenFunction &CGF, CallArgList &args,
CGF.ConvertTypeForMem(CRE->getType()->getPointeeType());
// If the address is a constant null, just pass the appropriate null.
- if (isProvablyNull(srcAddr.getBasePointer())) {
+ if (isProvablyNull(srcAddr.getPointerIfNotSigned())) {
args.add(RValue::get(llvm::ConstantPointerNull::get(destType)),
CRE->getType());
return;
diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp
index bb2ed237ee9f3..2de85963437f5 100644
--- a/clang/lib/CodeGen/CGException.cpp
+++ b/clang/lib/CodeGen/CGException.cpp
@@ -1835,8 +1835,8 @@ Address CodeGenFunction::recoverAddrOfEscapedLocal(CodeGenFunction &ParentCGF,
llvm::Value *ParentFP) {
llvm::CallInst *RecoverCall = nullptr;
CGBuilderTy Builder(*this, AllocaInsertPt);
- if (auto *ParentAlloca =
- dyn_cast_or_null<llvm::AllocaInst>(ParentVar.getBasePointer())) {
+ if (auto *ParentAlloca = dyn_cast_or_null<llvm::AllocaInst>(
+ ParentVar.getPointerIfNotSigned())) {
// Mark the variable escaped if nobody else referenced it and compute the
// localescape index.
auto InsertPair = ParentCGF.EscapedLocals.insert(
diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 30f3911a8b03c..7395370259fe9 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -4425,7 +4425,7 @@ void FragileHazards::emitHazardsInNewBlocks() {
static void addIfPresent(llvm::DenseSet<llvm::Value*> &S, Address V) {
if (V.isValid())
- if (llvm::Value *Ptr = V.getBasePointer())
+ if (llvm::Value *Ptr = V.getPointerIfNotSigned())
S.insert(Ptr);
}
>From a147bcebdd879fec4f7e26339c20ed84dd012136 Mon Sep 17 00:00:00 2001
From: Ahmed Bougacha <ahmed at bougacha.org>
Date: Wed, 15 May 2024 13:37:17 -0700
Subject: [PATCH 2/4] [clang][CodeGen] Set KnownNonNull in more places.
---
clang/lib/CodeGen/CGExpr.cpp | 15 ++++++++++----
clang/lib/CodeGen/CGExprAgg.cpp | 3 +++
clang/lib/CodeGen/CGExprCXX.cpp | 9 +++++----
clang/lib/CodeGen/CGValue.h | 10 ++-------
clang/lib/CodeGen/CodeGenFunction.cpp | 29 ++++++++++++++++++---------
clang/lib/CodeGen/CodeGenFunction.h | 4 +++-
clang/lib/CodeGen/ItaniumCXXABI.cpp | 2 +-
7 files changed, 45 insertions(+), 27 deletions(-)
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index ddb82571f53d7..d5c3732a4e270 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -1941,6 +1941,9 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(Address Addr, bool Volatile,
Addr = Addr.withPointer(Builder.CreateThreadLocalAddress(GV),
NotKnownNonNull);
+ if (!CGM.getCodeGenOpts().NullPointerIsValid)
+ Addr = Addr.setKnownNonNull();
+
if (const auto *ClangVecTy = Ty->getAs<VectorType>()) {
// Boolean vectors use `iN` as storage type.
if (ClangVecTy->isExtVectorBoolType()) {
@@ -2090,6 +2093,9 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, Address Addr,
Addr = Addr.withPointer(Builder.CreateThreadLocalAddress(GV),
NotKnownNonNull);
+ if (!CGM.getCodeGenOpts().NullPointerIsValid)
+ Addr = Addr.setKnownNonNull();
+
llvm::Type *SrcTy = Value->getType();
if (const auto *ClangVecTy = Ty->getAs<VectorType>()) {
auto *VecTy = dyn_cast<llvm::FixedVectorType>(SrcTy);
@@ -2791,9 +2797,9 @@ CodeGenFunction::EmitLoadOfReference(LValue RefLVal,
llvm::LoadInst *Load =
Builder.CreateLoad(RefLVal.getAddress(), RefLVal.isVolatile());
CGM.DecorateInstructionWithTBAA(Load, RefLVal.getTBAAInfo());
- return makeNaturalAddressForPointer(Load, RefLVal.getType()->getPointeeType(),
- CharUnits(), /*ForPointeeType=*/true,
- PointeeBaseInfo, PointeeTBAAInfo);
+ return makeNaturalAddressForPointer(
+ Load, RefLVal.getType()->getPointeeType(), CharUnits(),
+ /*ForPointeeType=*/true, PointeeBaseInfo, PointeeTBAAInfo, KnownNonNull);
}
LValue CodeGenFunction::EmitLoadOfReferenceLValue(LValue RefLVal) {
@@ -4706,7 +4712,8 @@ LValue CodeGenFunction::EmitLValueForLambdaField(const FieldDecl *Field,
}
} else {
QualType LambdaTagType = getContext().getTagDeclType(Field->getParent());
- LambdaLV = MakeNaturalAlignAddrLValue(ThisValue, LambdaTagType);
+ LambdaLV = MakeNaturalAlignAddrLValue(ThisValue, LambdaTagType,
+ KnownNonNull);
}
return EmitLValueForField(LambdaLV, Field);
}
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index c3c10e73ff05e..d70701f0856cf 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -253,6 +253,9 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
void AggExprEmitter::EmitAggLoadOfLValue(const Expr *E) {
LValue LV = CGF.EmitLValue(E);
+ if (!CGF.CGM.getCodeGenOpts().NullPointerIsValid)
+ LV = LV.setKnownNonNull();
+
// If the type of the l-value is atomic, then do an atomic load.
if (LV.getType()->isAtomicType() || CGF.LValueIsSuitableForInlineAtomic(LV)) {
CGF.EmitAtomicLoad(LV, E->getExprLoc(), Dest);
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp
index 8eb6ab7381acb..db4a70f5316f8 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/lib/CodeGen/CGExprCXX.cpp
@@ -265,7 +265,7 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(CE)) {
if (OCE->isAssignmentOp()) {
if (TrivialAssignment) {
- TrivialAssignmentRHS = EmitLValue(CE->getArg(1));
+ TrivialAssignmentRHS = EmitLValue(CE->getArg(1), KnownNonNull);
} else {
RtlArgs = &RtlArgStorage;
EmitCallArgs(*RtlArgs, MD->getType()->castAs<FunctionProtoType>(),
@@ -279,11 +279,12 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
if (IsArrow) {
LValueBaseInfo BaseInfo;
TBAAAccessInfo TBAAInfo;
- Address ThisValue = EmitPointerWithAlignment(Base, &BaseInfo, &TBAAInfo);
+ Address ThisValue = EmitPointerWithAlignment(
+ Base, &BaseInfo, &TBAAInfo, KnownNonNull);
This = MakeAddrLValue(ThisValue, Base->getType()->getPointeeType(),
BaseInfo, TBAAInfo);
} else {
- This = EmitLValue(Base);
+ This = EmitLValue(Base, KnownNonNull);
}
if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(MD)) {
@@ -316,7 +317,7 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
// the RHS.
LValue RHS = isa<CXXOperatorCallExpr>(CE)
? TrivialAssignmentRHS
- : EmitLValue(*CE->arg_begin());
+ : EmitLValue(*CE->arg_begin(), KnownNonNull);
EmitAggregateAssign(This, RHS, CE->getType());
return RValue::get(This.getPointer(*this));
}
diff --git a/clang/lib/CodeGen/CGValue.h b/clang/lib/CodeGen/CGValue.h
index f1ba3cf95ae59..6ed94bd9c7592 100644
--- a/clang/lib/CodeGen/CGValue.h
+++ b/clang/lib/CodeGen/CGValue.h
@@ -233,9 +233,6 @@ class LValue {
// this lvalue.
bool Nontemporal : 1;
- // The pointer is known not to be null.
- bool IsKnownNonNull : 1;
-
LValueBaseInfo BaseInfo;
TBAAAccessInfo TBAAInfo;
@@ -263,7 +260,6 @@ class LValue {
this->ImpreciseLifetime = false;
this->Nontemporal = false;
this->ThreadLocalRef = false;
- this->IsKnownNonNull = false;
this->BaseIvarExp = nullptr;
}
@@ -349,11 +345,9 @@ class LValue {
LValueBaseInfo getBaseInfo() const { return BaseInfo; }
void setBaseInfo(LValueBaseInfo Info) { BaseInfo = Info; }
- KnownNonNull_t isKnownNonNull() const {
- return (KnownNonNull_t)IsKnownNonNull;
- }
+ KnownNonNull_t isKnownNonNull() const { return Addr.isKnownNonNull(); }
LValue setKnownNonNull() {
- IsKnownNonNull = true;
+ Addr.setKnownNonNull();
return *this;
}
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 26deeca95d326..a222bc05e8dab 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -195,34 +195,45 @@ CodeGenFunction::CGFPOptionsRAII::~CGFPOptionsRAII() {
CGF.Builder.setDefaultConstrainedRounding(OldRounding);
}
-static LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T,
- bool ForPointeeType,
- CodeGenFunction &CGF) {
+static LValue
+MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T, bool ForPointeeType,
+ bool MightBeSigned, CodeGenFunction &CGF,
+ KnownNonNull_t IsKnownNonNull = NotKnownNonNull) {
LValueBaseInfo BaseInfo;
TBAAAccessInfo TBAAInfo;
CharUnits Alignment =
CGF.CGM.getNaturalTypeAlignment(T, &BaseInfo, &TBAAInfo, ForPointeeType);
- Address Addr = Address(V, CGF.ConvertTypeForMem(T), Alignment);
+ Address Addr =
+ MightBeSigned
+ ? CGF.makeNaturalAddressForPointer(V, T, Alignment, false, nullptr,
+ nullptr, IsKnownNonNull)
+ : Address(V, CGF.ConvertTypeForMem(T), Alignment, IsKnownNonNull);
return CGF.MakeAddrLValue(Addr, T, BaseInfo, TBAAInfo);
}
-LValue CodeGenFunction::MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T) {
- return ::MakeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ false, *this);
+LValue
+CodeGenFunction::MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T,
+ KnownNonNull_t IsKnownNonNull) {
+ return ::MakeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ false,
+ /*IsSigned*/ true, *this, IsKnownNonNull);
}
LValue
CodeGenFunction::MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T) {
- return ::MakeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ true, *this);
+ return ::MakeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ true,
+ /*IsSigned*/ true, *this);
}
LValue CodeGenFunction::MakeNaturalAlignRawAddrLValue(llvm::Value *V,
QualType T) {
- return ::MakeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ false, *this);
+ return ::MakeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ false,
+ /*IsSigned*/ false, *this);
}
LValue CodeGenFunction::MakeNaturalAlignPointeeRawAddrLValue(llvm::Value *V,
QualType T) {
- return ::MakeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ true, *this);
+ return ::MakeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ true,
+ /*IsSigned*/ false, *this);
}
llvm::Type *CodeGenFunction::ConvertTypeForMem(QualType T) {
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 13f12b5d878a6..5268cc7eda4a2 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -2728,7 +2728,9 @@ class CodeGenFunction : public CodeGenTypeCache {
/// an l-value with the natural pointee alignment of T.
LValue MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T);
- LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T);
+ LValue
+ MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T,
+ KnownNonNull_t IsKnownNonNull = NotKnownNonNull);
/// Same as MakeNaturalAlignPointeeAddrLValue except that the pointer is known
/// to be unsigned.
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 6e5fa0faf73d7..1609ae19696c7 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -4711,7 +4711,7 @@ static void InitCatchParam(CodeGenFunction &CGF,
// Cast that to the appropriate type.
Address adjustedExn(CGF.Builder.CreateBitCast(rawAdjustedExn, PtrTy),
- LLVMCatchTy, caughtExnAlignment);
+ LLVMCatchTy, caughtExnAlignment, KnownNonNull);
// The copy expression is defined in terms of an OpaqueValueExpr.
// Find it and map it to the adjusted expression.
>From 4110867a3b0a20a7685aeae9ceaa64d65c365f4f Mon Sep 17 00:00:00 2001
From: Ahmed Bougacha <ahmed at bougacha.org>
Date: Thu, 27 Jun 2024 16:00:35 -0700
Subject: [PATCH 3/4] [clang] Resign type-discriminated function pointers on
cast.
---
clang/include/clang/AST/ASTContext.h | 2 +-
clang/include/clang/AST/Type.h | 5 +-
clang/lib/AST/ASTContext.cpp | 12 +-
clang/lib/CodeGen/Address.h | 39 ++-
clang/lib/CodeGen/CGBuilder.h | 94 ++++--
clang/lib/CodeGen/CGBuiltin.cpp | 3 +-
clang/lib/CodeGen/CGCall.cpp | 6 +-
clang/lib/CodeGen/CGExpr.cpp | 10 +-
clang/lib/CodeGen/CGExprAgg.cpp | 4 +-
clang/lib/CodeGen/CGExprConstant.cpp | 16 +-
clang/lib/CodeGen/CGExprScalar.cpp | 29 +-
clang/lib/CodeGen/CGPointerAuth.cpp | 318 ++++++++++++++++++
clang/lib/CodeGen/CGValue.h | 29 +-
clang/lib/CodeGen/CodeGenFunction.cpp | 60 +++-
clang/lib/CodeGen/CodeGenFunction.h | 73 +++-
clang/lib/CodeGen/CodeGenModule.h | 3 +
clang/lib/Headers/ptrauth.h | 15 +
.../ptrauth-function-lvalue-cast-disc.c | 55 +++
...ptrauth-function-type-discriminator-cast.c | 85 +++++
clang/test/CodeGen/ptrauth.c | 77 +++++
clang/test/Preprocessor/ptrauth_feature.c | 10 +
.../ptrauth-function-type-discriminatior.c | 65 ++++
22 files changed, 907 insertions(+), 103 deletions(-)
create mode 100644 clang/test/CodeGen/ptrauth-function-lvalue-cast-disc.c
create mode 100644 clang/test/CodeGen/ptrauth-function-type-discriminator-cast.c
create mode 100644 clang/test/CodeGen/ptrauth.c
create mode 100644 clang/test/Sema/ptrauth-function-type-discriminatior.c
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 57022e75073fe..8ba0c943a9c86 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1284,7 +1284,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
getPointerAuthVTablePointerDiscriminator(const CXXRecordDecl *RD);
/// Return the "other" type-specific discriminator for the given type.
- uint16_t getPointerAuthTypeDiscriminator(QualType T) const;
+ uint16_t getPointerAuthTypeDiscriminator(QualType T);
/// Apply Objective-C protocol qualifiers to the given type.
/// \param allowOnPointerType specifies if we can apply protocol
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 3aa0f05b0ab60..bf242debe479a 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -2507,6 +2507,7 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
bool isFunctionProtoType() const { return getAs<FunctionProtoType>(); }
bool isPointerType() const;
bool isSignableType() const;
+ bool isSignablePointerType() const;
bool isAnyPointerType() const; // Any C pointer or ObjC object pointer
bool isCountAttributedType() const;
bool isBlockPointerType() const;
@@ -8002,7 +8003,9 @@ inline bool Type::isAnyPointerType() const {
return isPointerType() || isObjCObjectPointerType();
}
-inline bool Type::isSignableType() const { return isPointerType(); }
+inline bool Type::isSignableType() const { return isSignablePointerType(); }
+
+inline bool Type::isSignablePointerType() const { return isPointerType(); }
inline bool Type::isBlockPointerType() const {
return isa<BlockPointerType>(CanonicalType);
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 497579dcc56b6..18dfe51e167e0 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -3400,7 +3400,7 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx,
}
}
-uint16_t ASTContext::getPointerAuthTypeDiscriminator(QualType T) const {
+uint16_t ASTContext::getPointerAuthTypeDiscriminator(QualType T) {
assert(!T->isDependentType() &&
"cannot compute type discriminator of a dependent type");
@@ -3410,11 +3410,13 @@ uint16_t ASTContext::getPointerAuthTypeDiscriminator(QualType T) const {
if (T->isFunctionPointerType() || T->isFunctionReferenceType())
T = T->getPointeeType();
- if (T->isFunctionType())
+ if (T->isFunctionType()) {
encodeTypeForFunctionPointerAuth(*this, Out, T);
- else
- llvm_unreachable(
- "type discrimination of non-function type not implemented yet");
+ } else {
+ T = T.getUnqualifiedType();
+ std::unique_ptr<MangleContext> MC(createMangleContext());
+ MC->mangleCanonicalTypeName(T, Out);
+ }
return llvm::getPointerAuthStableSipHash(Str);
}
diff --git a/clang/lib/CodeGen/Address.h b/clang/lib/CodeGen/Address.h
index 3b677c9159e22..1d2c453f25523 100644
--- a/clang/lib/CodeGen/Address.h
+++ b/clang/lib/CodeGen/Address.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_LIB_CODEGEN_ADDRESS_H
#define LLVM_CLANG_LIB_CODEGEN_ADDRESS_H
+#include "CGPointerAuthInfo.h"
#include "clang/AST/CharUnits.h"
#include "clang/AST/Type.h"
#include "llvm/ADT/PointerIntPair.h"
@@ -141,7 +142,11 @@ class Address {
CharUnits Alignment;
- /// Offset from the base pointer.
+ /// The ptrauth information needed to authenticate the base pointer.
+ CGPointerAuthInfo PtrAuthInfo;
+
+ /// Offset from the base pointer. This is non-null only when the base
+ /// pointer is signed.
llvm::Value *Offset = nullptr;
llvm::Value *emitRawPointerSlow(CodeGenFunction &CGF) const;
@@ -160,12 +165,14 @@ class Address {
}
Address(llvm::Value *BasePtr, llvm::Type *ElementType, CharUnits Alignment,
- llvm::Value *Offset, KnownNonNull_t IsKnownNonNull = NotKnownNonNull)
+ CGPointerAuthInfo PtrAuthInfo, llvm::Value *Offset,
+ KnownNonNull_t IsKnownNonNull = NotKnownNonNull)
: Pointer(BasePtr, IsKnownNonNull), ElementType(ElementType),
- Alignment(Alignment), Offset(Offset) {}
+ Alignment(Alignment), PtrAuthInfo(PtrAuthInfo), Offset(Offset) {}
Address(RawAddress RawAddr)
- : Pointer(RawAddr.isValid() ? RawAddr.getPointer() : nullptr),
+ : Pointer(RawAddr.isValid() ? RawAddr.getPointer() : nullptr,
+ RawAddr.isValid() ? RawAddr.isKnownNonNull() : NotKnownNonNull),
ElementType(RawAddr.isValid() ? RawAddr.getElementType() : nullptr),
Alignment(RawAddr.isValid() ? RawAddr.getAlignment()
: CharUnits::Zero()) {}
@@ -175,7 +182,7 @@ class Address {
llvm::Value *getPointerIfNotSigned() const {
assert(isValid() && "pointer isn't valid");
- return Pointer.getPointer();
+ return !isSigned() ? Pointer.getPointer() : nullptr;
}
/// This function is used in situations where the caller is doing some sort of
@@ -197,7 +204,10 @@ class Address {
return Pointer.getPointer();
}
- llvm::Value *getUnsignedPointer() const { return getBasePointer(); }
+ llvm::Value *getUnsignedPointer() const {
+ assert(!isSigned() && "cannot call this function if pointer is signed");
+ return getBasePointer();
+ }
/// Return the type of the pointer value.
llvm::PointerType *getType() const {
@@ -219,6 +229,9 @@ class Address {
/// Return the IR name of the pointer value.
llvm::StringRef getName() const { return Pointer.getPointer()->getName(); }
+ const CGPointerAuthInfo &getPointerAuthInfo() const { return PtrAuthInfo; }
+ void setPointerAuthInfo(const CGPointerAuthInfo &Info) { PtrAuthInfo = Info; }
+
// This function is called only in CGBuilderBaseTy::CreateElementBitCast.
void setElementType(llvm::Type *Ty) {
assert(hasOffset() &&
@@ -226,7 +239,8 @@ class Address {
ElementType = Ty;
}
- /// Whether the pointer is known not to be null.
+ bool isSigned() const { return PtrAuthInfo.isSigned(); }
+
KnownNonNull_t isKnownNonNull() const {
assert(isValid());
return (KnownNonNull_t)Pointer.getInt();
@@ -250,10 +264,15 @@ class Address {
llvm::Value *getOffset() const { return Offset; }
+ Address getResignedAddress(const CGPointerAuthInfo &NewInfo,
+ CodeGenFunction &CGF) const;
+
/// Return the pointer contained in this class after authenticating it and
/// adding offset to it if necessary.
llvm::Value *emitRawPointer(CodeGenFunction &CGF) const {
- return getUnsignedPointer();
+ if (!isSigned())
+ return getUnsignedPointer();
+ return emitRawPointerSlow(CGF);
}
/// Return address with different pointer, but same element type and
@@ -275,8 +294,8 @@ class Address {
/// alignment.
Address withElementType(llvm::Type *ElemTy) const {
if (!hasOffset())
- return Address(getBasePointer(), ElemTy, getAlignment(), nullptr,
- isKnownNonNull());
+ return Address(getBasePointer(), ElemTy, getAlignment(),
+ getPointerAuthInfo(), nullptr, isKnownNonNull());
Address A(*this);
A.ElementType = ElemTy;
return A;
diff --git a/clang/lib/CodeGen/CGBuilder.h b/clang/lib/CodeGen/CGBuilder.h
index 752bfc6c0c058..48b3067494062 100644
--- a/clang/lib/CodeGen/CGBuilder.h
+++ b/clang/lib/CodeGen/CGBuilder.h
@@ -57,7 +57,10 @@ class CGBuilderTy : public CGBuilderBaseTy {
CodeGenFunction *getCGF() const { return getInserter().CGF; }
llvm::Value *emitRawPointerFromAddress(Address Addr) const {
- return Addr.getUnsignedPointer();
+ if (!Addr.isSigned())
+ return Addr.getUnsignedPointer();
+ assert(getCGF() && "CGF not set");
+ return Addr.emitRawPointerSlow(*getCGF());
}
/// Helper function to compute a GEP's offset and add it to Addr.
@@ -208,8 +211,8 @@ class CGBuilderTy : public CGBuilderBaseTy {
const llvm::Twine &Name = "") {
if (!Addr.hasOffset())
return Address(CreateAddrSpaceCast(Addr.getBasePointer(), Ty, Name),
- ElementTy, Addr.getAlignment(), nullptr,
- Addr.isKnownNonNull());
+ ElementTy, Addr.getAlignment(), Addr.getPointerAuthInfo(),
+ nullptr, Addr.isKnownNonNull());
// Eagerly force a raw address if these is an offset.
return RawAddress(
CreateAddrSpaceCast(Addr.emitRawPointer(*getCGF()), Ty, Name),
@@ -240,11 +243,14 @@ class CGBuilderTy : public CGBuilderBaseTy {
const llvm::StructLayout *Layout = DL.getStructLayout(ElTy);
auto Offset = CharUnits::fromQuantity(Layout->getElementOffset(Index));
- return Address(CreateStructGEP(Addr.getElementType(),
- Addr.getUnsignedPointer(), Index, Name),
- ElTy->getElementType(Index),
- Addr.getAlignment().alignmentAtOffset(Offset),
- Addr.isKnownNonNull());
+ if (!Addr.isSigned())
+ return Address(CreateStructGEP(Addr.getElementType(),
+ Addr.getUnsignedPointer(), Index, Name),
+ ElTy->getElementType(Index),
+ Addr.getAlignment().alignmentAtOffset(Offset),
+ Addr.isKnownNonNull());
+ Addr.addOffset(Offset, ElTy->getTypeAtIndex(Index), *this);
+ return Addr;
}
/// Given
@@ -262,12 +268,15 @@ class CGBuilderTy : public CGBuilderBaseTy {
CharUnits EltSize =
CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy->getElementType()));
- return Address(
- CreateInBoundsGEP(Addr.getElementType(), Addr.getUnsignedPointer(),
- {getSize(CharUnits::Zero()), getSize(Index)}, Name),
- ElTy->getElementType(),
- Addr.getAlignment().alignmentAtOffset(Index * EltSize),
- Addr.isKnownNonNull());
+ if (!Addr.isSigned())
+ return Address(
+ CreateInBoundsGEP(Addr.getElementType(), Addr.getUnsignedPointer(),
+ {getSize(CharUnits::Zero()), getSize(Index)}, Name),
+ ElTy->getElementType(),
+ Addr.getAlignment().alignmentAtOffset(Index * EltSize),
+ Addr.isKnownNonNull());
+ Addr.addOffset(Index * EltSize, ElTy, *this);
+ return Addr;
}
/// Given
@@ -281,10 +290,14 @@ class CGBuilderTy : public CGBuilderBaseTy {
const llvm::DataLayout &DL = BB->getDataLayout();
CharUnits EltSize = CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy));
- return Address(CreateInBoundsGEP(ElTy, Addr.getUnsignedPointer(),
- getSize(Index), Name),
- ElTy, Addr.getAlignment().alignmentAtOffset(Index * EltSize),
- Addr.isKnownNonNull());
+ if (!Addr.isSigned())
+ return Address(CreateInBoundsGEP(ElTy, Addr.getUnsignedPointer(),
+ getSize(Index), Name),
+ ElTy,
+ Addr.getAlignment().alignmentAtOffset(Index * EltSize),
+ Addr.isKnownNonNull());
+ Addr.addOffset(Index * EltSize, ElTy, *this);
+ return Addr;
}
/// Given
@@ -298,10 +311,12 @@ class CGBuilderTy : public CGBuilderBaseTy {
const llvm::DataLayout &DL = BB->getDataLayout();
CharUnits EltSize = CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy));
- return Address(
- CreateGEP(ElTy, Addr.getUnsignedPointer(), getSize(Index), Name),
- Addr.getElementType(),
- Addr.getAlignment().alignmentAtOffset(Index * EltSize));
+ if (!Addr.isSigned())
+ return Address(
+ CreateGEP(ElTy, Addr.getUnsignedPointer(), getSize(Index), Name),
+ ElTy, Addr.getAlignment().alignmentAtOffset(Index * EltSize));
+ Addr.addOffset(Index * EltSize, ElTy, *this);
+ return Addr;
}
/// Create GEP with single dynamic index. The address alignment is reduced
@@ -323,21 +338,28 @@ class CGBuilderTy : public CGBuilderBaseTy {
Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset,
const llvm::Twine &Name = "") {
assert(Addr.getElementType() == TypeCache.Int8Ty);
- return Address(
- CreateInBoundsGEP(Addr.getElementType(), Addr.getUnsignedPointer(),
- getSize(Offset), Name),
- Addr.getElementType(), Addr.getAlignment().alignmentAtOffset(Offset),
- Addr.isKnownNonNull());
+
+ if (!Addr.isSigned())
+ return Address(
+ CreateInBoundsGEP(Addr.getElementType(), Addr.getUnsignedPointer(),
+ getSize(Offset), Name),
+ Addr.getElementType(), Addr.getAlignment().alignmentAtOffset(Offset),
+ Addr.isKnownNonNull());
+ Addr.addOffset(Offset, TypeCache.Int8Ty, *this);
+ return Addr;
}
Address CreateConstByteGEP(Address Addr, CharUnits Offset,
const llvm::Twine &Name = "") {
assert(Addr.getElementType() == TypeCache.Int8Ty);
- return Address(CreateGEP(Addr.getElementType(), Addr.getUnsignedPointer(),
- getSize(Offset), Name),
- Addr.getElementType(),
- Addr.getAlignment().alignmentAtOffset(Offset));
+ if (!Addr.isSigned())
+ return Address(CreateGEP(Addr.getElementType(), Addr.getUnsignedPointer(),
+ getSize(Offset), Name),
+ Addr.getElementType(),
+ Addr.getAlignment().alignmentAtOffset(Offset));
+ Addr.addOffset(Offset, TypeCache.Int8Ty, *this);
+ return Addr;
}
using CGBuilderBaseTy::CreateConstInBoundsGEP2_32;
@@ -364,10 +386,12 @@ class CGBuilderTy : public CGBuilderBaseTy {
Address CreateInBoundsGEP(Address Addr, ArrayRef<llvm::Value *> IdxList,
llvm::Type *ElementType, CharUnits Align,
const Twine &Name = "") {
- return RawAddress(CreateInBoundsGEP(Addr.getElementType(),
- emitRawPointerFromAddress(Addr),
- IdxList, Name),
- ElementType, Align, Addr.isKnownNonNull());
+ if (!Addr.isSigned())
+ return RawAddress(CreateInBoundsGEP(Addr.getElementType(),
+ emitRawPointerFromAddress(Addr),
+ IdxList, Name),
+ ElementType, Align, Addr.isKnownNonNull());
+ return addGEPOffset(Addr, IdxList, Align, true, Name);
}
using CGBuilderBaseTy::CreateIsNull;
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 6cc0d9485720c..494891ce4740d 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -2151,7 +2151,8 @@ RValue CodeGenFunction::emitBuiltinOSLogFormat(const CallExpr &E) {
// Ignore argument 1, the format string. It is not currently used.
CallArgList Args;
- Args.add(RValue::get(BufAddr.emitRawPointer(*this)), Ctx.VoidPtrTy);
+ Args.add(RValue::get(getAsNaturalPointerTo(BufAddr, Ctx.VoidTy)),
+ Ctx.VoidPtrTy);
for (const auto &Item : Layout.Items) {
int Size = Item.getSizeByte();
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 333771160cabf..b60f5b3a65868 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -4135,8 +4135,8 @@ static bool isProvablyNull(llvm::Value *addr) {
}
static bool isProvablyNonNull(Address Addr, CodeGenFunction &CGF) {
- return llvm::isKnownNonZero(Addr.getUnsignedPointer(),
- CGF.CGM.getDataLayout());
+ return !Addr.isSigned() && llvm::isKnownNonZero(Addr.getUnsignedPointer(),
+ CGF.CGM.getDataLayout());
}
/// Emit the actual writing-back of a writeback.
@@ -5101,7 +5101,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
llvm::Value *UnusedReturnSizePtr = nullptr;
if (RetAI.isIndirect() || RetAI.isInAlloca() || RetAI.isCoerceAndExpand()) {
if (!ReturnValue.isNull()) {
- SRetPtr = ReturnValue.getAddress();
+ SRetPtr = ReturnValue.getValue();
} else {
SRetPtr = CreateMemTemp(RetTy, "tmp", &SRetAlloca);
if (HaveInsertPoint() && ReturnValue.isUnused()) {
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index d5c3732a4e270..c3bf7d960410a 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -1311,7 +1311,8 @@ static Address EmitPointerWithAlignment(const Expr *E, LValueBaseInfo *BaseInfo,
if (CE->getCastKind() == CK_AddressSpaceConversion)
Addr = CGF.Builder.CreateAddrSpaceCast(
Addr, CGF.ConvertType(E->getType()), ElemTy);
- return Addr;
+ return CGF.AuthPointerToPointerCast(Addr, CE->getSubExpr()->getType(),
+ CE->getType());
}
break;
@@ -1785,8 +1786,11 @@ CodeGenFunction::tryEmitAsConstant(DeclRefExpr *refExpr) {
}
// Emit as a constant.
- auto C = ConstantEmitter(*this).emitAbstract(refExpr->getLocation(),
- result.Val, resultType);
+ // Try to emit as a constant.
+ llvm::Constant *C =
+ ConstantEmitter(*this).tryEmitAbstract(result.Val, resultType);
+ if (!C)
+ return ConstantEmission();
// Make sure we emit a debug reference to the global variable.
// This should probably fire even for
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index d70701f0856cf..14fee2eee8250 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -330,8 +330,8 @@ void AggExprEmitter::withReturnValueSlot(
if (!UseTemp)
return;
- assert(Dest.isIgnored() || Dest.emitRawPointer(CGF) !=
- Src.getAggregatePointer(E->getType(), CGF));
+ assert(Dest.getAddress().isSigned() || Dest.isIgnored() ||
+ Dest.emitRawPointer(CGF) != Src.getAggregatePointer(E->getType(), CGF));
EmitFinalDestCopy(E->getType(), Src);
if (!RequiresDestruction && LifetimeStartInst) {
diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp
index 00a5a7e6898a8..534f7c0407f61 100644
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ b/clang/lib/CodeGen/CGExprConstant.cpp
@@ -2074,14 +2074,24 @@ ConstantLValueEmitter::tryEmitBase(const APValue::LValueBase &base) {
if (D->hasAttr<WeakRefAttr>())
return CGM.GetWeakRefReference(D).getPointer();
- auto PtrAuthSign = [&](llvm::Constant *C) {
+ auto PtrAuthSign = [&](llvm::Constant *C, bool IsFunction) {
CGPointerAuthInfo AuthInfo;
if (EnablePtrAuthFunctionTypeDiscrimination)
AuthInfo = CGM.getFunctionPointerAuthInfo(DestType);
+ else {
+ // FIXME: getPointerAuthInfoForType should be able to return the pointer
+ // auth info of reference types.
+ if (auto *RT = DestType->getAs<ReferenceType>())
+ DestType = CGM.getContext().getPointerType(RT->getPointeeType());
+ // Don't emit a signed pointer if the destination is a function pointer
+ // type.
+ if (DestType->isSignableType() && !DestType->isFunctionPointerType())
+ AuthInfo = CGM.getPointerAuthInfoForType(DestType);
+ }
if (AuthInfo) {
- if (hasNonZeroOffset())
+ if (IsFunction && hasNonZeroOffset())
return ConstantLValue(nullptr);
C = applyOffset(C);
@@ -2095,7 +2105,7 @@ ConstantLValueEmitter::tryEmitBase(const APValue::LValueBase &base) {
};
if (const auto *FD = dyn_cast<FunctionDecl>(D))
- return PtrAuthSign(CGM.getRawFunctionPointer(FD));
+ return PtrAuthSign(CGM.getRawFunctionPointer(FD), true);
if (const auto *VD = dyn_cast<VarDecl>(D)) {
// We can never refer to a variable with local storage.
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index f40f3c273206b..65acb3b067f91 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -2373,7 +2373,9 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
DestLV.setTBAAInfo(TBAAAccessInfo::getMayAliasInfo());
return EmitLoadOfLValue(DestLV, CE->getExprLoc());
}
- return Builder.CreateBitCast(Src, DstTy);
+
+ llvm::Value *Result = Builder.CreateBitCast(Src, DstTy);
+ return CGF.AuthPointerToPointerCast(Result, E->getType(), DestTy);
}
case CK_AddressSpaceConversion: {
Expr::EvalResult Result;
@@ -2523,6 +2525,8 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
if (DestTy.mayBeDynamicClass())
IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr);
}
+
+ IntToPtr = CGF.AuthPointerToPointerCast(IntToPtr, E->getType(), DestTy);
return IntToPtr;
}
case CK_PointerToIntegral: {
@@ -2538,6 +2542,7 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
PtrExpr = Builder.CreateStripInvariantGroup(PtrExpr);
}
+ PtrExpr = CGF.AuthPointerToPointerCast(PtrExpr, E->getType(), DestTy);
return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy));
}
case CK_ToVoid: {
@@ -2850,10 +2855,11 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
Builder.SetInsertPoint(opBB);
atomicPHI = Builder.CreatePHI(value->getType(), 2);
atomicPHI->addIncoming(value, startBB);
- value = atomicPHI;
+ value = CGF.EmitPointerAuthAuth(type->getPointeeType(), atomicPHI);
} else {
value = EmitLoadOfLValue(LV, E->getExprLoc());
input = value;
+ value = CGF.EmitPointerAuthAuth(type->getPointeeType(), value);
}
// Special case of integer increment that we have to check first: bool++.
@@ -3095,6 +3101,7 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
if (atomicPHI) {
llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
llvm::BasicBlock *contBB = CGF.createBasicBlock("atomic_cont", CGF.CurFn);
+ value = CGF.EmitPointerAuthSign(type->getPointeeType(), value);
auto Pair = CGF.EmitAtomicCompareExchange(
LV, RValue::get(atomicPHI), RValue::get(value), E->getExprLoc());
llvm::Value *old = CGF.EmitToMemory(Pair.first.getScalarVal(), type);
@@ -3106,6 +3113,7 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
}
// Store the updated result through the lvalue.
+ value = CGF.EmitPointerAuthSign(type->getPointeeType(), value);
if (LV.isBitField()) {
Value *Src = Previous ? Previous : value;
CGF.EmitStoreThroughBitfieldLValue(RValue::get(value), LV, &value);
@@ -3966,6 +3974,10 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,
return CGF.Builder.CreateBitCast(result, pointer->getType());
}
+ CGPointerAuthInfo PtrAuthInfo = CGF.CGM.getPointerAuthInfoForType(op.Ty);
+ if (PtrAuthInfo)
+ pointer = CGF.EmitPointerAuthAuth(PtrAuthInfo, pointer);
+
QualType elementType = pointerType->getPointeeType();
if (const VariableArrayType *vla
= CGF.getContext().getAsVariableArrayType(elementType)) {
@@ -3986,7 +3998,8 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,
elemTy, pointer, index, isSigned, isSubtraction, op.E->getExprLoc(),
"add.ptr");
}
- return pointer;
+ return PtrAuthInfo ? CGF.EmitPointerAuthSign(PtrAuthInfo, pointer)
+ : pointer;
}
// Explicitly handle GNU void* and function pointer arithmetic extensions. The
@@ -3999,11 +4012,13 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,
elemTy = CGF.ConvertTypeForMem(elementType);
if (CGF.getLangOpts().isSignedOverflowDefined())
- return CGF.Builder.CreateGEP(elemTy, pointer, index, "add.ptr");
+ pointer = CGF.Builder.CreateGEP(elemTy, pointer, index, "add.ptr");
+ else
+ pointer = CGF.EmitCheckedInBoundsGEP(elemTy, pointer, index, isSigned,
+ isSubtraction, op.E->getExprLoc(),
+ "add.ptr");
- return CGF.EmitCheckedInBoundsGEP(
- elemTy, pointer, index, isSigned, isSubtraction, op.E->getExprLoc(),
- "add.ptr");
+ return PtrAuthInfo ? CGF.EmitPointerAuthSign(PtrAuthInfo, pointer) : pointer;
}
// Construct an fmuladd intrinsic to represent a fused mul-add of MulOp and
diff --git a/clang/lib/CodeGen/CGPointerAuth.cpp b/clang/lib/CodeGen/CGPointerAuth.cpp
index 621d567dde721..c069b3fa72fba 100644
--- a/clang/lib/CodeGen/CGPointerAuth.cpp
+++ b/clang/lib/CodeGen/CGPointerAuth.cpp
@@ -15,6 +15,7 @@
#include "CodeGenModule.h"
#include "clang/CodeGen/CodeGenABITypes.h"
#include "clang/CodeGen/ConstantInitBuilder.h"
+#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Support/SipHash.h"
using namespace clang;
@@ -89,6 +90,7 @@ CGPointerAuthInfo CodeGenModule::getFunctionPointerAuthInfo(QualType T) {
Discriminator);
}
+
llvm::Value *
CodeGenFunction::EmitPointerAuthBlendDiscriminator(llvm::Value *StorageAddress,
llvm::Value *Discriminator) {
@@ -165,6 +167,130 @@ CGPointerAuthInfo CodeGenModule::getPointerAuthInfoForType(QualType T) {
return ::getPointerAuthInfoForType(*this, T);
}
+Address CodeGenFunction::mergeAddressesInConditionalExpr(
+ Address LHS, Address RHS, llvm::BasicBlock *LHSBlock,
+ llvm::BasicBlock *RHSBlock, llvm::BasicBlock *MergeBlock,
+ QualType MergedType) {
+ CGPointerAuthInfo LHSInfo = LHS.getPointerAuthInfo();
+ CGPointerAuthInfo RHSInfo = RHS.getPointerAuthInfo();
+
+ if (LHSInfo || RHSInfo) {
+ if (LHSInfo != RHSInfo || LHS.getOffset() != RHS.getOffset() ||
+ LHS.getBasePointer()->getType() != RHS.getBasePointer()->getType()) {
+ // If the LHS and RHS have different signing information, offsets, or base
+ // pointer types, resign both sides and clear out the offsets.
+ CGPointerAuthInfo NewInfo =
+ CGM.getPointerAuthInfoForPointeeType(MergedType);
+ LHSBlock->getTerminator()->eraseFromParent();
+ Builder.SetInsertPoint(LHSBlock);
+ LHS = LHS.getResignedAddress(NewInfo, *this);
+ Builder.CreateBr(MergeBlock);
+ LHSBlock = Builder.GetInsertBlock();
+ RHSBlock->getTerminator()->eraseFromParent();
+ Builder.SetInsertPoint(RHSBlock);
+ RHS = RHS.getResignedAddress(NewInfo, *this);
+ Builder.CreateBr(MergeBlock);
+ RHSBlock = Builder.GetInsertBlock();
+ }
+
+ assert(LHS.getPointerAuthInfo() == RHS.getPointerAuthInfo() &&
+ LHS.getOffset() == RHS.getOffset() &&
+ LHS.getBasePointer()->getType() == RHS.getBasePointer()->getType() &&
+ "lhs and rhs must have the same signing information, offsets, and "
+ "base pointer types");
+ }
+
+ Builder.SetInsertPoint(MergeBlock);
+ llvm::PHINode *PtrPhi = Builder.CreatePHI(LHS.getType(), 2, "cond");
+ PtrPhi->addIncoming(LHS.getBasePointer(), LHSBlock);
+ PtrPhi->addIncoming(RHS.getBasePointer(), RHSBlock);
+ LHS.replaceBasePointer(PtrPhi);
+ LHS.setAlignment(std::min(LHS.getAlignment(), RHS.getAlignment()));
+ return LHS;
+}
+
+static bool isZeroConstant(llvm::Value *value) {
+ if (auto ci = dyn_cast<llvm::ConstantInt>(value))
+ return ci->isZero();
+ return false;
+}
+
+static bool equalAuthPolicies(const CGPointerAuthInfo &left,
+ const CGPointerAuthInfo &right) {
+ if (left.isSigned() != right.isSigned())
+ return false;
+ assert(left.isSigned() && right.isSigned() &&
+ "should only be called with non-null auth policies");
+ return left.getKey() == right.getKey() &&
+ left.getAuthenticationMode() == right.getAuthenticationMode();
+}
+
+llvm::Value *CodeGenFunction::EmitPointerAuthResign(
+ llvm::Value *value, QualType type, const CGPointerAuthInfo &curAuthInfo,
+ const CGPointerAuthInfo &newAuthInfo, bool isKnownNonNull) {
+ // Fast path: if neither schema wants a signature, we're done.
+ if (!curAuthInfo && !newAuthInfo)
+ return value;
+
+ llvm::Value *null = nullptr;
+ // If the value is obviously null, we're done.
+ if (auto pointerValue = dyn_cast<llvm::PointerType>(value->getType())) {
+ null = CGM.getNullPointer(pointerValue, type);
+ } else {
+ assert(value->getType()->isIntegerTy());
+ null = llvm::ConstantInt::get(IntPtrTy, 0);
+ }
+ if (value == null) {
+ return value;
+ }
+
+ // If both schemas sign the same way, we're done.
+ if (equalAuthPolicies(curAuthInfo, newAuthInfo)) {
+ auto curD = curAuthInfo.getDiscriminator();
+ auto newD = newAuthInfo.getDiscriminator();
+ if (curD == newD)
+ return value;
+
+ if ((curD == nullptr && isZeroConstant(newD)) ||
+ (newD == nullptr && isZeroConstant(curD)))
+ return value;
+ }
+
+ llvm::BasicBlock *initBB = Builder.GetInsertBlock();
+ llvm::BasicBlock *resignBB = nullptr, *contBB = nullptr;
+
+ // Null pointers have to be mapped to null, and the ptrauth_resign
+ // intrinsic doesn't do that.
+ if (!isKnownNonNull && !llvm::isKnownNonZero(value, CGM.getDataLayout())) {
+ contBB = createBasicBlock("resign.cont");
+ resignBB = createBasicBlock("resign.nonnull");
+
+ auto isNonNull = Builder.CreateICmpNE(value, null);
+ Builder.CreateCondBr(isNonNull, resignBB, contBB);
+ EmitBlock(resignBB);
+ }
+
+ // Perform the auth/sign/resign operation.
+ if (!newAuthInfo) {
+ value = EmitPointerAuthAuth(curAuthInfo, value);
+ } else if (!curAuthInfo) {
+ value = EmitPointerAuthSign(newAuthInfo, value);
+ } else {
+ value = EmitPointerAuthResignCall(value, curAuthInfo, newAuthInfo);
+ }
+
+ // Clean up with a phi if we branched before.
+ if (contBB) {
+ EmitBlock(contBB);
+ auto phi = Builder.CreatePHI(value->getType(), 2);
+ phi->addIncoming(null, initBB);
+ phi->addIncoming(value, resignBB);
+ value = phi;
+ }
+
+ return value;
+}
+
llvm::Constant *
CodeGenModule::getConstantSignedPointer(llvm::Constant *Pointer, unsigned Key,
llvm::Constant *StorageAddress,
@@ -211,6 +337,16 @@ llvm::Constant *CodeGenModule::getConstantSignedPointer(
OtherDiscriminator);
}
+llvm::Constant *CodeGenModule::getConstantSignedPointer(llvm::Constant *Pointer,
+ QualType PointeeType) {
+ CGPointerAuthInfo Info = getPointerAuthInfoForPointeeType(PointeeType);
+ if (!Info.shouldSign())
+ return Pointer;
+ return getConstantSignedPointer(
+ Pointer, Info.getKey(), nullptr,
+ cast<llvm::ConstantInt>(Info.getDiscriminator()));
+}
+
/// If applicable, sign a given constant function pointer with the ABI rules for
/// functionType.
llvm::Constant *CodeGenModule::getFunctionPointer(llvm::Constant *Pointer,
@@ -351,3 +487,185 @@ CodeGenModule::getVTablePointerAuthInfo(CodeGenFunction *CGF,
/* IsIsaPointer */ false,
/* AuthenticatesNullValues */ false, Discriminator);
}
+
+llvm::Value *CodeGenFunction::AuthPointerToPointerCast(llvm::Value *ResultPtr,
+ QualType SourceType,
+ QualType DestType) {
+ CGPointerAuthInfo CurAuthInfo, NewAuthInfo;
+ if (SourceType->isSignableType())
+ CurAuthInfo = getPointerAuthInfoForType(CGM, SourceType);
+
+ if (DestType->isSignableType())
+ NewAuthInfo = getPointerAuthInfoForType(CGM, DestType);
+
+ if (!CurAuthInfo && !NewAuthInfo)
+ return ResultPtr;
+
+ // If only one side of the cast is a function pointer, then we still need to
+ // resign to handle casts to/from opaque pointers.
+ if (!CurAuthInfo && DestType->isFunctionPointerType())
+ CurAuthInfo = CGM.getFunctionPointerAuthInfo(SourceType);
+
+ if (!NewAuthInfo && SourceType->isFunctionPointerType())
+ NewAuthInfo = CGM.getFunctionPointerAuthInfo(DestType);
+
+ return EmitPointerAuthResign(ResultPtr, DestType, CurAuthInfo, NewAuthInfo,
+ /*IsKnownNonNull=*/false);
+}
+
+Address CodeGenFunction::AuthPointerToPointerCast(Address Ptr,
+ QualType SourceType,
+ QualType DestType) {
+ CGPointerAuthInfo CurAuthInfo, NewAuthInfo;
+ if (SourceType->isSignableType())
+ CurAuthInfo = getPointerAuthInfoForType(CGM, SourceType);
+
+ if (DestType->isSignableType())
+ NewAuthInfo = getPointerAuthInfoForType(CGM, DestType);
+
+ if (!CurAuthInfo && !NewAuthInfo)
+ return Ptr;
+
+ if (!CurAuthInfo && DestType->isFunctionPointerType()) {
+ // When casting a non-signed pointer to a function pointer, just set the
+ // auth info on Ptr to the assumed schema. The pointer will be resigned to
+ // the effective type when used.
+ Ptr.setPointerAuthInfo(CGM.getFunctionPointerAuthInfo(SourceType));
+ return Ptr;
+ }
+
+ if (!NewAuthInfo && SourceType->isFunctionPointerType()) {
+ NewAuthInfo = CGM.getFunctionPointerAuthInfo(DestType);
+ Ptr = Ptr.getResignedAddress(NewAuthInfo, *this);
+ Ptr.setPointerAuthInfo(CGPointerAuthInfo());
+ return Ptr;
+ }
+
+ return Ptr;
+}
+
+Address CodeGenFunction::EmitPointerAuthSign(Address Addr,
+ QualType PointeeType) {
+ CGPointerAuthInfo Info = getPointerAuthInfoForPointeeType(CGM, PointeeType);
+ llvm::Value *Ptr = EmitPointerAuthSign(Info, Addr.emitRawPointer(*this));
+ return Address(Ptr, Addr.getElementType(), Addr.getAlignment());
+}
+
+Address CodeGenFunction::EmitPointerAuthAuth(Address Addr,
+ QualType PointeeType) {
+ CGPointerAuthInfo Info = getPointerAuthInfoForPointeeType(CGM, PointeeType);
+ llvm::Value *Ptr = EmitPointerAuthAuth(Info, Addr.emitRawPointer(*this));
+ return Address(Ptr, Addr.getElementType(), Addr.getAlignment());
+}
+
+Address CodeGenFunction::getAsNaturalAddressOf(Address Addr,
+ QualType PointeeTy) {
+ CGPointerAuthInfo Info =
+ PointeeTy.isNull() ? CGPointerAuthInfo()
+ : CGM.getPointerAuthInfoForPointeeType(PointeeTy);
+ return Addr.getResignedAddress(Info, *this);
+}
+
+Address Address::getResignedAddress(const CGPointerAuthInfo &NewInfo,
+ CodeGenFunction &CGF) const {
+ assert(isValid() && "pointer isn't valid");
+ CGPointerAuthInfo CurInfo = getPointerAuthInfo();
+ llvm::Value *Val;
+
+ // Nothing to do if neither the current or the new ptrauth info needs signing.
+ if (!CurInfo.isSigned() && !NewInfo.isSigned())
+ return Address(getUnsignedPointer(), getElementType(), getAlignment(),
+ isKnownNonNull());
+
+ assert(ElementType && "Effective type has to be set");
+
+ // If the current and the new ptrauth infos are the same and the offset is
+ // null, just cast the base pointer to the effective type.
+ if (CurInfo == NewInfo && !hasOffset())
+ Val = getBasePointer();
+ else {
+ if (Offset) {
+ assert(isSigned() && "signed pointer expected");
+ // Authenticate the base pointer.
+ Val = CGF.EmitPointerAuthResign(getBasePointer(), QualType(), CurInfo,
+ CGPointerAuthInfo(), isKnownNonNull());
+
+ // Add offset to the authenticated pointer.
+ unsigned AS = cast<llvm::PointerType>(getBasePointer()->getType())
+ ->getAddressSpace();
+ Val = CGF.Builder.CreateBitCast(Val,
+ llvm::PointerType::get(CGF.Int8Ty, AS));
+ Val = CGF.Builder.CreateGEP(CGF.Int8Ty, Val, Offset, "resignedgep");
+
+ // Sign the pointer using the new ptrauth info.
+ Val = CGF.EmitPointerAuthResign(Val, QualType(), CGPointerAuthInfo(),
+ NewInfo, isKnownNonNull());
+ } else {
+ Val = CGF.EmitPointerAuthResign(getBasePointer(), QualType(), CurInfo,
+ NewInfo, isKnownNonNull());
+ }
+ }
+
+ Val = CGF.Builder.CreateBitCast(Val, getType());
+ return Address(Val, getElementType(), getAlignment(), NewInfo, nullptr,
+ isKnownNonNull());
+}
+
+void Address::addOffset(CharUnits V, llvm::Type *Ty, CGBuilderTy &Builder) {
+ assert(isSigned() &&
+ "shouldn't add an offset if the base pointer isn't signed");
+ Alignment = Alignment.alignmentAtOffset(V);
+ llvm::Value *FixedOffset =
+ llvm::ConstantInt::get(Builder.getCGF()->IntPtrTy, V.getQuantity());
+ addOffset(FixedOffset, Ty, Builder, Alignment);
+}
+
+void Address::addOffset(llvm::Value *V, llvm::Type *Ty, CGBuilderTy &Builder,
+ CharUnits NewAlignment) {
+ assert(isSigned() &&
+ "shouldn't add an offset if the base pointer isn't signed");
+ ElementType = Ty;
+ Alignment = NewAlignment;
+
+ if (!Offset) {
+ Offset = V;
+ return;
+ }
+
+ Offset = Builder.CreateAdd(Offset, V, "add");
+}
+
+llvm::Value *Address::emitRawPointerSlow(CodeGenFunction &CGF) const {
+ return CGF.getAsNaturalPointerTo(*this, QualType());
+}
+
+llvm::Value *RValue::getAggregatePointer(QualType PointeeType,
+ CodeGenFunction &CGF) const {
+ return CGF.getAsNaturalPointerTo(getAggregateAddress(), PointeeType);
+}
+
+llvm::Value *LValue::getPointer(CodeGenFunction &CGF) const {
+ assert(isSimple());
+ return emitResignedPointer(getType(), CGF);
+}
+
+llvm::Value *LValue::emitResignedPointer(QualType PointeeTy,
+ CodeGenFunction &CGF) const {
+ assert(isSimple());
+ return CGF.getAsNaturalAddressOf(Addr, PointeeTy).getBasePointer();
+}
+
+llvm::Value *LValue::emitRawPointer(CodeGenFunction &CGF) const {
+ assert(isSimple());
+ return Addr.isValid() ? Addr.emitRawPointer(CGF) : nullptr;
+}
+
+llvm::Value *AggValueSlot::getPointer(QualType PointeeTy,
+ CodeGenFunction &CGF) const {
+ Address SignedAddr = CGF.getAsNaturalAddressOf(Addr, PointeeTy);
+ return SignedAddr.getBasePointer();
+}
+
+llvm::Value *AggValueSlot::emitRawPointer(CodeGenFunction &CGF) const {
+ return Addr.isValid() ? Addr.emitRawPointer(CGF) : nullptr;
+}
diff --git a/clang/lib/CodeGen/CGValue.h b/clang/lib/CodeGen/CGValue.h
index 6ed94bd9c7592..27efcf6ac199b 100644
--- a/clang/lib/CodeGen/CGValue.h
+++ b/clang/lib/CodeGen/CGValue.h
@@ -15,6 +15,7 @@
#define LLVM_CLANG_LIB_CODEGEN_CGVALUE_H
#include "Address.h"
+#include "CGPointerAuthInfo.h"
#include "CodeGenTBAA.h"
#include "EHScopeStack.h"
#include "clang/AST/ASTContext.h"
@@ -78,6 +79,8 @@ class RValue {
return std::make_pair(Vals.first, Vals.second);
}
+ bool isSignedAggregate() const { return AggregateAddr.isSigned(); }
+
/// getAggregateAddr() - Return the Value* of the address of the aggregate.
Address getAggregateAddress() const {
assert(isAggregate() && "Not an aggregate!");
@@ -85,9 +88,7 @@ class RValue {
}
llvm::Value *getAggregatePointer(QualType PointeeType,
- CodeGenFunction &CGF) const {
- return getAggregateAddress().getBasePointer();
- }
+ CodeGenFunction &CGF) const;
static RValue getIgnored() {
// FIXME: should we make this a more explicit state?
@@ -317,6 +318,8 @@ class LValue {
bool isNontemporal() const { return Nontemporal; }
void setNontemporal(bool Value) { Nontemporal = Value; }
+ bool isPointerSigned() const { return Addr.isSigned(); }
+
bool isObjCWeak() const {
return Quals.getObjCGCAttr() == Qualifiers::Weak;
}
@@ -352,19 +355,19 @@ class LValue {
}
// simple lvalue
- llvm::Value *getPointer(CodeGenFunction &CGF) const {
- assert(isSimple());
- return Addr.getBasePointer();
- }
- llvm::Value *emitRawPointer(CodeGenFunction &CGF) const {
- assert(isSimple());
- return Addr.isValid() ? Addr.emitRawPointer(CGF) : nullptr;
- }
+ llvm::Value *getPointer(CodeGenFunction &CGF) const;
+ llvm::Value *emitResignedPointer(QualType PointeeTy,
+ CodeGenFunction &CGF) const;
+ llvm::Value *emitRawPointer(CodeGenFunction &CGF) const;
Address getAddress() const { return Addr; }
void setAddress(Address address) { Addr = address; }
+ CGPointerAuthInfo getPointerAuthInfo() const {
+ return Addr.getPointerAuthInfo();
+ }
+
// vector elt lvalue
Address getVectorAddress() const {
assert(isVectorElt());
@@ -636,9 +639,7 @@ class AggValueSlot {
llvm::Value *getPointer(QualType PointeeTy, CodeGenFunction &CGF) const;
- llvm::Value *emitRawPointer(CodeGenFunction &CGF) const {
- return Addr.isValid() ? Addr.emitRawPointer(CGF) : nullptr;
- }
+ llvm::Value *emitRawPointer(CodeGenFunction &CGF) const;
Address getAddress() const {
return Addr;
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index a222bc05e8dab..9e29cddc6f858 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -18,6 +18,7 @@
#include "CGDebugInfo.h"
#include "CGHLSLRuntime.h"
#include "CGOpenMPRuntime.h"
+#include "CGRecordLayout.h"
#include "CodeGenModule.h"
#include "CodeGenPGO.h"
#include "TargetInfo.h"
@@ -558,8 +559,11 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
ReturnBlock.getBlock()->eraseFromParent();
}
if (ReturnValue.isValid()) {
+ // This only matters when ReturnValue isn't signed. ReturnValue is possibly
+ // signed only when the return is Indirect or InAlloca. In that case, a
+ // temporary alloca to store the return value isn't created.
auto *RetAlloca =
- dyn_cast<llvm::AllocaInst>(ReturnValue.emitRawPointer(*this));
+ dyn_cast_or_null<llvm::AllocaInst>(ReturnValue.getPointerIfNotSigned());
if (RetAlloca && RetAlloca->use_empty()) {
RetAlloca->eraseFromParent();
ReturnValue = Address::invalid();
@@ -3137,3 +3141,57 @@ CodeGenFunction::EmitPointerAuthAuth(const CGPointerAuthInfo &PointerAuth,
return EmitPointerAuthCommon(*this, PointerAuth, Pointer,
llvm::Intrinsic::ptrauth_auth);
}
+
+llvm::Value *CodeGenFunction::EmitPointerAuthSign(QualType pointeeType,
+ llvm::Value *pointer) {
+ CGPointerAuthInfo pointerAuth =
+ CGM.getPointerAuthInfoForPointeeType(pointeeType);
+ return EmitPointerAuthSign(pointerAuth, pointer);
+}
+
+llvm::Value *CodeGenFunction::EmitPointerAuthAuth(QualType pointeeType,
+ llvm::Value *pointer) {
+ CGPointerAuthInfo pointerAuth =
+ CGM.getPointerAuthInfoForPointeeType(pointeeType);
+ return EmitPointerAuthAuth(pointerAuth, pointer);
+}
+
+llvm::Value *
+CodeGenFunction::EmitPointerAuthResignCall(llvm::Value *value,
+ const CGPointerAuthInfo &curAuth,
+ const CGPointerAuthInfo &newAuth) {
+ assert(curAuth && newAuth);
+
+ if (curAuth.getAuthenticationMode() !=
+ PointerAuthenticationMode::SignAndAuth ||
+ newAuth.getAuthenticationMode() !=
+ PointerAuthenticationMode::SignAndAuth) {
+ auto authedValue = EmitPointerAuthAuth(curAuth, value);
+ return EmitPointerAuthSign(newAuth, authedValue);
+ }
+ // Convert the pointer to intptr_t before signing it.
+ auto origType = value->getType();
+ value = Builder.CreatePtrToInt(value, IntPtrTy);
+
+ auto curKey = Builder.getInt32(curAuth.getKey());
+ auto newKey = Builder.getInt32(newAuth.getKey());
+
+ llvm::Value *curDiscriminator = curAuth.getDiscriminator();
+ if (!curDiscriminator)
+ curDiscriminator = Builder.getSize(0);
+
+ llvm::Value *newDiscriminator = newAuth.getDiscriminator();
+ if (!newDiscriminator)
+ newDiscriminator = Builder.getSize(0);
+
+ // call i64 @llvm.ptrauth.resign(i64 %pointer,
+ // i32 %curKey, i64 %curDiscriminator,
+ // i32 %newKey, i64 %newDiscriminator)
+ auto intrinsic = CGM.getIntrinsic(llvm::Intrinsic::ptrauth_resign);
+ value = EmitRuntimeCall(
+ intrinsic, {value, curKey, curDiscriminator, newKey, newDiscriminator});
+
+ // Convert back to the original type.
+ value = Builder.CreateIntToPtr(value, origType);
+ return value;
+}
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 5268cc7eda4a2..2ce28f3e4681f 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -185,6 +185,11 @@ template <> struct DominatingValue<Address> {
DominatingLLVMValue::saved_type BasePtr;
llvm::Type *ElementType;
CharUnits Alignment;
+ unsigned PtrAuthKey : 28;
+ PointerAuthenticationMode PtrAuthMode : 2;
+ bool IsIsaPointer : 1;
+ bool AuthenticatesNullValues : 1;
+ DominatingLLVMValue::saved_type PtrAuthDiscriminator;
DominatingLLVMValue::saved_type Offset;
llvm::PointerType *EffectiveType;
};
@@ -193,16 +198,36 @@ template <> struct DominatingValue<Address> {
if (DominatingLLVMValue::needsSaving(value.getBasePointer()) ||
DominatingLLVMValue::needsSaving(value.getOffset()))
return true;
+ CGPointerAuthInfo info = value.getPointerAuthInfo();
+ if (info.isSigned() &&
+ DominatingLLVMValue::needsSaving(info.getDiscriminator()))
+ return true;
return false;
}
static saved_type save(CodeGenFunction &CGF, type value) {
+ bool isSigned = value.getPointerAuthInfo().isSigned();
return {DominatingLLVMValue::save(CGF, value.getBasePointer()),
- value.getElementType(), value.getAlignment(),
- DominatingLLVMValue::save(CGF, value.getOffset()), value.getType()};
+ value.getElementType(),
+ value.getAlignment(),
+ isSigned ? value.getPointerAuthInfo().getKey() : 0,
+ value.getPointerAuthInfo().getAuthenticationMode(),
+ value.getPointerAuthInfo().isIsaPointer(),
+ value.getPointerAuthInfo().authenticatesNullValues(),
+ isSigned ? DominatingLLVMValue::save(
+ CGF, value.getPointerAuthInfo().getDiscriminator())
+ : DominatingLLVMValue::saved_type(),
+ DominatingLLVMValue::save(CGF, value.getOffset()),
+ value.getType()};
}
static type restore(CodeGenFunction &CGF, saved_type value) {
+ CGPointerAuthInfo info;
+ if (value.PtrAuthMode != PointerAuthenticationMode::None)
+ info = CGPointerAuthInfo{
+ value.PtrAuthKey, value.PtrAuthMode, value.IsIsaPointer,
+ value.AuthenticatesNullValues,
+ DominatingLLVMValue::restore(CGF, value.PtrAuthDiscriminator)};
return Address(DominatingLLVMValue::restore(CGF, value.BasePtr),
- value.ElementType, value.Alignment,
+ value.ElementType, value.Alignment, info,
DominatingLLVMValue::restore(CGF, value.Offset));
}
};
@@ -2665,15 +2690,7 @@ class CodeGenFunction : public CodeGenTypeCache {
llvm::BasicBlock *LHSBlock,
llvm::BasicBlock *RHSBlock,
llvm::BasicBlock *MergeBlock,
- QualType MergedType) {
- Builder.SetInsertPoint(MergeBlock);
- llvm::PHINode *PtrPhi = Builder.CreatePHI(LHS.getType(), 2, "cond");
- PtrPhi->addIncoming(LHS.getBasePointer(), LHSBlock);
- PtrPhi->addIncoming(RHS.getBasePointer(), RHSBlock);
- LHS.replaceBasePointer(PtrPhi);
- LHS.setAlignment(std::min(LHS.getAlignment(), RHS.getAlignment()));
- return LHS;
- }
+ QualType MergedType);
/// Construct an address with the natural alignment of T. If a pointer to T
/// is expected to be signed, the pointer passed to this function must have
@@ -2687,7 +2704,8 @@ class CodeGenFunction : public CodeGenTypeCache {
if (Alignment.isZero())
Alignment =
CGM.getNaturalTypeAlignment(T, BaseInfo, TBAAInfo, ForPointeeType);
- return Address(Ptr, ConvertTypeForMem(T), Alignment, nullptr,
+ return Address(Ptr, ConvertTypeForMem(T), Alignment,
+ CGM.getPointerAuthInfoForPointeeType(T), nullptr,
IsKnownNonNull);
}
@@ -4423,10 +4441,6 @@ class CodeGenFunction : public CodeGenTypeCache {
CXXDtorType Type,
const CXXRecordDecl *RD);
- llvm::Value *getAsNaturalPointerTo(Address Addr, QualType PointeeType) {
- return Addr.getBasePointer();
- }
-
bool isPointerKnownNonNull(const Expr *E);
/// Create the discriminator from the storage address and the entity hash.
@@ -4436,16 +4450,41 @@ class CodeGenFunction : public CodeGenTypeCache {
llvm::Value *StorageAddress,
GlobalDecl SchemaDecl,
QualType SchemaType);
+
llvm::Value *EmitPointerAuthSign(QualType PointeeType, llvm::Value *Pointer);
llvm::Value *EmitPointerAuthSign(const CGPointerAuthInfo &Info,
llvm::Value *Pointer);
+
+ llvm::Value *EmitPointerAuthAuth(QualType PointeeType, llvm::Value *Pointer);
llvm::Value *EmitPointerAuthAuth(const CGPointerAuthInfo &Info,
llvm::Value *Pointer);
+ llvm::Value *EmitPointerAuthResign(llvm::Value *Pointer, QualType PointerType,
+ const CGPointerAuthInfo &CurAuthInfo,
+ const CGPointerAuthInfo &NewAuthInfo,
+ bool IsKnownNonNull);
+ llvm::Value *EmitPointerAuthResignCall(llvm::Value *Pointer,
+ const CGPointerAuthInfo &CurInfo,
+ const CGPointerAuthInfo &NewInfo);
+
void EmitPointerAuthOperandBundle(
const CGPointerAuthInfo &Info,
SmallVectorImpl<llvm::OperandBundleDef> &Bundles);
+ llvm::Value *AuthPointerToPointerCast(llvm::Value *ResultPtr,
+ QualType SourceType, QualType DestType);
+ Address AuthPointerToPointerCast(Address Ptr, QualType SourceType,
+ QualType DestType);
+
+ Address EmitPointerAuthSign(Address Addr, QualType PointeeType);
+ Address EmitPointerAuthAuth(Address Addr, QualType PointeeType);
+
+ Address getAsNaturalAddressOf(Address Addr, QualType PointeeTy);
+
+ llvm::Value *getAsNaturalPointerTo(Address Addr, QualType PointeeType) {
+ return getAsNaturalAddressOf(Addr, PointeeType).getBasePointer();
+ }
+
// Return the copy constructor name with the prefix "__copy_constructor_"
// removed.
static std::string getNonTrivialCopyConstructorStr(QualType QT,
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index caa3786c033b5..7c6078df0af82 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -986,6 +986,9 @@ class CodeGenModule : public CodeGenTypeCache {
GlobalDecl SchemaDecl,
QualType SchemaType);
+ llvm::Constant *getConstantSignedPointer(llvm::Constant *Pointer,
+ QualType PointeeType);
+
llvm::Constant *
getConstantSignedPointer(llvm::Constant *Pointer, unsigned Key,
llvm::Constant *StorageAddress,
diff --git a/clang/lib/Headers/ptrauth.h b/clang/lib/Headers/ptrauth.h
index 40ac6dcac2ab8..e0bc8c4f9acf7 100644
--- a/clang/lib/Headers/ptrauth.h
+++ b/clang/lib/Headers/ptrauth.h
@@ -58,6 +58,21 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t;
/* Authenticating a pointer that was not signed with the given key
and extra-data value will (likely) fail by trapping. */
+/* The null function pointer is always the all-zero bit pattern.
+ Signing an all-zero bit pattern will embed a (likely) non-zero
+ signature in the result, and so the result will not seem to be
+ a null function pointer. Authenticating this value will yield
+ a null function pointer back. However, authenticating an
+ all-zero bit pattern will probably fail, because the
+ authentication will expect a (likely) non-zero signature to
+ embedded in the value.
+
+ Because of this, if a pointer may validly be null, you should
+ check for null before attempting to authenticate it with one
+ of these intrinsics. This is not necessary when using the
+ __ptrauth qualifier; the compiler will perform this check
+ automatically. */
+
#if __has_feature(ptrauth_intrinsics)
/* Strip the signature from a value without authenticating it.
diff --git a/clang/test/CodeGen/ptrauth-function-lvalue-cast-disc.c b/clang/test/CodeGen/ptrauth-function-lvalue-cast-disc.c
new file mode 100644
index 0000000000000..6712a6cf417b9
--- /dev/null
+++ b/clang/test/CodeGen/ptrauth-function-lvalue-cast-disc.c
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 %s -triple arm64e-apple-ios13 -fptrauth-calls -fptrauth-intrinsics -emit-llvm -o- -fptrauth-function-pointer-type-discrimination | FileCheck %s
+
+typedef void (*fptr_t)(void);
+
+char *cptr;
+void (*fptr)(void);
+
+// CHECK-LABEL: define void @test1
+void test1() {
+ // CHECK: [[LOAD:%.*]] = load ptr, ptr @cptr
+ // CHECK: [[TOINT:%.*]] = ptrtoint ptr [[LOAD]] to i64
+ // CHECK: call i64 @llvm.ptrauth.resign(i64 [[TOINT]], i32 0, i64 0, i32 0, i64 18983)
+ // CHECK: call void {{.*}}() [ "ptrauth"(i32 0, i64 18983) ]
+
+ (*(fptr_t)cptr)();
+}
+
+// CHECK-LABEL: define i8 @test2
+char test2() {
+ return *(char *)fptr;
+
+ // CHECK: [[LOAD:%.*]] = load ptr, ptr @fptr
+ // CHECK: [[CMP:%.*]] = icmp ne ptr [[LOAD]], null
+
+ // CHECK: [[TOINT:%.*]] = ptrtoint ptr [[LOAD]] to i64
+ // CHECK: call i64 @llvm.ptrauth.resign(i64 [[TOINT]], i32 0, i64 18983, i32 0, i64 0)
+}
+
+// CHECK-LABEL: define void @test4
+void test4() {
+ (*((fptr_t)(&*((char *)(&*(fptr_t)cptr)))))();
+
+ // CHECK: [[LOAD:%.*]] = load ptr, ptr @cptr
+ // CHECK-NEXT: [[CAST4:%.*]] = ptrtoint ptr [[LOAD]] to i64
+ // CHECK-NEXT: [[RESIGN:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[CAST4]], i32 0, i64 0, i32 0, i64 18983)
+ // CHECK-NEXT: [[CAST5:%.*]] = inttoptr i64 [[RESIGN]] to ptr
+ // CHECK-NEXT: call void [[CAST5]]() [ "ptrauth"(i32 0, i64 18983) ]
+}
+
+void *vptr;
+void test5() {
+ vptr = &*(char *)fptr;
+
+ // CHECK: [[LOAD:%.*]] = load ptr, ptr @fptr
+ // CHECK-NEXT: [[CMP]] = icmp ne ptr [[LOAD]], null
+ // CHECK-NEXT: br i1 [[CMP]], label %[[NONNULL:.*]], label %[[CONT:.*]]
+
+ // CHECK: [[NONNULL]]:
+ // CHECK: [[RESIGN:%.*]] = call i64 @llvm.ptrauth.resign(i64 {{.*}}, i32 0, i64 18983, i32 0, i64 0)
+ // CHECK: [[CAST:%.*]] = inttoptr i64 [[RESIGN]] to ptr
+
+ // CHECK: [[CONT]]:
+ // CHECK: [[PHI:%.*]] = phi ptr [ null, {{.*}} ], [ [[CAST]], %[[NONNULL]] ]
+ // CHECK: store ptr [[PHI]], ptr @vptr
+}
diff --git a/clang/test/CodeGen/ptrauth-function-type-discriminator-cast.c b/clang/test/CodeGen/ptrauth-function-type-discriminator-cast.c
new file mode 100644
index 0000000000000..fa12e2c7ec19c
--- /dev/null
+++ b/clang/test/CodeGen/ptrauth-function-type-discriminator-cast.c
@@ -0,0 +1,85 @@
+// RUN: %clang_cc1 %s -fptrauth-function-pointer-type-discrimination -triple arm64e-apple-ios13 -fptrauth-calls -fptrauth-intrinsics -disable-llvm-passes -emit-llvm -o- | FileCheck %s
+// RUN: %clang_cc1 -xc++ %s -fptrauth-function-pointer-type-discrimination -triple arm64e-apple-ios13 -fptrauth-calls -fptrauth-intrinsics -disable-llvm-passes -emit-llvm -o- | FileCheck %s --check-prefixes=CHECK,CHECKCXX
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void f(void);
+void f2(int);
+void (*fptr)(void);
+void *opaque;
+unsigned long uintptr;
+
+#ifdef __cplusplus
+struct ptr_member {
+ void (*fptr_)(int) = 0;
+};
+ptr_member pm;
+void (*test_member)() = (void (*)())pm.fptr_;
+
+// CHECKCXX-LABEL: define internal void @__cxx_global_var_init
+// CHECKCXX: call i64 @llvm.ptrauth.resign(i64 {{.*}}, i32 0, i64 2712, i32 0, i64 18983)
+#endif
+
+
+// CHECK-LABEL: define void @test_cast_to_opaque
+void test_cast_to_opaque() {
+ opaque = (void *)f;
+
+ // CHECK: [[RESIGN_VAL:%.*]] = call i64 @llvm.ptrauth.resign(i64 ptrtoint (ptr ptrauth (ptr @f, i32 0, i64 18983) to i64), i32 0, i64 18983, i32 0, i64 0)
+ // CHECK: [[RESIGN_PTR:%.*]] = inttoptr i64 [[RESIGN_VAL]] to ptr
+}
+
+// CHECK-LABEL: define void @test_cast_from_opaque
+void test_cast_from_opaque() {
+ fptr = (void (*)(void))opaque;
+
+ // CHECK: [[LOAD:%.*]] = load ptr, ptr @opaque
+ // CHECK: [[CMP:%.*]] = icmp ne ptr [[LOAD]], null
+ // CHECK: br i1 [[CMP]], label %[[RESIGN_LAB:.*]], label
+
+ // CHECK: [[RESIGN_LAB]]:
+ // CHECK: [[INT:%.*]] = ptrtoint ptr [[LOAD]] to i64
+ // CHECK: [[RESIGN_INT:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[INT]], i32 0, i64 0, i32 0, i64 18983)
+}
+
+// CHECK-LABEL: define void @test_cast_to_intptr
+void test_cast_to_intptr() {
+ uintptr = (unsigned long)fptr;
+
+ // CHECK: [[ENTRY:.*]]:
+ // CHECK: [[LOAD:%.*]] = load ptr, ptr @fptr
+ // CHECK: [[CMP:%.*]] = icmp ne ptr [[LOAD]], null
+ // CHECK: br i1 [[CMP]], label %[[RESIGN_LAB:.*]], label %[[RESIGN_CONT:.*]]
+
+ // CHECK: [[RESIGN_LAB]]:
+ // CHECK: [[INT:%.*]] = ptrtoint ptr [[LOAD]] to i64
+ // CHECK: [[RESIGN_INT:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[INT]], i32 0, i64 18983, i32 0, i64 0)
+ // CHECK: [[RESIGN:%.*]] = inttoptr i64 [[RESIGN_INT]] to ptr
+ // CHECK: br label %[[RESIGN_CONT]]
+
+ // CHECK: [[RESIGN_CONT]]:
+ // CHECK: phi ptr [ null, %[[ENTRY]] ], [ [[RESIGN]], %[[RESIGN_LAB]] ]
+}
+
+// CHECK-LABEL: define void @test_function_to_function_cast
+void test_function_to_function_cast() {
+ void (*fptr2)(int) = (void (*)(int))fptr;
+ // CHECK: call i64 @llvm.ptrauth.resign(i64 {{.*}}, i32 0, i64 18983, i32 0, i64 2712)
+}
+
+// CHECK-LABEL: define void @test_call_lvalue_cast
+void test_call_lvalue_cast() {
+ (*(void (*)(int))f)(42);
+
+ // CHECK: entry:
+ // CHECK-NEXT: [[RESIGN:%.*]] = call i64 @llvm.ptrauth.resign(i64 ptrtoint (ptr ptrauth (ptr @f, i32 0, i64 18983) to i64), i32 0, i64 18983, i32 0, i64 2712)
+ // CHECK-NEXT: [[RESIGN_INT:%.*]] = inttoptr i64 [[RESIGN]] to ptr
+ // CHECK-NEXT: call void [[RESIGN_INT]](i32 noundef 42) [ "ptrauth"(i32 0, i64 2712) ]
+}
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/clang/test/CodeGen/ptrauth.c b/clang/test/CodeGen/ptrauth.c
new file mode 100644
index 0000000000000..dff6dbeb8508a
--- /dev/null
+++ b/clang/test/CodeGen/ptrauth.c
@@ -0,0 +1,77 @@
+// RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -emit-llvm %s -o - | FileCheck -check-prefix=CHECK -check-prefix=NOPCH %s
+// RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -emit-pch %s -o %t.ast
+// RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -emit-llvm -x ast -o - %t.ast | FileCheck -check-prefix=CHECK -check-prefix=PCH %s
+
+#define FNPTRKEY 0
+
+void (*fnptr)(void);
+long discriminator;
+
+extern void external_function(void);
+// CHECK: @fptr1 = global ptr ptrauth (ptr @external_function, i32 0, i64 18983)
+void (*fptr1)(void) = external_function;
+// CHECK: @fptr2 = global ptr ptrauth (ptr @external_function, i32 0, i64 18983)
+void (*fptr2)(void) = &external_function;
+
+// CHECK: @fptr3 = global ptr ptrauth (ptr @external_function, i32 2, i64 26)
+void (*fptr3)(void) = __builtin_ptrauth_sign_constant(&external_function, 2, 26);
+
+// CHECK: @fptr4 = global ptr ptrauth (ptr @external_function, i32 2, i64 26, ptr @fptr4)
+void (*fptr4)(void) = __builtin_ptrauth_sign_constant(&external_function, 2, __builtin_ptrauth_blend_discriminator(&fptr4, 26));
+
+// CHECK-LABEL: define void @test_call()
+void test_call() {
+ // CHECK: [[T0:%.*]] = load ptr, ptr @fnptr,
+ // CHECK-NEXT: call void [[T0]]() [ "ptrauth"(i32 0, i64 18983) ]
+ fnptr();
+}
+
+// CHECK-LABEL: define void @test_direct_call()
+void test_direct_call() {
+ // CHECK: call void @test_call(){{$}}
+ test_call();
+}
+
+void abort();
+// CHECK-LABEL: define void @test_direct_builtin_call()
+void test_direct_builtin_call() {
+ // CHECK: call void @abort() {{#[0-9]+$}}
+ abort();
+}
+
+// CHECK-LABEL: define ptr @test_function_pointer()
+// CHECK: ret ptr ptrauth (ptr @external_function, i32 0, i64 18983)
+void (*test_function_pointer())(void) {
+ return external_function;
+}
+
+struct InitiallyIncomplete;
+extern struct InitiallyIncomplete returns_initially_incomplete(void);
+// CHECK-LABEL: define void @use_while_incomplete()
+void use_while_incomplete() {
+ // NOPCH: [[VAR:%.*]] = alloca ptr,
+ // NOPCH-NEXT: store ptr ptrauth (ptr @returns_initially_incomplete, i32 0, i64 25106), ptr [[VAR]]
+ // PCH: [[VAR:%.*]] = alloca ptr,
+ // PCH-NEXT: store ptr ptrauth (ptr @returns_initially_incomplete, i32 0, i64 25106), ptr [[VAR]]
+ struct InitiallyIncomplete (*fnptr)(void) = &returns_initially_incomplete;
+}
+struct InitiallyIncomplete { int x; };
+// CHECK-LABEL: define void @use_while_complete()
+void use_while_complete() {
+ // CHECK: [[VAR:%.*]] = alloca ptr,
+ // CHECK-NEXT: store ptr ptrauth (ptr @returns_initially_incomplete, i32 0, i64 25106), ptr [[VAR]]
+ // CHECK-NEXT: ret void
+ struct InitiallyIncomplete (*fnptr)(void) = &returns_initially_incomplete;
+}
+
+// CHECK-LABEL: define void @test_memcpy_inline(
+// CHECK-NOT: call{{.*}}memcpy
+
+extern inline __attribute__((__always_inline__))
+void *memcpy(void *d, const void *s, unsigned long) {
+ return 0;
+}
+
+void test_memcpy_inline(char *d, char *s) {
+ memcpy(d, s, 4);
+}
diff --git a/clang/test/Preprocessor/ptrauth_feature.c b/clang/test/Preprocessor/ptrauth_feature.c
index 88b6982c01657..c19ac21d42139 100644
--- a/clang/test/Preprocessor/ptrauth_feature.c
+++ b/clang/test/Preprocessor/ptrauth_feature.c
@@ -65,6 +65,16 @@
// RUN: FileCheck %s --check-prefixes=INTRIN,CALLS,RETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,NOINITFINI,FUNC
+// RUN: %clang_cc1 -E %s -triple=aarch64 \
+// RUN: -fptrauth-intrinsics \
+// RUN: -fptrauth-calls \
+// RUN: -fptrauth-returns \
+// RUN: -fptrauth-vtable-pointer-address-discrimination \
+// RUN: -fptrauth-vtable-pointer-type-discrimination \
+// RUN: -fptrauth-function-pointer-type-discrimination | \
+// RUN: FileCheck %s --check-prefixes=INTRIN,CALLS,RETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,NOINITFINI,FUNC
+
+
#if __has_feature(ptrauth_intrinsics)
// INTRIN: has_ptrauth_intrinsics
void has_ptrauth_intrinsics() {}
diff --git a/clang/test/Sema/ptrauth-function-type-discriminatior.c b/clang/test/Sema/ptrauth-function-type-discriminatior.c
new file mode 100644
index 0000000000000..0dacdf35f2038
--- /dev/null
+++ b/clang/test/Sema/ptrauth-function-type-discriminatior.c
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 %s -triple arm64e-apple-ios13 -verify -xobjective-c -fblocks
+// RUN: %clang_cc1 %s -triple arm64e-apple-ios13 -verify -xc
+// RUN: %clang_cc1 %s -triple arm64e-apple-ios13 -verify -xc++
+
+// expected-no-diagnostics
+
+#define discm(x) __builtin_ptrauth_type_discriminator(x)
+
+struct Complete {};
+struct Incomplete;
+
+#ifndef __cplusplus
+enum EIncomplete;
+#endif
+
+enum EComplete { enumerator };
+
+_Static_assert(discm(void(void)) == 18983, "");
+_Static_assert(discm(void()) == discm(void(void)), "");
+_Static_assert(discm(void(int *)) == discm(void(float *)), "");
+_Static_assert(discm(void(int *)) == discm(void(struct Incomplete *)), "");
+_Static_assert(discm(void(struct Complete *)) == discm(void(struct Incomplete *)), "");
+_Static_assert(discm(void(int *)) != discm(void(int)), "");
+_Static_assert(discm(void(int)) != discm(void(int, ...)), "");
+_Static_assert(discm(_Atomic(int *)()) == discm(int *()), "");
+#ifndef __cplusplus
+_Static_assert(discm(enum EIncomplete()) == discm(int()), "");
+#endif
+_Static_assert(discm(enum EComplete()) == discm(int()), "");
+_Static_assert(discm(unsigned long()) == discm(int()), "");
+_Static_assert(discm(char()) == discm(int()), "");
+_Static_assert(discm(int(int (*)[10])) == discm(int(int (*)[9])), "");
+_Static_assert(discm(void (int[10])) == discm(void (int *)), "");
+_Static_assert(discm(void (int[*])) == discm(void (int *)), "");
+_Static_assert(discm(void (void ())) == discm(void (void (*))), "");
+
+#ifndef __cplusplus
+typedef struct {} foo;
+struct foo {};
+_Static_assert(discm(void(foo)) == discm(void(struct foo)), "");
+#endif
+
+#ifdef __OBJC__
+ at interface I @end
+_Static_assert(discm(id()) == discm(I*()), "");
+_Static_assert(discm(id()) == discm(void*()), "");
+_Static_assert(discm(id()) == discm(Class()), "");
+_Static_assert(discm(void(^())()) == discm(id()), "");
+#endif
+
+#ifdef __cplusplus
+_Static_assert(discm(void(Complete &)) != discm(void(Complete *)), "");
+_Static_assert(discm(void(Complete &)) != discm(void(Complete &&)), "");
+_Static_assert(discm(void(Incomplete &)) != discm(void(Incomplete &&)), "");
+/* Descend into array and function types when using references. */
+_Static_assert(discm(void(void (&)())) != discm(void (void (&)(int))), "");
+_Static_assert(discm(void(void (&)())) != discm(void (int (&)())), "");
+_Static_assert(discm(void(int (&)[10])) == discm(void(int (&)[9])), "");
+_Static_assert(discm(void(int (&)[10])) == discm(void(int (&)[])), "");
+_Static_assert(discm(void(int (&)[10])) != discm(void(float (&)[10])), "");
+#endif
+
+typedef __attribute__((ext_vector_type(4))) float vec4;
+typedef __attribute__((ext_vector_type(16))) char char_vec16;
+_Static_assert(discm(void (vec4)) == discm(void (char_vec16)), "");
>From d7ad33a22780ba8edd1bf53ca2096a4ecf278385 Mon Sep 17 00:00:00 2001
From: Akira Hatanaka <ahatanak at gmail.com>
Date: Sun, 14 Jul 2024 15:58:04 -0700
Subject: [PATCH 4/4] revert unneeded changes
---
clang/include/clang/AST/ASTContext.h | 2 +-
clang/include/clang/AST/Type.h | 5 +-
clang/lib/AST/ASTContext.cpp | 12 ++-
clang/lib/CodeGen/Address.h | 28 +------
clang/lib/CodeGen/CGBlocks.cpp | 4 +-
clang/lib/CodeGen/CGBuilder.h | 108 ++++++++------------------
clang/lib/CodeGen/CGBuiltin.cpp | 3 +-
clang/lib/CodeGen/CGCall.cpp | 15 ++--
clang/lib/CodeGen/CGException.cpp | 4 +-
clang/lib/CodeGen/CGExpr.cpp | 22 ++----
clang/lib/CodeGen/CGExprAgg.cpp | 7 +-
clang/lib/CodeGen/CGExprCXX.cpp | 9 +--
clang/lib/CodeGen/CGExprConstant.cpp | 16 +---
clang/lib/CodeGen/CGExprScalar.cpp | 22 ++----
clang/lib/CodeGen/CGObjCMac.cpp | 2 +-
clang/lib/CodeGen/CGPointerAuth.cpp | 88 +--------------------
clang/lib/CodeGen/CGValue.h | 12 +--
clang/lib/CodeGen/CodeGenFunction.cpp | 6 +-
clang/lib/CodeGen/CodeGenFunction.h | 41 +++-------
clang/lib/CodeGen/CodeGenModule.h | 3 -
clang/lib/CodeGen/ItaniumCXXABI.cpp | 2 +-
21 files changed, 97 insertions(+), 314 deletions(-)
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 8ba0c943a9c86..57022e75073fe 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1284,7 +1284,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
getPointerAuthVTablePointerDiscriminator(const CXXRecordDecl *RD);
/// Return the "other" type-specific discriminator for the given type.
- uint16_t getPointerAuthTypeDiscriminator(QualType T);
+ uint16_t getPointerAuthTypeDiscriminator(QualType T) const;
/// Apply Objective-C protocol qualifiers to the given type.
/// \param allowOnPointerType specifies if we can apply protocol
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index bf242debe479a..3aa0f05b0ab60 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -2507,7 +2507,6 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
bool isFunctionProtoType() const { return getAs<FunctionProtoType>(); }
bool isPointerType() const;
bool isSignableType() const;
- bool isSignablePointerType() const;
bool isAnyPointerType() const; // Any C pointer or ObjC object pointer
bool isCountAttributedType() const;
bool isBlockPointerType() const;
@@ -8003,9 +8002,7 @@ inline bool Type::isAnyPointerType() const {
return isPointerType() || isObjCObjectPointerType();
}
-inline bool Type::isSignableType() const { return isSignablePointerType(); }
-
-inline bool Type::isSignablePointerType() const { return isPointerType(); }
+inline bool Type::isSignableType() const { return isPointerType(); }
inline bool Type::isBlockPointerType() const {
return isa<BlockPointerType>(CanonicalType);
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 18dfe51e167e0..497579dcc56b6 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -3400,7 +3400,7 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx,
}
}
-uint16_t ASTContext::getPointerAuthTypeDiscriminator(QualType T) {
+uint16_t ASTContext::getPointerAuthTypeDiscriminator(QualType T) const {
assert(!T->isDependentType() &&
"cannot compute type discriminator of a dependent type");
@@ -3410,13 +3410,11 @@ uint16_t ASTContext::getPointerAuthTypeDiscriminator(QualType T) {
if (T->isFunctionPointerType() || T->isFunctionReferenceType())
T = T->getPointeeType();
- if (T->isFunctionType()) {
+ if (T->isFunctionType())
encodeTypeForFunctionPointerAuth(*this, Out, T);
- } else {
- T = T.getUnqualifiedType();
- std::unique_ptr<MangleContext> MC(createMangleContext());
- MC->mangleCanonicalTypeName(T, Out);
- }
+ else
+ llvm_unreachable(
+ "type discrimination of non-function type not implemented yet");
return llvm::getPointerAuthStableSipHash(Str);
}
diff --git a/clang/lib/CodeGen/Address.h b/clang/lib/CodeGen/Address.h
index 1d2c453f25523..17232772ce8e1 100644
--- a/clang/lib/CodeGen/Address.h
+++ b/clang/lib/CodeGen/Address.h
@@ -180,11 +180,6 @@ class Address {
static Address invalid() { return Address(nullptr); }
bool isValid() const { return Pointer.getPointer() != nullptr; }
- llvm::Value *getPointerIfNotSigned() const {
- assert(isValid() && "pointer isn't valid");
- return !isSigned() ? Pointer.getPointer() : nullptr;
- }
-
/// This function is used in situations where the caller is doing some sort of
/// opaque "laundering" of the pointer.
void replaceBasePointer(llvm::Value *P) {
@@ -204,11 +199,6 @@ class Address {
return Pointer.getPointer();
}
- llvm::Value *getUnsignedPointer() const {
- assert(!isSigned() && "cannot call this function if pointer is signed");
- return getBasePointer();
- }
-
/// Return the type of the pointer value.
llvm::PointerType *getType() const {
return llvm::PointerType::get(
@@ -252,14 +242,6 @@ class Address {
return *this;
}
- /// Add a constant offset.
- void addOffset(CharUnits V, llvm::Type *Ty, CGBuilderTy &Builder);
-
- /// Add a variable offset.
- /// \param V An llvm value holding a variable offset.
- void addOffset(llvm::Value *V, llvm::Type *Ty, CGBuilderTy &Builder,
- CharUnits NewAlignment);
-
bool hasOffset() const { return Offset; }
llvm::Value *getOffset() const { return Offset; }
@@ -270,9 +252,7 @@ class Address {
/// Return the pointer contained in this class after authenticating it and
/// adding offset to it if necessary.
llvm::Value *emitRawPointer(CodeGenFunction &CGF) const {
- if (!isSigned())
- return getUnsignedPointer();
- return emitRawPointerSlow(CGF);
+ return getBasePointer();
}
/// Return address with different pointer, but same element type and
@@ -303,9 +283,9 @@ class Address {
};
inline RawAddress::RawAddress(Address Addr)
- : PointerAndKnownNonNull(
- Addr.isValid() ? Addr.getUnsignedPointer() : nullptr,
- Addr.isValid() ? Addr.isKnownNonNull() : NotKnownNonNull),
+ : PointerAndKnownNonNull(Addr.isValid() ? Addr.getBasePointer() : nullptr,
+ Addr.isValid() ? Addr.isKnownNonNull()
+ : NotKnownNonNull),
ElementType(Addr.isValid() ? Addr.getElementType() : nullptr),
Alignment(Addr.isValid() ? Addr.getAlignment() : CharUnits::Zero()) {}
diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp
index 2affd93c6b9a2..066139b1c78c7 100644
--- a/clang/lib/CodeGen/CGBlocks.cpp
+++ b/clang/lib/CodeGen/CGBlocks.cpp
@@ -1974,8 +1974,8 @@ CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) {
// it. It's not quite worth the annoyance to avoid creating it in the
// first place.
if (!needsEHCleanup(captureType.isDestructedType()))
- if (auto *I = cast_or_null<llvm::Instruction>(
- dstField.getPointerIfNotSigned()))
+ if (auto *I =
+ cast_or_null<llvm::Instruction>(dstField.getBasePointer()))
I->eraseFromParent();
}
break;
diff --git a/clang/lib/CodeGen/CGBuilder.h b/clang/lib/CodeGen/CGBuilder.h
index 48b3067494062..6625c662e041f 100644
--- a/clang/lib/CodeGen/CGBuilder.h
+++ b/clang/lib/CodeGen/CGBuilder.h
@@ -15,7 +15,6 @@
#include "llvm/Analysis/Utils/Local.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
namespace clang {
@@ -57,27 +56,7 @@ class CGBuilderTy : public CGBuilderBaseTy {
CodeGenFunction *getCGF() const { return getInserter().CGF; }
llvm::Value *emitRawPointerFromAddress(Address Addr) const {
- if (!Addr.isSigned())
- return Addr.getUnsignedPointer();
- assert(getCGF() && "CGF not set");
- return Addr.emitRawPointerSlow(*getCGF());
- }
-
- /// Helper function to compute a GEP's offset and add it to Addr.
- Address addGEPOffset(Address Addr, ArrayRef<llvm::Value *> IdxList,
- CharUnits Align, bool IsInBounds, const Twine &Name) {
- typedef ArrayRef<llvm::Value *>::const_iterator IdxItTy;
- typedef llvm::generic_gep_type_iterator<IdxItTy> GEPTypeIt;
- const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
- GEPTypeIt GTI = GEPTypeIt::begin(Addr.getElementType(), IdxList.begin());
- IdxItTy IdxBegin = IdxList.begin(), IdxEnd = IdxList.end();
- llvm::Type *GEPType = Addr.getType();
- SmallString<12> Buffer;
- StringRef GEPName = Name.toStringRef(Buffer);
- std::pair<llvm::Value *, llvm::Type *> OffsetAndType = llvm::EmitGEPOffset(
- this, DL, GTI, IdxBegin, IdxEnd, GEPType, GEPName, IsInBounds, false);
- Addr.addOffset(OffsetAndType.first, OffsetAndType.second, *this, Align);
- return Addr;
+ return Addr.getBasePointer();
}
template <bool IsInBounds>
@@ -243,14 +222,11 @@ class CGBuilderTy : public CGBuilderBaseTy {
const llvm::StructLayout *Layout = DL.getStructLayout(ElTy);
auto Offset = CharUnits::fromQuantity(Layout->getElementOffset(Index));
- if (!Addr.isSigned())
- return Address(CreateStructGEP(Addr.getElementType(),
- Addr.getUnsignedPointer(), Index, Name),
- ElTy->getElementType(Index),
- Addr.getAlignment().alignmentAtOffset(Offset),
- Addr.isKnownNonNull());
- Addr.addOffset(Offset, ElTy->getTypeAtIndex(Index), *this);
- return Addr;
+ return Address(CreateStructGEP(Addr.getElementType(), Addr.getBasePointer(),
+ Index, Name),
+ ElTy->getElementType(Index),
+ Addr.getAlignment().alignmentAtOffset(Offset),
+ Addr.isKnownNonNull());
}
/// Given
@@ -268,15 +244,12 @@ class CGBuilderTy : public CGBuilderBaseTy {
CharUnits EltSize =
CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy->getElementType()));
- if (!Addr.isSigned())
- return Address(
- CreateInBoundsGEP(Addr.getElementType(), Addr.getUnsignedPointer(),
- {getSize(CharUnits::Zero()), getSize(Index)}, Name),
- ElTy->getElementType(),
- Addr.getAlignment().alignmentAtOffset(Index * EltSize),
- Addr.isKnownNonNull());
- Addr.addOffset(Index * EltSize, ElTy, *this);
- return Addr;
+ return Address(
+ CreateInBoundsGEP(Addr.getElementType(), Addr.getBasePointer(),
+ {getSize(CharUnits::Zero()), getSize(Index)}, Name),
+ ElTy->getElementType(),
+ Addr.getAlignment().alignmentAtOffset(Index * EltSize),
+ Addr.isKnownNonNull());
}
/// Given
@@ -290,14 +263,10 @@ class CGBuilderTy : public CGBuilderBaseTy {
const llvm::DataLayout &DL = BB->getDataLayout();
CharUnits EltSize = CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy));
- if (!Addr.isSigned())
- return Address(CreateInBoundsGEP(ElTy, Addr.getUnsignedPointer(),
- getSize(Index), Name),
- ElTy,
- Addr.getAlignment().alignmentAtOffset(Index * EltSize),
- Addr.isKnownNonNull());
- Addr.addOffset(Index * EltSize, ElTy, *this);
- return Addr;
+ return Address(
+ CreateInBoundsGEP(ElTy, Addr.getBasePointer(), getSize(Index), Name),
+ ElTy, Addr.getAlignment().alignmentAtOffset(Index * EltSize),
+ Addr.isKnownNonNull());
}
/// Given
@@ -311,12 +280,9 @@ class CGBuilderTy : public CGBuilderBaseTy {
const llvm::DataLayout &DL = BB->getDataLayout();
CharUnits EltSize = CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy));
- if (!Addr.isSigned())
- return Address(
- CreateGEP(ElTy, Addr.getUnsignedPointer(), getSize(Index), Name),
- ElTy, Addr.getAlignment().alignmentAtOffset(Index * EltSize));
- Addr.addOffset(Index * EltSize, ElTy, *this);
- return Addr;
+ return Address(CreateGEP(ElTy, Addr.getBasePointer(), getSize(Index), Name),
+ Addr.getElementType(),
+ Addr.getAlignment().alignmentAtOffset(Index * EltSize));
}
/// Create GEP with single dynamic index. The address alignment is reduced
@@ -338,28 +304,20 @@ class CGBuilderTy : public CGBuilderBaseTy {
Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset,
const llvm::Twine &Name = "") {
assert(Addr.getElementType() == TypeCache.Int8Ty);
-
- if (!Addr.isSigned())
- return Address(
- CreateInBoundsGEP(Addr.getElementType(), Addr.getUnsignedPointer(),
- getSize(Offset), Name),
- Addr.getElementType(), Addr.getAlignment().alignmentAtOffset(Offset),
- Addr.isKnownNonNull());
- Addr.addOffset(Offset, TypeCache.Int8Ty, *this);
- return Addr;
+ return Address(
+ CreateInBoundsGEP(Addr.getElementType(), Addr.getBasePointer(),
+ getSize(Offset), Name),
+ Addr.getElementType(), Addr.getAlignment().alignmentAtOffset(Offset),
+ Addr.isKnownNonNull());
}
Address CreateConstByteGEP(Address Addr, CharUnits Offset,
const llvm::Twine &Name = "") {
assert(Addr.getElementType() == TypeCache.Int8Ty);
-
- if (!Addr.isSigned())
- return Address(CreateGEP(Addr.getElementType(), Addr.getUnsignedPointer(),
- getSize(Offset), Name),
- Addr.getElementType(),
- Addr.getAlignment().alignmentAtOffset(Offset));
- Addr.addOffset(Offset, TypeCache.Int8Ty, *this);
- return Addr;
+ return Address(CreateGEP(Addr.getElementType(), Addr.getBasePointer(),
+ getSize(Offset), Name),
+ Addr.getElementType(),
+ Addr.getAlignment().alignmentAtOffset(Offset));
}
using CGBuilderBaseTy::CreateConstInBoundsGEP2_32;
@@ -386,12 +344,10 @@ class CGBuilderTy : public CGBuilderBaseTy {
Address CreateInBoundsGEP(Address Addr, ArrayRef<llvm::Value *> IdxList,
llvm::Type *ElementType, CharUnits Align,
const Twine &Name = "") {
- if (!Addr.isSigned())
- return RawAddress(CreateInBoundsGEP(Addr.getElementType(),
- emitRawPointerFromAddress(Addr),
- IdxList, Name),
- ElementType, Align, Addr.isKnownNonNull());
- return addGEPOffset(Addr, IdxList, Align, true, Name);
+ return RawAddress(CreateInBoundsGEP(Addr.getElementType(),
+ emitRawPointerFromAddress(Addr),
+ IdxList, Name),
+ ElementType, Align, Addr.isKnownNonNull());
}
using CGBuilderBaseTy::CreateIsNull;
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 494891ce4740d..6cc0d9485720c 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -2151,8 +2151,7 @@ RValue CodeGenFunction::emitBuiltinOSLogFormat(const CallExpr &E) {
// Ignore argument 1, the format string. It is not currently used.
CallArgList Args;
- Args.add(RValue::get(getAsNaturalPointerTo(BufAddr, Ctx.VoidTy)),
- Ctx.VoidPtrTy);
+ Args.add(RValue::get(BufAddr.emitRawPointer(*this)), Ctx.VoidPtrTy);
for (const auto &Item : Layout.Items) {
int Size = Item.getSizeByte();
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index b60f5b3a65868..a38484941ba24 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -3508,8 +3508,7 @@ static llvm::Value *tryRemoveRetainOfSelf(CodeGenFunction &CGF,
llvm::LoadInst *load =
dyn_cast<llvm::LoadInst>(retainedValue->stripPointerCasts());
if (!load || load->isAtomic() || load->isVolatile() ||
- load->getPointerOperand() !=
- CGF.GetAddrOfLocalVar(self).getPointerIfNotSigned())
+ load->getPointerOperand() != CGF.GetAddrOfLocalVar(self).getBasePointer())
return nullptr;
// Okay! Burn it all down. This relies for correctness on the
@@ -3546,8 +3545,7 @@ static llvm::Value *emitAutoreleaseOfResult(CodeGenFunction &CGF,
/// Heuristically search for a dominating store to the return-value slot.
static llvm::StoreInst *findDominatingStoreToReturnValue(CodeGenFunction &CGF) {
- // This function shouldn't be called when ReturnValue is signed.
- llvm::Value *ReturnValuePtr = CGF.ReturnValue.getUnsignedPointer();
+ llvm::Value *ReturnValuePtr = CGF.ReturnValue.getBasePointer();
// Check if a User is a store which pointerOperand is the ReturnValue.
// We are looking for stores to the ReturnValue, not for stores of the
@@ -4135,8 +4133,7 @@ static bool isProvablyNull(llvm::Value *addr) {
}
static bool isProvablyNonNull(Address Addr, CodeGenFunction &CGF) {
- return !Addr.isSigned() && llvm::isKnownNonZero(Addr.getUnsignedPointer(),
- CGF.CGM.getDataLayout());
+ return llvm::isKnownNonZero(Addr.getBasePointer(), CGF.CGM.getDataLayout());
}
/// Emit the actual writing-back of a writeback.
@@ -4144,7 +4141,7 @@ static void emitWriteback(CodeGenFunction &CGF,
const CallArgList::Writeback &writeback) {
const LValue &srcLV = writeback.Source;
Address srcAddr = srcLV.getAddress();
- assert(!isProvablyNull(srcAddr.getPointerIfNotSigned()) &&
+ assert(!isProvablyNull(srcAddr.getBasePointer()) &&
"shouldn't have writeback for provably null argument");
llvm::BasicBlock *contBB = nullptr;
@@ -4261,7 +4258,7 @@ static void emitWritebackArg(CodeGenFunction &CGF, CallArgList &args,
CGF.ConvertTypeForMem(CRE->getType()->getPointeeType());
// If the address is a constant null, just pass the appropriate null.
- if (isProvablyNull(srcAddr.getPointerIfNotSigned())) {
+ if (isProvablyNull(srcAddr.getBasePointer())) {
args.add(RValue::get(llvm::ConstantPointerNull::get(destType)),
CRE->getType());
return;
@@ -5101,7 +5098,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
llvm::Value *UnusedReturnSizePtr = nullptr;
if (RetAI.isIndirect() || RetAI.isInAlloca() || RetAI.isCoerceAndExpand()) {
if (!ReturnValue.isNull()) {
- SRetPtr = ReturnValue.getValue();
+ SRetPtr = ReturnValue.getAddress();
} else {
SRetPtr = CreateMemTemp(RetTy, "tmp", &SRetAlloca);
if (HaveInsertPoint() && ReturnValue.isUnused()) {
diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp
index 2de85963437f5..bb2ed237ee9f3 100644
--- a/clang/lib/CodeGen/CGException.cpp
+++ b/clang/lib/CodeGen/CGException.cpp
@@ -1835,8 +1835,8 @@ Address CodeGenFunction::recoverAddrOfEscapedLocal(CodeGenFunction &ParentCGF,
llvm::Value *ParentFP) {
llvm::CallInst *RecoverCall = nullptr;
CGBuilderTy Builder(*this, AllocaInsertPt);
- if (auto *ParentAlloca = dyn_cast_or_null<llvm::AllocaInst>(
- ParentVar.getPointerIfNotSigned())) {
+ if (auto *ParentAlloca =
+ dyn_cast_or_null<llvm::AllocaInst>(ParentVar.getBasePointer())) {
// Mark the variable escaped if nobody else referenced it and compute the
// localescape index.
auto InsertPair = ParentCGF.EscapedLocals.insert(
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index c3bf7d960410a..7ae5f0b1cf760 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -1786,11 +1786,8 @@ CodeGenFunction::tryEmitAsConstant(DeclRefExpr *refExpr) {
}
// Emit as a constant.
- // Try to emit as a constant.
- llvm::Constant *C =
- ConstantEmitter(*this).tryEmitAbstract(result.Val, resultType);
- if (!C)
- return ConstantEmission();
+ auto C = ConstantEmitter(*this).emitAbstract(refExpr->getLocation(),
+ result.Val, resultType);
// Make sure we emit a debug reference to the global variable.
// This should probably fire even for
@@ -1945,9 +1942,6 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(Address Addr, bool Volatile,
Addr = Addr.withPointer(Builder.CreateThreadLocalAddress(GV),
NotKnownNonNull);
- if (!CGM.getCodeGenOpts().NullPointerIsValid)
- Addr = Addr.setKnownNonNull();
-
if (const auto *ClangVecTy = Ty->getAs<VectorType>()) {
// Boolean vectors use `iN` as storage type.
if (ClangVecTy->isExtVectorBoolType()) {
@@ -2097,9 +2091,6 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, Address Addr,
Addr = Addr.withPointer(Builder.CreateThreadLocalAddress(GV),
NotKnownNonNull);
- if (!CGM.getCodeGenOpts().NullPointerIsValid)
- Addr = Addr.setKnownNonNull();
-
llvm::Type *SrcTy = Value->getType();
if (const auto *ClangVecTy = Ty->getAs<VectorType>()) {
auto *VecTy = dyn_cast<llvm::FixedVectorType>(SrcTy);
@@ -2801,9 +2792,9 @@ CodeGenFunction::EmitLoadOfReference(LValue RefLVal,
llvm::LoadInst *Load =
Builder.CreateLoad(RefLVal.getAddress(), RefLVal.isVolatile());
CGM.DecorateInstructionWithTBAA(Load, RefLVal.getTBAAInfo());
- return makeNaturalAddressForPointer(
- Load, RefLVal.getType()->getPointeeType(), CharUnits(),
- /*ForPointeeType=*/true, PointeeBaseInfo, PointeeTBAAInfo, KnownNonNull);
+ return makeNaturalAddressForPointer(Load, RefLVal.getType()->getPointeeType(),
+ CharUnits(), /*ForPointeeType=*/true,
+ PointeeBaseInfo, PointeeTBAAInfo);
}
LValue CodeGenFunction::EmitLoadOfReferenceLValue(LValue RefLVal) {
@@ -4716,8 +4707,7 @@ LValue CodeGenFunction::EmitLValueForLambdaField(const FieldDecl *Field,
}
} else {
QualType LambdaTagType = getContext().getTagDeclType(Field->getParent());
- LambdaLV = MakeNaturalAlignAddrLValue(ThisValue, LambdaTagType,
- KnownNonNull);
+ LambdaLV = MakeNaturalAlignAddrLValue(ThisValue, LambdaTagType);
}
return EmitLValueForField(LambdaLV, Field);
}
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index 14fee2eee8250..c3c10e73ff05e 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -253,9 +253,6 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
void AggExprEmitter::EmitAggLoadOfLValue(const Expr *E) {
LValue LV = CGF.EmitLValue(E);
- if (!CGF.CGM.getCodeGenOpts().NullPointerIsValid)
- LV = LV.setKnownNonNull();
-
// If the type of the l-value is atomic, then do an atomic load.
if (LV.getType()->isAtomicType() || CGF.LValueIsSuitableForInlineAtomic(LV)) {
CGF.EmitAtomicLoad(LV, E->getExprLoc(), Dest);
@@ -330,8 +327,8 @@ void AggExprEmitter::withReturnValueSlot(
if (!UseTemp)
return;
- assert(Dest.getAddress().isSigned() || Dest.isIgnored() ||
- Dest.emitRawPointer(CGF) != Src.getAggregatePointer(E->getType(), CGF));
+ assert(Dest.isIgnored() || Dest.emitRawPointer(CGF) !=
+ Src.getAggregatePointer(E->getType(), CGF));
EmitFinalDestCopy(E->getType(), Src);
if (!RequiresDestruction && LifetimeStartInst) {
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp
index db4a70f5316f8..8eb6ab7381acb 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/lib/CodeGen/CGExprCXX.cpp
@@ -265,7 +265,7 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(CE)) {
if (OCE->isAssignmentOp()) {
if (TrivialAssignment) {
- TrivialAssignmentRHS = EmitLValue(CE->getArg(1), KnownNonNull);
+ TrivialAssignmentRHS = EmitLValue(CE->getArg(1));
} else {
RtlArgs = &RtlArgStorage;
EmitCallArgs(*RtlArgs, MD->getType()->castAs<FunctionProtoType>(),
@@ -279,12 +279,11 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
if (IsArrow) {
LValueBaseInfo BaseInfo;
TBAAAccessInfo TBAAInfo;
- Address ThisValue = EmitPointerWithAlignment(
- Base, &BaseInfo, &TBAAInfo, KnownNonNull);
+ Address ThisValue = EmitPointerWithAlignment(Base, &BaseInfo, &TBAAInfo);
This = MakeAddrLValue(ThisValue, Base->getType()->getPointeeType(),
BaseInfo, TBAAInfo);
} else {
- This = EmitLValue(Base, KnownNonNull);
+ This = EmitLValue(Base);
}
if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(MD)) {
@@ -317,7 +316,7 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
// the RHS.
LValue RHS = isa<CXXOperatorCallExpr>(CE)
? TrivialAssignmentRHS
- : EmitLValue(*CE->arg_begin(), KnownNonNull);
+ : EmitLValue(*CE->arg_begin());
EmitAggregateAssign(This, RHS, CE->getType());
return RValue::get(This.getPointer(*this));
}
diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp
index 534f7c0407f61..00a5a7e6898a8 100644
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ b/clang/lib/CodeGen/CGExprConstant.cpp
@@ -2074,24 +2074,14 @@ ConstantLValueEmitter::tryEmitBase(const APValue::LValueBase &base) {
if (D->hasAttr<WeakRefAttr>())
return CGM.GetWeakRefReference(D).getPointer();
- auto PtrAuthSign = [&](llvm::Constant *C, bool IsFunction) {
+ auto PtrAuthSign = [&](llvm::Constant *C) {
CGPointerAuthInfo AuthInfo;
if (EnablePtrAuthFunctionTypeDiscrimination)
AuthInfo = CGM.getFunctionPointerAuthInfo(DestType);
- else {
- // FIXME: getPointerAuthInfoForType should be able to return the pointer
- // auth info of reference types.
- if (auto *RT = DestType->getAs<ReferenceType>())
- DestType = CGM.getContext().getPointerType(RT->getPointeeType());
- // Don't emit a signed pointer if the destination is a function pointer
- // type.
- if (DestType->isSignableType() && !DestType->isFunctionPointerType())
- AuthInfo = CGM.getPointerAuthInfoForType(DestType);
- }
if (AuthInfo) {
- if (IsFunction && hasNonZeroOffset())
+ if (hasNonZeroOffset())
return ConstantLValue(nullptr);
C = applyOffset(C);
@@ -2105,7 +2095,7 @@ ConstantLValueEmitter::tryEmitBase(const APValue::LValueBase &base) {
};
if (const auto *FD = dyn_cast<FunctionDecl>(D))
- return PtrAuthSign(CGM.getRawFunctionPointer(FD), true);
+ return PtrAuthSign(CGM.getRawFunctionPointer(FD));
if (const auto *VD = dyn_cast<VarDecl>(D)) {
// We can never refer to a variable with local storage.
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 65acb3b067f91..14ca9341c5148 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -2855,11 +2855,10 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
Builder.SetInsertPoint(opBB);
atomicPHI = Builder.CreatePHI(value->getType(), 2);
atomicPHI->addIncoming(value, startBB);
- value = CGF.EmitPointerAuthAuth(type->getPointeeType(), atomicPHI);
+ value = atomicPHI;
} else {
value = EmitLoadOfLValue(LV, E->getExprLoc());
input = value;
- value = CGF.EmitPointerAuthAuth(type->getPointeeType(), value);
}
// Special case of integer increment that we have to check first: bool++.
@@ -3101,7 +3100,6 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
if (atomicPHI) {
llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
llvm::BasicBlock *contBB = CGF.createBasicBlock("atomic_cont", CGF.CurFn);
- value = CGF.EmitPointerAuthSign(type->getPointeeType(), value);
auto Pair = CGF.EmitAtomicCompareExchange(
LV, RValue::get(atomicPHI), RValue::get(value), E->getExprLoc());
llvm::Value *old = CGF.EmitToMemory(Pair.first.getScalarVal(), type);
@@ -3113,7 +3111,6 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
}
// Store the updated result through the lvalue.
- value = CGF.EmitPointerAuthSign(type->getPointeeType(), value);
if (LV.isBitField()) {
Value *Src = Previous ? Previous : value;
CGF.EmitStoreThroughBitfieldLValue(RValue::get(value), LV, &value);
@@ -3974,10 +3971,6 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,
return CGF.Builder.CreateBitCast(result, pointer->getType());
}
- CGPointerAuthInfo PtrAuthInfo = CGF.CGM.getPointerAuthInfoForType(op.Ty);
- if (PtrAuthInfo)
- pointer = CGF.EmitPointerAuthAuth(PtrAuthInfo, pointer);
-
QualType elementType = pointerType->getPointeeType();
if (const VariableArrayType *vla
= CGF.getContext().getAsVariableArrayType(elementType)) {
@@ -3998,8 +3991,7 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,
elemTy, pointer, index, isSigned, isSubtraction, op.E->getExprLoc(),
"add.ptr");
}
- return PtrAuthInfo ? CGF.EmitPointerAuthSign(PtrAuthInfo, pointer)
- : pointer;
+ return pointer;
}
// Explicitly handle GNU void* and function pointer arithmetic extensions. The
@@ -4012,13 +4004,11 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,
elemTy = CGF.ConvertTypeForMem(elementType);
if (CGF.getLangOpts().isSignedOverflowDefined())
- pointer = CGF.Builder.CreateGEP(elemTy, pointer, index, "add.ptr");
- else
- pointer = CGF.EmitCheckedInBoundsGEP(elemTy, pointer, index, isSigned,
- isSubtraction, op.E->getExprLoc(),
- "add.ptr");
+ return CGF.Builder.CreateGEP(elemTy, pointer, index, "add.ptr");
- return PtrAuthInfo ? CGF.EmitPointerAuthSign(PtrAuthInfo, pointer) : pointer;
+ return CGF.EmitCheckedInBoundsGEP(
+ elemTy, pointer, index, isSigned, isSubtraction, op.E->getExprLoc(),
+ "add.ptr");
}
// Construct an fmuladd intrinsic to represent a fused mul-add of MulOp and
diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 7395370259fe9..30f3911a8b03c 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -4425,7 +4425,7 @@ void FragileHazards::emitHazardsInNewBlocks() {
static void addIfPresent(llvm::DenseSet<llvm::Value*> &S, Address V) {
if (V.isValid())
- if (llvm::Value *Ptr = V.getPointerIfNotSigned())
+ if (llvm::Value *Ptr = V.getBasePointer())
S.insert(Ptr);
}
diff --git a/clang/lib/CodeGen/CGPointerAuth.cpp b/clang/lib/CodeGen/CGPointerAuth.cpp
index c069b3fa72fba..7651dd936016e 100644
--- a/clang/lib/CodeGen/CGPointerAuth.cpp
+++ b/clang/lib/CodeGen/CGPointerAuth.cpp
@@ -90,7 +90,6 @@ CGPointerAuthInfo CodeGenModule::getFunctionPointerAuthInfo(QualType T) {
Discriminator);
}
-
llvm::Value *
CodeGenFunction::EmitPointerAuthBlendDiscriminator(llvm::Value *StorageAddress,
llvm::Value *Discriminator) {
@@ -167,48 +166,6 @@ CGPointerAuthInfo CodeGenModule::getPointerAuthInfoForType(QualType T) {
return ::getPointerAuthInfoForType(*this, T);
}
-Address CodeGenFunction::mergeAddressesInConditionalExpr(
- Address LHS, Address RHS, llvm::BasicBlock *LHSBlock,
- llvm::BasicBlock *RHSBlock, llvm::BasicBlock *MergeBlock,
- QualType MergedType) {
- CGPointerAuthInfo LHSInfo = LHS.getPointerAuthInfo();
- CGPointerAuthInfo RHSInfo = RHS.getPointerAuthInfo();
-
- if (LHSInfo || RHSInfo) {
- if (LHSInfo != RHSInfo || LHS.getOffset() != RHS.getOffset() ||
- LHS.getBasePointer()->getType() != RHS.getBasePointer()->getType()) {
- // If the LHS and RHS have different signing information, offsets, or base
- // pointer types, resign both sides and clear out the offsets.
- CGPointerAuthInfo NewInfo =
- CGM.getPointerAuthInfoForPointeeType(MergedType);
- LHSBlock->getTerminator()->eraseFromParent();
- Builder.SetInsertPoint(LHSBlock);
- LHS = LHS.getResignedAddress(NewInfo, *this);
- Builder.CreateBr(MergeBlock);
- LHSBlock = Builder.GetInsertBlock();
- RHSBlock->getTerminator()->eraseFromParent();
- Builder.SetInsertPoint(RHSBlock);
- RHS = RHS.getResignedAddress(NewInfo, *this);
- Builder.CreateBr(MergeBlock);
- RHSBlock = Builder.GetInsertBlock();
- }
-
- assert(LHS.getPointerAuthInfo() == RHS.getPointerAuthInfo() &&
- LHS.getOffset() == RHS.getOffset() &&
- LHS.getBasePointer()->getType() == RHS.getBasePointer()->getType() &&
- "lhs and rhs must have the same signing information, offsets, and "
- "base pointer types");
- }
-
- Builder.SetInsertPoint(MergeBlock);
- llvm::PHINode *PtrPhi = Builder.CreatePHI(LHS.getType(), 2, "cond");
- PtrPhi->addIncoming(LHS.getBasePointer(), LHSBlock);
- PtrPhi->addIncoming(RHS.getBasePointer(), RHSBlock);
- LHS.replaceBasePointer(PtrPhi);
- LHS.setAlignment(std::min(LHS.getAlignment(), RHS.getAlignment()));
- return LHS;
-}
-
static bool isZeroConstant(llvm::Value *value) {
if (auto ci = dyn_cast<llvm::ConstantInt>(value))
return ci->isZero();
@@ -337,16 +294,6 @@ llvm::Constant *CodeGenModule::getConstantSignedPointer(
OtherDiscriminator);
}
-llvm::Constant *CodeGenModule::getConstantSignedPointer(llvm::Constant *Pointer,
- QualType PointeeType) {
- CGPointerAuthInfo Info = getPointerAuthInfoForPointeeType(PointeeType);
- if (!Info.shouldSign())
- return Pointer;
- return getConstantSignedPointer(
- Pointer, Info.getKey(), nullptr,
- cast<llvm::ConstantInt>(Info.getDiscriminator()));
-}
-
/// If applicable, sign a given constant function pointer with the ABI rules for
/// functionType.
llvm::Constant *CodeGenModule::getFunctionPointer(llvm::Constant *Pointer,
@@ -574,7 +521,7 @@ Address Address::getResignedAddress(const CGPointerAuthInfo &NewInfo,
// Nothing to do if neither the current or the new ptrauth info needs signing.
if (!CurInfo.isSigned() && !NewInfo.isSigned())
- return Address(getUnsignedPointer(), getElementType(), getAlignment(),
+ return Address(getBasePointer(), getElementType(), getAlignment(),
isKnownNonNull());
assert(ElementType && "Effective type has to be set");
@@ -611,39 +558,10 @@ Address Address::getResignedAddress(const CGPointerAuthInfo &NewInfo,
isKnownNonNull());
}
-void Address::addOffset(CharUnits V, llvm::Type *Ty, CGBuilderTy &Builder) {
- assert(isSigned() &&
- "shouldn't add an offset if the base pointer isn't signed");
- Alignment = Alignment.alignmentAtOffset(V);
- llvm::Value *FixedOffset =
- llvm::ConstantInt::get(Builder.getCGF()->IntPtrTy, V.getQuantity());
- addOffset(FixedOffset, Ty, Builder, Alignment);
-}
-
-void Address::addOffset(llvm::Value *V, llvm::Type *Ty, CGBuilderTy &Builder,
- CharUnits NewAlignment) {
- assert(isSigned() &&
- "shouldn't add an offset if the base pointer isn't signed");
- ElementType = Ty;
- Alignment = NewAlignment;
-
- if (!Offset) {
- Offset = V;
- return;
- }
-
- Offset = Builder.CreateAdd(Offset, V, "add");
-}
-
llvm::Value *Address::emitRawPointerSlow(CodeGenFunction &CGF) const {
return CGF.getAsNaturalPointerTo(*this, QualType());
}
-llvm::Value *RValue::getAggregatePointer(QualType PointeeType,
- CodeGenFunction &CGF) const {
- return CGF.getAsNaturalPointerTo(getAggregateAddress(), PointeeType);
-}
-
llvm::Value *LValue::getPointer(CodeGenFunction &CGF) const {
assert(isSimple());
return emitResignedPointer(getType(), CGF);
@@ -665,7 +583,3 @@ llvm::Value *AggValueSlot::getPointer(QualType PointeeTy,
Address SignedAddr = CGF.getAsNaturalAddressOf(Addr, PointeeTy);
return SignedAddr.getBasePointer();
}
-
-llvm::Value *AggValueSlot::emitRawPointer(CodeGenFunction &CGF) const {
- return Addr.isValid() ? Addr.emitRawPointer(CGF) : nullptr;
-}
diff --git a/clang/lib/CodeGen/CGValue.h b/clang/lib/CodeGen/CGValue.h
index 27efcf6ac199b..c4ec8d207d2e3 100644
--- a/clang/lib/CodeGen/CGValue.h
+++ b/clang/lib/CodeGen/CGValue.h
@@ -79,8 +79,6 @@ class RValue {
return std::make_pair(Vals.first, Vals.second);
}
- bool isSignedAggregate() const { return AggregateAddr.isSigned(); }
-
/// getAggregateAddr() - Return the Value* of the address of the aggregate.
Address getAggregateAddress() const {
assert(isAggregate() && "Not an aggregate!");
@@ -88,7 +86,9 @@ class RValue {
}
llvm::Value *getAggregatePointer(QualType PointeeType,
- CodeGenFunction &CGF) const;
+ CodeGenFunction &CGF) const {
+ return getAggregateAddress().getBasePointer();
+ }
static RValue getIgnored() {
// FIXME: should we make this a more explicit state?
@@ -318,8 +318,6 @@ class LValue {
bool isNontemporal() const { return Nontemporal; }
void setNontemporal(bool Value) { Nontemporal = Value; }
- bool isPointerSigned() const { return Addr.isSigned(); }
-
bool isObjCWeak() const {
return Quals.getObjCGCAttr() == Qualifiers::Weak;
}
@@ -639,7 +637,9 @@ class AggValueSlot {
llvm::Value *getPointer(QualType PointeeTy, CodeGenFunction &CGF) const;
- llvm::Value *emitRawPointer(CodeGenFunction &CGF) const;
+ llvm::Value *emitRawPointer(CodeGenFunction &CGF) const {
+ return Addr.isValid() ? Addr.emitRawPointer(CGF) : nullptr;
+ }
Address getAddress() const {
return Addr;
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 9e29cddc6f858..fab3091f0581c 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -18,7 +18,6 @@
#include "CGDebugInfo.h"
#include "CGHLSLRuntime.h"
#include "CGOpenMPRuntime.h"
-#include "CGRecordLayout.h"
#include "CodeGenModule.h"
#include "CodeGenPGO.h"
#include "TargetInfo.h"
@@ -559,11 +558,8 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
ReturnBlock.getBlock()->eraseFromParent();
}
if (ReturnValue.isValid()) {
- // This only matters when ReturnValue isn't signed. ReturnValue is possibly
- // signed only when the return is Indirect or InAlloca. In that case, a
- // temporary alloca to store the return value isn't created.
auto *RetAlloca =
- dyn_cast_or_null<llvm::AllocaInst>(ReturnValue.getPointerIfNotSigned());
+ dyn_cast<llvm::AllocaInst>(ReturnValue.emitRawPointer(*this));
if (RetAlloca && RetAlloca->use_empty()) {
RetAlloca->eraseFromParent();
ReturnValue = Address::invalid();
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 2ce28f3e4681f..4a85153cd7830 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -185,11 +185,6 @@ template <> struct DominatingValue<Address> {
DominatingLLVMValue::saved_type BasePtr;
llvm::Type *ElementType;
CharUnits Alignment;
- unsigned PtrAuthKey : 28;
- PointerAuthenticationMode PtrAuthMode : 2;
- bool IsIsaPointer : 1;
- bool AuthenticatesNullValues : 1;
- DominatingLLVMValue::saved_type PtrAuthDiscriminator;
DominatingLLVMValue::saved_type Offset;
llvm::PointerType *EffectiveType;
};
@@ -198,36 +193,16 @@ template <> struct DominatingValue<Address> {
if (DominatingLLVMValue::needsSaving(value.getBasePointer()) ||
DominatingLLVMValue::needsSaving(value.getOffset()))
return true;
- CGPointerAuthInfo info = value.getPointerAuthInfo();
- if (info.isSigned() &&
- DominatingLLVMValue::needsSaving(info.getDiscriminator()))
- return true;
return false;
}
static saved_type save(CodeGenFunction &CGF, type value) {
- bool isSigned = value.getPointerAuthInfo().isSigned();
return {DominatingLLVMValue::save(CGF, value.getBasePointer()),
- value.getElementType(),
- value.getAlignment(),
- isSigned ? value.getPointerAuthInfo().getKey() : 0,
- value.getPointerAuthInfo().getAuthenticationMode(),
- value.getPointerAuthInfo().isIsaPointer(),
- value.getPointerAuthInfo().authenticatesNullValues(),
- isSigned ? DominatingLLVMValue::save(
- CGF, value.getPointerAuthInfo().getDiscriminator())
- : DominatingLLVMValue::saved_type(),
- DominatingLLVMValue::save(CGF, value.getOffset()),
- value.getType()};
+ value.getElementType(), value.getAlignment(),
+ DominatingLLVMValue::save(CGF, value.getOffset()), value.getType()};
}
static type restore(CodeGenFunction &CGF, saved_type value) {
- CGPointerAuthInfo info;
- if (value.PtrAuthMode != PointerAuthenticationMode::None)
- info = CGPointerAuthInfo{
- value.PtrAuthKey, value.PtrAuthMode, value.IsIsaPointer,
- value.AuthenticatesNullValues,
- DominatingLLVMValue::restore(CGF, value.PtrAuthDiscriminator)};
return Address(DominatingLLVMValue::restore(CGF, value.BasePtr),
- value.ElementType, value.Alignment, info,
+ value.ElementType, value.Alignment, CGPointerAuthInfo(),
DominatingLLVMValue::restore(CGF, value.Offset));
}
};
@@ -2690,7 +2665,15 @@ class CodeGenFunction : public CodeGenTypeCache {
llvm::BasicBlock *LHSBlock,
llvm::BasicBlock *RHSBlock,
llvm::BasicBlock *MergeBlock,
- QualType MergedType);
+ QualType MergedType) {
+ Builder.SetInsertPoint(MergeBlock);
+ llvm::PHINode *PtrPhi = Builder.CreatePHI(LHS.getType(), 2, "cond");
+ PtrPhi->addIncoming(LHS.getBasePointer(), LHSBlock);
+ PtrPhi->addIncoming(RHS.getBasePointer(), RHSBlock);
+ LHS.replaceBasePointer(PtrPhi);
+ LHS.setAlignment(std::min(LHS.getAlignment(), RHS.getAlignment()));
+ return LHS;
+ }
/// Construct an address with the natural alignment of T. If a pointer to T
/// is expected to be signed, the pointer passed to this function must have
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index 7c6078df0af82..caa3786c033b5 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -986,9 +986,6 @@ class CodeGenModule : public CodeGenTypeCache {
GlobalDecl SchemaDecl,
QualType SchemaType);
- llvm::Constant *getConstantSignedPointer(llvm::Constant *Pointer,
- QualType PointeeType);
-
llvm::Constant *
getConstantSignedPointer(llvm::Constant *Pointer, unsigned Key,
llvm::Constant *StorageAddress,
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 1609ae19696c7..6e5fa0faf73d7 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -4711,7 +4711,7 @@ static void InitCatchParam(CodeGenFunction &CGF,
// Cast that to the appropriate type.
Address adjustedExn(CGF.Builder.CreateBitCast(rawAdjustedExn, PtrTy),
- LLVMCatchTy, caughtExnAlignment, KnownNonNull);
+ LLVMCatchTy, caughtExnAlignment);
// The copy expression is defined in terms of an OpaqueValueExpr.
// Find it and map it to the adjusted expression.
More information about the cfe-commits
mailing list