aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CGCall.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/CGCall.cpp')
-rw-r--r--clang/lib/CodeGen/CGCall.cpp171
1 files changed, 97 insertions, 74 deletions
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index b8adf5c..fb00782 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -1037,15 +1037,9 @@ static void forConstantArrayExpansion(CodeGenFunction &CGF,
ConstantArrayExpansion *CAE,
Address BaseAddr,
llvm::function_ref<void(Address)> Fn) {
- CharUnits EltSize = CGF.getContext().getTypeSizeInChars(CAE->EltTy);
- CharUnits EltAlign =
- BaseAddr.getAlignment().alignmentOfArrayElement(EltSize);
- llvm::Type *EltTy = CGF.ConvertTypeForMem(CAE->EltTy);
-
for (int i = 0, n = CAE->NumElts; i < n; i++) {
- llvm::Value *EltAddr = CGF.Builder.CreateConstGEP2_32(
- BaseAddr.getElementType(), BaseAddr.getPointer(), 0, i);
- Fn(Address(EltAddr, EltTy, EltAlign));
+ Address EltAddr = CGF.Builder.CreateConstGEP2_32(BaseAddr, 0, i);
+ Fn(EltAddr);
}
}
@@ -1160,9 +1154,10 @@ void CodeGenFunction::ExpandTypeToArgs(
}
/// Create a temporary allocation for the purposes of coercion.
-static Address CreateTempAllocaForCoercion(CodeGenFunction &CGF, llvm::Type *Ty,
- CharUnits MinAlign,
- const Twine &Name = "tmp") {
+static RawAddress CreateTempAllocaForCoercion(CodeGenFunction &CGF,
+ llvm::Type *Ty,
+ CharUnits MinAlign,
+ const Twine &Name = "tmp") {
// Don't use an alignment that's worse than what LLVM would prefer.
auto PrefAlign = CGF.CGM.getDataLayout().getPrefTypeAlign(Ty);
CharUnits Align = std::max(MinAlign, CharUnits::fromQuantity(PrefAlign));
@@ -1332,11 +1327,11 @@ static llvm::Value *CreateCoercedLoad(Address Src, llvm::Type *Ty,
}
// Otherwise do coercion through memory. This is stupid, but simple.
- Address Tmp =
+ RawAddress Tmp =
CreateTempAllocaForCoercion(CGF, Ty, Src.getAlignment(), Src.getName());
CGF.Builder.CreateMemCpy(
- Tmp.getPointer(), Tmp.getAlignment().getAsAlign(), Src.getPointer(),
- Src.getAlignment().getAsAlign(),
+ Tmp.getPointer(), Tmp.getAlignment().getAsAlign(),
+ Src.emitRawPointer(CGF), Src.getAlignment().getAsAlign(),
llvm::ConstantInt::get(CGF.IntPtrTy, SrcSize.getKnownMinValue()));
return CGF.Builder.CreateLoad(Tmp);
}
@@ -1420,11 +1415,12 @@ static void CreateCoercedStore(llvm::Value *Src,
//
// FIXME: Assert that we aren't truncating non-padding bits when have access
// to that information.
- Address Tmp = CreateTempAllocaForCoercion(CGF, SrcTy, Dst.getAlignment());
+ RawAddress Tmp =
+ CreateTempAllocaForCoercion(CGF, SrcTy, Dst.getAlignment());
CGF.Builder.CreateStore(Src, Tmp);
CGF.Builder.CreateMemCpy(
- Dst.getPointer(), Dst.getAlignment().getAsAlign(), Tmp.getPointer(),
- Tmp.getAlignment().getAsAlign(),
+ Dst.emitRawPointer(CGF), Dst.getAlignment().getAsAlign(),
+ Tmp.getPointer(), Tmp.getAlignment().getAsAlign(),
llvm::ConstantInt::get(CGF.IntPtrTy, DstSize.getFixedValue()));
}
}
@@ -3024,17 +3020,17 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
case ABIArgInfo::Indirect:
case ABIArgInfo::IndirectAliased: {
assert(NumIRArgs == 1);
- Address ParamAddr = Address(Fn->getArg(FirstIRArg), ConvertTypeForMem(Ty),
- ArgI.getIndirectAlign(), KnownNonNull);
+ Address ParamAddr = makeNaturalAddressForPointer(
+ Fn->getArg(FirstIRArg), Ty, ArgI.getIndirectAlign(), false, nullptr,
+ nullptr, KnownNonNull);
if (!hasScalarEvaluationKind(Ty)) {
// Aggregates and complex variables are accessed by reference. All we
// need to do is realign the value, if requested. Also, if the address
// may be aliased, copy it to ensure that the parameter variable is
// mutable and has a unique adress, as C requires.
- Address V = ParamAddr;
if (ArgI.getIndirectRealign() || ArgI.isIndirectAliased()) {
- Address AlignedTemp = CreateMemTemp(Ty, "coerce");
+ RawAddress AlignedTemp = CreateMemTemp(Ty, "coerce");
// Copy from the incoming argument pointer to the temporary with the
// appropriate alignment.
@@ -3044,11 +3040,12 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
CharUnits Size = getContext().getTypeSizeInChars(Ty);
Builder.CreateMemCpy(
AlignedTemp.getPointer(), AlignedTemp.getAlignment().getAsAlign(),
- ParamAddr.getPointer(), ParamAddr.getAlignment().getAsAlign(),
+ ParamAddr.emitRawPointer(*this),
+ ParamAddr.getAlignment().getAsAlign(),
llvm::ConstantInt::get(IntPtrTy, Size.getQuantity()));
- V = AlignedTemp;
+ ParamAddr = AlignedTemp;
}
- ArgVals.push_back(ParamValue::forIndirect(V));
+ ArgVals.push_back(ParamValue::forIndirect(ParamAddr));
} else {
// Load scalar value from indirect argument.
llvm::Value *V =
@@ -3162,10 +3159,10 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
== ParameterABI::SwiftErrorResult) {
QualType pointeeTy = Ty->getPointeeType();
assert(pointeeTy->isPointerType());
- Address temp =
- CreateMemTemp(pointeeTy, getPointerAlign(), "swifterror.temp");
- Address arg(V, ConvertTypeForMem(pointeeTy),
- getContext().getTypeAlignInChars(pointeeTy));
+ RawAddress temp =
+ CreateMemTemp(pointeeTy, getPointerAlign(), "swifterror.temp");
+ Address arg = makeNaturalAddressForPointer(
+ V, pointeeTy, getContext().getTypeAlignInChars(pointeeTy));
llvm::Value *incomingErrorValue = Builder.CreateLoad(arg);
Builder.CreateStore(incomingErrorValue, temp);
V = temp.getPointer();
@@ -3502,7 +3499,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).getPointer())
+ load->getPointerOperand() != CGF.GetAddrOfLocalVar(self).getBasePointer())
return nullptr;
// Okay! Burn it all down. This relies for correctness on the
@@ -3539,12 +3536,15 @@ 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();
+
// 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
// ReturnValue to some other location.
- auto GetStoreIfValid = [&CGF](llvm::User *U) -> llvm::StoreInst * {
+ auto GetStoreIfValid = [&CGF,
+ ReturnValuePtr](llvm::User *U) -> llvm::StoreInst * {
auto *SI = dyn_cast<llvm::StoreInst>(U);
- if (!SI || SI->getPointerOperand() != CGF.ReturnValue.getPointer() ||
+ if (!SI || SI->getPointerOperand() != ReturnValuePtr ||
SI->getValueOperand()->getType() != CGF.ReturnValue.getElementType())
return nullptr;
// These aren't actually possible for non-coerced returns, and we
@@ -3558,7 +3558,7 @@ static llvm::StoreInst *findDominatingStoreToReturnValue(CodeGenFunction &CGF) {
// for something immediately preceding the IP. Sometimes this can
// happen with how we generate implicit-returns; it can also happen
// with noreturn cleanups.
- if (!CGF.ReturnValue.getPointer()->hasOneUse()) {
+ if (!ReturnValuePtr->hasOneUse()) {
llvm::BasicBlock *IP = CGF.Builder.GetInsertBlock();
if (IP->empty()) return nullptr;
@@ -3576,8 +3576,7 @@ static llvm::StoreInst *findDominatingStoreToReturnValue(CodeGenFunction &CGF) {
return nullptr;
}
- llvm::StoreInst *store =
- GetStoreIfValid(CGF.ReturnValue.getPointer()->user_back());
+ llvm::StoreInst *store = GetStoreIfValid(ReturnValuePtr->user_back());
if (!store) return nullptr;
// Now do a first-and-dirty dominance check: just walk up the
@@ -4121,7 +4120,11 @@ void CodeGenFunction::EmitDelegateCallArg(CallArgList &args,
}
static bool isProvablyNull(llvm::Value *addr) {
- return isa<llvm::ConstantPointerNull>(addr);
+ return llvm::isa_and_nonnull<llvm::ConstantPointerNull>(addr);
+}
+
+static bool isProvablyNonNull(Address Addr, CodeGenFunction &CGF) {
+ return llvm::isKnownNonZero(Addr.getBasePointer(), CGF.CGM.getDataLayout());
}
/// Emit the actual writing-back of a writeback.
@@ -4129,21 +4132,20 @@ static void emitWriteback(CodeGenFunction &CGF,
const CallArgList::Writeback &writeback) {
const LValue &srcLV = writeback.Source;
Address srcAddr = srcLV.getAddress(CGF);
- assert(!isProvablyNull(srcAddr.getPointer()) &&
+ assert(!isProvablyNull(srcAddr.getBasePointer()) &&
"shouldn't have writeback for provably null argument");
llvm::BasicBlock *contBB = nullptr;
// If the argument wasn't provably non-null, we need to null check
// before doing the store.
- bool provablyNonNull = llvm::isKnownNonZero(srcAddr.getPointer(),
- CGF.CGM.getDataLayout());
+ bool provablyNonNull = isProvablyNonNull(srcAddr, CGF);
+
if (!provablyNonNull) {
llvm::BasicBlock *writebackBB = CGF.createBasicBlock("icr.writeback");
contBB = CGF.createBasicBlock("icr.done");
- llvm::Value *isNull =
- CGF.Builder.CreateIsNull(srcAddr.getPointer(), "icr.isnull");
+ llvm::Value *isNull = CGF.Builder.CreateIsNull(srcAddr, "icr.isnull");
CGF.Builder.CreateCondBr(isNull, contBB, writebackBB);
CGF.EmitBlock(writebackBB);
}
@@ -4247,7 +4249,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.getPointer())) {
+ if (isProvablyNull(srcAddr.getBasePointer())) {
args.add(RValue::get(llvm::ConstantPointerNull::get(destType)),
CRE->getType());
return;
@@ -4276,17 +4278,16 @@ static void emitWritebackArg(CodeGenFunction &CGF, CallArgList &args,
// If the address is *not* known to be non-null, we need to switch.
llvm::Value *finalArgument;
- bool provablyNonNull = llvm::isKnownNonZero(srcAddr.getPointer(),
- CGF.CGM.getDataLayout());
+ bool provablyNonNull = isProvablyNonNull(srcAddr, CGF);
+
if (provablyNonNull) {
- finalArgument = temp.getPointer();
+ finalArgument = temp.emitRawPointer(CGF);
} else {
- llvm::Value *isNull =
- CGF.Builder.CreateIsNull(srcAddr.getPointer(), "icr.isnull");
+ llvm::Value *isNull = CGF.Builder.CreateIsNull(srcAddr, "icr.isnull");
- finalArgument = CGF.Builder.CreateSelect(isNull,
- llvm::ConstantPointerNull::get(destType),
- temp.getPointer(), "icr.argument");
+ finalArgument = CGF.Builder.CreateSelect(
+ isNull, llvm::ConstantPointerNull::get(destType),
+ temp.emitRawPointer(CGF), "icr.argument");
// If we need to copy, then the load has to be conditional, which
// means we need control flow.
@@ -4410,6 +4411,16 @@ void CodeGenFunction::EmitNonNullArgCheck(RValue RV, QualType ArgType,
EmitCheck(std::make_pair(Cond, CheckKind), Handler, StaticData, std::nullopt);
}
+void CodeGenFunction::EmitNonNullArgCheck(Address Addr, QualType ArgType,
+ SourceLocation ArgLoc,
+ AbstractCallee AC, unsigned ParmNum) {
+ if (!AC.getDecl() || !(SanOpts.has(SanitizerKind::NonnullAttribute) ||
+ SanOpts.has(SanitizerKind::NullabilityArg)))
+ return;
+
+ EmitNonNullArgCheck(RValue::get(Addr, *this), ArgType, ArgLoc, AC, ParmNum);
+}
+
// Check if the call is going to use the inalloca convention. This needs to
// agree with CGFunctionInfo::usesInAlloca. The CGFunctionInfo is arranged
// later, so we can't check it directly.
@@ -4750,12 +4761,22 @@ CodeGenFunction::AddObjCARCExceptionMetadata(llvm::Instruction *Inst) {
llvm::CallInst *
CodeGenFunction::EmitNounwindRuntimeCall(llvm::FunctionCallee callee,
const llvm::Twine &name) {
- return EmitNounwindRuntimeCall(callee, std::nullopt, name);
+ return EmitNounwindRuntimeCall(callee, ArrayRef<llvm::Value *>(), name);
}
/// Emits a call to the given nounwind runtime function.
llvm::CallInst *
CodeGenFunction::EmitNounwindRuntimeCall(llvm::FunctionCallee callee,
+ ArrayRef<Address> args,
+ const llvm::Twine &name) {
+ SmallVector<llvm::Value *, 3> values;
+ for (auto arg : args)
+ values.push_back(arg.emitRawPointer(*this));
+ return EmitNounwindRuntimeCall(callee, values, name);
+}
+
+llvm::CallInst *
+CodeGenFunction::EmitNounwindRuntimeCall(llvm::FunctionCallee callee,
ArrayRef<llvm::Value *> args,
const llvm::Twine &name) {
llvm::CallInst *call = EmitRuntimeCall(callee, args, name);
@@ -5032,7 +5053,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
// If we're using inalloca, insert the allocation after the stack save.
// FIXME: Do this earlier rather than hacking it in here!
- Address ArgMemory = Address::invalid();
+ RawAddress ArgMemory = RawAddress::invalid();
if (llvm::StructType *ArgStruct = CallInfo.getArgStruct()) {
const llvm::DataLayout &DL = CGM.getDataLayout();
llvm::Instruction *IP = CallArgs.getStackBase();
@@ -5048,7 +5069,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
AI->setAlignment(Align.getAsAlign());
AI->setUsedWithInAlloca(true);
assert(AI->isUsedWithInAlloca() && !AI->isStaticAlloca());
- ArgMemory = Address(AI, ArgStruct, Align);
+ ArgMemory = RawAddress(AI, ArgStruct, Align);
}
ClangToLLVMArgMapping IRFunctionArgs(CGM.getContext(), CallInfo);
@@ -5057,11 +5078,11 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
// If the call returns a temporary with struct return, create a temporary
// alloca to hold the result, unless one is given to us.
Address SRetPtr = Address::invalid();
- Address SRetAlloca = Address::invalid();
+ RawAddress SRetAlloca = RawAddress::invalid();
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()) {
@@ -5071,15 +5092,16 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
}
}
if (IRFunctionArgs.hasSRetArg()) {
- IRCallArgs[IRFunctionArgs.getSRetArgNo()] = SRetPtr.getPointer();
+ IRCallArgs[IRFunctionArgs.getSRetArgNo()] =
+ getAsNaturalPointerTo(SRetPtr, RetTy);
} else if (RetAI.isInAlloca()) {
Address Addr =
Builder.CreateStructGEP(ArgMemory, RetAI.getInAllocaFieldIndex());
- Builder.CreateStore(SRetPtr.getPointer(), Addr);
+ Builder.CreateStore(getAsNaturalPointerTo(SRetPtr, RetTy), Addr);
}
}
- Address swiftErrorTemp = Address::invalid();
+ RawAddress swiftErrorTemp = RawAddress::invalid();
Address swiftErrorArg = Address::invalid();
// When passing arguments using temporary allocas, we need to add the
@@ -5112,9 +5134,9 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
assert(NumIRArgs == 0);
assert(getTarget().getTriple().getArch() == llvm::Triple::x86);
if (I->isAggregate()) {
- Address Addr = I->hasLValue()
- ? I->getKnownLValue().getAddress(*this)
- : I->getKnownRValue().getAggregateAddress();
+ RawAddress Addr = I->hasLValue()
+ ? I->getKnownLValue().getAddress(*this)
+ : I->getKnownRValue().getAggregateAddress();
llvm::Instruction *Placeholder =
cast<llvm::Instruction>(Addr.getPointer());
@@ -5138,7 +5160,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
} else if (ArgInfo.getInAllocaIndirect()) {
// Make a temporary alloca and store the address of it into the argument
// struct.
- Address Addr = CreateMemTempWithoutCast(
+ RawAddress Addr = CreateMemTempWithoutCast(
I->Ty, getContext().getTypeAlignInChars(I->Ty),
"indirect-arg-temp");
I->copyInto(*this, Addr);
@@ -5160,12 +5182,12 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
assert(NumIRArgs == 1);
if (!I->isAggregate()) {
// Make a temporary alloca to pass the argument.
- Address Addr = CreateMemTempWithoutCast(
+ RawAddress Addr = CreateMemTempWithoutCast(
I->Ty, ArgInfo.getIndirectAlign(), "indirect-arg-temp");
- llvm::Value *Val = Addr.getPointer();
+ llvm::Value *Val = getAsNaturalPointerTo(Addr, I->Ty);
if (ArgHasMaybeUndefAttr)
- Val = Builder.CreateFreeze(Addr.getPointer());
+ Val = Builder.CreateFreeze(Val);
IRCallArgs[FirstIRArg] = Val;
I->copyInto(*this, Addr);
@@ -5181,7 +5203,6 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
Address Addr = I->hasLValue()
? I->getKnownLValue().getAddress(*this)
: I->getKnownRValue().getAggregateAddress();
- llvm::Value *V = Addr.getPointer();
CharUnits Align = ArgInfo.getIndirectAlign();
const llvm::DataLayout *TD = &CGM.getDataLayout();
@@ -5192,8 +5213,9 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
bool NeedCopy = false;
if (Addr.getAlignment() < Align &&
- llvm::getOrEnforceKnownAlignment(V, Align.getAsAlign(), *TD) <
- Align.getAsAlign()) {
+ llvm::getOrEnforceKnownAlignment(Addr.emitRawPointer(*this),
+ Align.getAsAlign(),
+ *TD) < Align.getAsAlign()) {
NeedCopy = true;
} else if (I->hasLValue()) {
auto LV = I->getKnownLValue();
@@ -5224,11 +5246,11 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
if (NeedCopy) {
// Create an aligned temporary, and copy to it.
- Address AI = CreateMemTempWithoutCast(
+ RawAddress AI = CreateMemTempWithoutCast(
I->Ty, ArgInfo.getIndirectAlign(), "byval-temp");
- llvm::Value *Val = AI.getPointer();
+ llvm::Value *Val = getAsNaturalPointerTo(AI, I->Ty);
if (ArgHasMaybeUndefAttr)
- Val = Builder.CreateFreeze(AI.getPointer());
+ Val = Builder.CreateFreeze(Val);
IRCallArgs[FirstIRArg] = Val;
// Emit lifetime markers for the temporary alloca.
@@ -5245,6 +5267,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
I->copyInto(*this, AI);
} else {
// Skip the extra memcpy call.
+ llvm::Value *V = getAsNaturalPointerTo(Addr, I->Ty);
auto *T = llvm::PointerType::get(
CGM.getLLVMContext(), CGM.getDataLayout().getAllocaAddrSpace());
@@ -5284,8 +5307,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
assert(!swiftErrorTemp.isValid() && "multiple swifterror args");
QualType pointeeTy = I->Ty->getPointeeType();
- swiftErrorArg = Address(V, ConvertTypeForMem(pointeeTy),
- getContext().getTypeAlignInChars(pointeeTy));
+ swiftErrorArg = makeNaturalAddressForPointer(
+ V, pointeeTy, getContext().getTypeAlignInChars(pointeeTy));
swiftErrorTemp =
CreateMemTemp(pointeeTy, getPointerAlign(), "swifterror.temp");
@@ -5422,7 +5445,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
llvm::Value *tempSize = nullptr;
Address addr = Address::invalid();
- Address AllocaAddr = Address::invalid();
+ RawAddress AllocaAddr = RawAddress::invalid();
if (I->isAggregate()) {
addr = I->hasLValue() ? I->getKnownLValue().getAddress(*this)
: I->getKnownRValue().getAggregateAddress();
@@ -5856,7 +5879,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
return RValue::getComplex(std::make_pair(Real, Imag));
}
case TEK_Aggregate: {
- Address DestPtr = ReturnValue.getValue();
+ Address DestPtr = ReturnValue.getAddress();
bool DestIsVolatile = ReturnValue.isVolatile();
if (!DestPtr.isValid()) {