aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CGCall.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-02-11 12:38:04 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-02-11 12:38:11 +0000
commite3b557809604d036af6e00c60f012c2025b59a5e (patch)
tree8a11ba2269a3b669601e2fd41145b174008f4da8 /clang/lib/CodeGen/CGCall.cpp
parent08e8dd7b9db7bb4a9de26d44c1cbfd24e869c014 (diff)
Diffstat (limited to 'clang/lib/CodeGen/CGCall.cpp')
-rw-r--r--clang/lib/CodeGen/CGCall.cpp251
1 files changed, 161 insertions, 90 deletions
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index dfa78bf59c65..dfa552161d7c 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -40,6 +40,7 @@
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Type.h"
#include "llvm/Transforms/Utils/Local.h"
+#include <optional>
using namespace clang;
using namespace CodeGen;
@@ -112,7 +113,7 @@ CodeGenTypes::arrangeFreeFunctionType(CanQual<FunctionNoProtoType> FTNP) {
// variadic type.
return arrangeLLVMFunctionInfo(FTNP->getReturnType().getUnqualifiedType(),
/*instanceMethod=*/false,
- /*chainCall=*/false, None,
+ /*chainCall=*/false, std::nullopt,
FTNP->getExtInfo(), {}, RequiredArgs(0));
}
@@ -459,7 +460,8 @@ CodeGenTypes::arrangeFunctionDeclaration(const FunctionDecl *FD) {
if (CanQual<FunctionNoProtoType> noProto = FTy.getAs<FunctionNoProtoType>()) {
return arrangeLLVMFunctionInfo(
noProto->getReturnType(), /*instanceMethod=*/false,
- /*chainCall=*/false, None, noProto->getExtInfo(), {},RequiredArgs::All);
+ /*chainCall=*/false, std::nullopt, noProto->getExtInfo(), {},
+ RequiredArgs::All);
}
return arrangeFreeFunctionType(FTy.castAs<FunctionProtoType>());
@@ -484,9 +486,11 @@ const CGFunctionInfo &
CodeGenTypes::arrangeObjCMessageSendSignature(const ObjCMethodDecl *MD,
QualType receiverType) {
SmallVector<CanQualType, 16> argTys;
- SmallVector<FunctionProtoType::ExtParameterInfo, 4> extParamInfos(2);
+ SmallVector<FunctionProtoType::ExtParameterInfo, 4> extParamInfos(
+ MD->isDirectMethod() ? 1 : 2);
argTys.push_back(Context.getCanonicalParamType(receiverType));
- argTys.push_back(Context.getCanonicalParamType(Context.getObjCSelType()));
+ if (!MD->isDirectMethod())
+ argTys.push_back(Context.getCanonicalParamType(Context.getObjCSelType()));
// FIXME: Kill copy?
for (const auto *I : MD->parameters()) {
argTys.push_back(Context.getCanonicalParamType(I->getType()));
@@ -708,7 +712,7 @@ CodeGenTypes::arrangeCXXMethodCall(const CallArgList &args,
const CGFunctionInfo &CodeGenTypes::arrangeNullaryFunction() {
return arrangeLLVMFunctionInfo(
getContext().VoidTy, /*instanceMethod=*/false, /*chainCall=*/false,
- None, FunctionType::ExtInfo(), {}, RequiredArgs::All);
+ std::nullopt, FunctionType::ExtInfo(), {}, RequiredArgs::All);
}
const CGFunctionInfo &
@@ -1144,7 +1148,7 @@ static Address 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().getPrefTypeAlignment(Ty);
+ auto PrefAlign = CGF.CGM.getDataLayout().getPrefTypeAlign(Ty);
CharUnits Align = std::max(MinAlign, CharUnits::fromQuantity(PrefAlign));
return CGF.CreateTempAlloca(Ty, Align, Name + ".coerce");
@@ -1257,7 +1261,7 @@ static llvm::Value *CreateCoercedLoad(Address Src, llvm::Type *Ty,
if (llvm::StructType *SrcSTy = dyn_cast<llvm::StructType>(SrcTy)) {
Src = EnterStructPointerForCoercedAccess(Src, SrcSTy,
- DstSize.getFixedSize(), CGF);
+ DstSize.getFixedValue(), CGF);
SrcTy = Src.getElementType();
}
@@ -1273,7 +1277,7 @@ static llvm::Value *CreateCoercedLoad(Address Src, llvm::Type *Ty,
// If load is legal, just bitcast the src pointer.
if (!SrcSize.isScalable() && !DstSize.isScalable() &&
- SrcSize.getFixedSize() >= DstSize.getFixedSize()) {
+ SrcSize.getFixedValue() >= DstSize.getFixedValue()) {
// Generally SrcSize is never greater than DstSize, since this means we are
// losing bits. However, this can happen in cases where the structure has
// additional padding, for example due to a user specified alignment.
@@ -1319,7 +1323,7 @@ static llvm::Value *CreateCoercedLoad(Address Src, llvm::Type *Ty,
CGF.Builder.CreateMemCpy(
Tmp.getPointer(), Tmp.getAlignment().getAsAlign(), Src.getPointer(),
Src.getAlignment().getAsAlign(),
- llvm::ConstantInt::get(CGF.IntPtrTy, SrcSize.getKnownMinSize()));
+ llvm::ConstantInt::get(CGF.IntPtrTy, SrcSize.getKnownMinValue()));
return CGF.Builder.CreateLoad(Tmp);
}
@@ -1362,7 +1366,7 @@ static void CreateCoercedStore(llvm::Value *Src,
if (llvm::StructType *DstSTy = dyn_cast<llvm::StructType>(DstTy)) {
Dst = EnterStructPointerForCoercedAccess(Dst, DstSTy,
- SrcSize.getFixedSize(), CGF);
+ SrcSize.getFixedValue(), CGF);
DstTy = Dst.getElementType();
}
@@ -1389,7 +1393,7 @@ static void CreateCoercedStore(llvm::Value *Src,
// If store is legal, just bitcast the src pointer.
if (isa<llvm::ScalableVectorType>(SrcTy) ||
isa<llvm::ScalableVectorType>(DstTy) ||
- SrcSize.getFixedSize() <= DstSize.getFixedSize()) {
+ SrcSize.getFixedValue() <= DstSize.getFixedValue()) {
Dst = CGF.Builder.CreateElementBitCast(Dst, SrcTy);
CGF.EmitAggregateStore(Src, Dst, DstIsVolatile);
} else {
@@ -1407,7 +1411,7 @@ static void CreateCoercedStore(llvm::Value *Src,
CGF.Builder.CreateMemCpy(
Dst.getPointer(), Dst.getAlignment().getAsAlign(), Tmp.getPointer(),
Tmp.getAlignment().getAsAlign(),
- llvm::ConstantInt::get(CGF.IntPtrTy, DstSize.getFixedSize()));
+ llvm::ConstantInt::get(CGF.IntPtrTy, DstSize.getFixedValue()));
}
}
@@ -1633,7 +1637,7 @@ CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI) {
// sret things on win32 aren't void, they return the sret pointer.
QualType ret = FI.getReturnType();
llvm::Type *ty = ConvertType(ret);
- unsigned addressSpace = Context.getTargetAddressSpace(ret);
+ unsigned addressSpace = CGM.getTypes().getTargetAddressSpace(ret);
resultType = llvm::PointerType::get(ty, addressSpace);
} else {
resultType = llvm::Type::getVoidTy(getLLVMContext());
@@ -1657,7 +1661,7 @@ CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI) {
if (IRFunctionArgs.hasSRetArg()) {
QualType Ret = FI.getReturnType();
llvm::Type *Ty = ConvertType(Ret);
- unsigned AddressSpace = Context.getTargetAddressSpace(Ret);
+ unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(Ret);
ArgTypes[IRFunctionArgs.getSRetArgNo()] =
llvm::PointerType::get(Ty, AddressSpace);
}
@@ -1723,7 +1727,7 @@ CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI) {
case ABIArgInfo::CoerceAndExpand: {
auto ArgTypesIter = ArgTypes.begin() + FirstIRArg;
- for (auto EltTy : ArgInfo.getCoerceAndExpandTypeSequence()) {
+ for (auto *EltTy : ArgInfo.getCoerceAndExpandTypeSequence()) {
*ArgTypesIter++ = EltTy;
}
assert(ArgTypesIter == ArgTypes.begin() + FirstIRArg + NumIRArgs);
@@ -1781,7 +1785,7 @@ static void AddAttributesFromAssumes(llvm::AttrBuilder &FuncAttrs,
}
bool CodeGenModule::MayDropFunctionReturn(const ASTContext &Context,
- QualType ReturnType) {
+ QualType ReturnType) const {
// We can't just discard the return value for a record type with a
// complex destructor or a non-trivially copyable type.
if (const RecordType *RT =
@@ -1792,6 +1796,38 @@ bool CodeGenModule::MayDropFunctionReturn(const ASTContext &Context,
return ReturnType.isTriviallyCopyableType(Context);
}
+static bool HasStrictReturn(const CodeGenModule &Module, QualType RetTy,
+ const Decl *TargetDecl) {
+ // As-is msan can not tolerate noundef mismatch between caller and
+ // implementation. Mismatch is possible for e.g. indirect calls from C-caller
+ // into C++. Such mismatches lead to confusing false reports. To avoid
+ // expensive workaround on msan we enforce initialization event in uncommon
+ // cases where it's allowed.
+ if (Module.getLangOpts().Sanitize.has(SanitizerKind::Memory))
+ return true;
+ // C++ explicitly makes returning undefined values UB. C's rule only applies
+ // to used values, so we never mark them noundef for now.
+ if (!Module.getLangOpts().CPlusPlus)
+ return false;
+ if (TargetDecl) {
+ if (const FunctionDecl *FDecl = dyn_cast<FunctionDecl>(TargetDecl)) {
+ if (FDecl->isExternC())
+ return false;
+ } else if (const VarDecl *VDecl = dyn_cast<VarDecl>(TargetDecl)) {
+ // Function pointer.
+ if (VDecl->isExternC())
+ return false;
+ }
+ }
+
+ // We don't want to be too aggressive with the return checking, unless
+ // it's explicit in the code opts or we're using an appropriate sanitizer.
+ // Try to respect what the programmer intended.
+ return Module.getCodeGenOpts().StrictReturn ||
+ !Module.MayDropFunctionReturn(Module.getContext(), RetTy) ||
+ Module.getLangOpts().Sanitize.has(SanitizerKind::Return);
+}
+
void CodeGenModule::getDefaultFunctionAttributes(StringRef Name,
bool HasOptnone,
bool AttrOnCallSite,
@@ -1820,19 +1856,16 @@ void CodeGenModule::getDefaultFunctionAttributes(StringRef Name,
if (!CodeGenOpts.TrapFuncName.empty())
FuncAttrs.addAttribute("trap-func-name", CodeGenOpts.TrapFuncName);
} else {
- StringRef FpKind;
switch (CodeGenOpts.getFramePointer()) {
case CodeGenOptions::FramePointerKind::None:
- FpKind = "none";
+ // This is the default behavior.
break;
case CodeGenOptions::FramePointerKind::NonLeaf:
- FpKind = "non-leaf";
- break;
case CodeGenOptions::FramePointerKind::All:
- FpKind = "all";
- break;
+ FuncAttrs.addAttribute("frame-pointer",
+ CodeGenOptions::getFramePointerKindName(
+ CodeGenOpts.getFramePointer()));
}
- FuncAttrs.addAttribute("frame-pointer", FpKind);
if (CodeGenOpts.LessPreciseFPMAD)
FuncAttrs.addAttribute("less-precise-fpmad", "true");
@@ -1860,7 +1893,12 @@ void CodeGenModule::getDefaultFunctionAttributes(StringRef Name,
FuncAttrs.addAttribute("no-nans-fp-math", "true");
if (LangOpts.ApproxFunc)
FuncAttrs.addAttribute("approx-func-fp-math", "true");
- if (LangOpts.UnsafeFPMath)
+ if (LangOpts.AllowFPReassoc && LangOpts.AllowRecip &&
+ LangOpts.NoSignedZero && LangOpts.ApproxFunc &&
+ (LangOpts.getDefaultFPContractMode() ==
+ LangOptions::FPModeKind::FPM_Fast ||
+ LangOpts.getDefaultFPContractMode() ==
+ LangOptions::FPModeKind::FPM_FastHonorPragmas))
FuncAttrs.addAttribute("unsafe-fp-math", "true");
if (CodeGenOpts.SoftFloat)
FuncAttrs.addAttribute("use-soft-float", "true");
@@ -1931,11 +1969,11 @@ void CodeGenModule::getDefaultFunctionAttributes(StringRef Name,
FuncAttrs.addAttribute(llvm::Attribute::Convergent);
}
- // TODO: NoUnwind attribute should be added for other GPU modes OpenCL, HIP,
+ // TODO: NoUnwind attribute should be added for other GPU modes HIP,
// SYCL, OpenMP offload. AFAIK, none of them support exceptions in device
// code.
- if (getLangOpts().CUDA && getLangOpts().CUDAIsDevice) {
- // Exceptions aren't supported in CUDA device code.
+ if ((getLangOpts().CUDA && getLangOpts().CUDAIsDevice) ||
+ getLangOpts().OpenCL) {
FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
}
@@ -2046,6 +2084,27 @@ static bool DetermineNoUndef(QualType QTy, CodeGenTypes &Types,
return false;
}
+/// Check if the argument of a function has maybe_undef attribute.
+static bool IsArgumentMaybeUndef(const Decl *TargetDecl,
+ unsigned NumRequiredArgs, unsigned ArgNo) {
+ const auto *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl);
+ if (!FD)
+ return false;
+
+ // Assume variadic arguments do not have maybe_undef attribute.
+ if (ArgNo >= NumRequiredArgs)
+ return false;
+
+ // Check if argument has maybe_undef attribute.
+ if (ArgNo < FD->getNumParams()) {
+ const ParmVarDecl *Param = FD->getParamDecl(ArgNo);
+ if (Param && Param->hasAttr<MaybeUndefAttr>())
+ return true;
+ }
+
+ return false;
+}
+
/// Construct the IR attribute list of a function or call.
///
/// When adding an attribute, please consider where it should be handled:
@@ -2094,6 +2153,15 @@ void CodeGenModule::ConstructAttributeList(StringRef Name,
// The NoBuiltinAttr attached to the target FunctionDecl.
const NoBuiltinAttr *NBA = nullptr;
+ // Some ABIs may result in additional accesses to arguments that may
+ // otherwise not be present.
+ auto AddPotentialArgAccess = [&]() {
+ llvm::Attribute A = FuncAttrs.getAttribute(llvm::Attribute::Memory);
+ if (A.isValid())
+ FuncAttrs.addMemoryAttr(A.getMemoryEffects() |
+ llvm::MemoryEffects::argMemOnly());
+ };
+
// Collect function IR attributes based on declaration-specific
// information.
// FIXME: handle sseregparm someday...
@@ -2140,18 +2208,18 @@ void CodeGenModule::ConstructAttributeList(StringRef Name,
// 'const', 'pure' and 'noalias' attributed functions are also nounwind.
if (TargetDecl->hasAttr<ConstAttr>()) {
- FuncAttrs.addAttribute(llvm::Attribute::ReadNone);
+ FuncAttrs.addMemoryAttr(llvm::MemoryEffects::none());
FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
// gcc specifies that 'const' functions have greater restrictions than
// 'pure' functions, so they also cannot have infinite loops.
FuncAttrs.addAttribute(llvm::Attribute::WillReturn);
} else if (TargetDecl->hasAttr<PureAttr>()) {
- FuncAttrs.addAttribute(llvm::Attribute::ReadOnly);
+ FuncAttrs.addMemoryAttr(llvm::MemoryEffects::readOnly());
FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
// gcc specifies that 'pure' functions cannot have infinite loops.
FuncAttrs.addAttribute(llvm::Attribute::WillReturn);
} else if (TargetDecl->hasAttr<NoAliasAttr>()) {
- FuncAttrs.addAttribute(llvm::Attribute::ArgMemOnly);
+ FuncAttrs.addMemoryAttr(llvm::MemoryEffects::argMemOnly());
FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
}
if (TargetDecl->hasAttr<RestrictAttr>())
@@ -2168,7 +2236,7 @@ void CodeGenModule::ConstructAttributeList(StringRef Name,
HasOptnone = TargetDecl->hasAttr<OptimizeNoneAttr>();
if (auto *AllocSize = TargetDecl->getAttr<AllocSizeAttr>()) {
- Optional<unsigned> NumElemsParam;
+ std::optional<unsigned> NumElemsParam;
if (AllocSize->getNumElemsParam().isValid())
NumElemsParam = AllocSize->getNumElemsParam().getLLVMIndex();
FuncAttrs.addAllocSizeAttr(AllocSize->getElemSizeParam().getLLVMIndex(),
@@ -2237,9 +2305,8 @@ void CodeGenModule::ConstructAttributeList(StringRef Name,
// Add "sample-profile-suffix-elision-policy" attribute for internal linkage
// functions with -funique-internal-linkage-names.
if (TargetDecl && CodeGenOpts.UniqueInternalLinkageNames) {
- if (isa<FunctionDecl>(TargetDecl)) {
- if (this->getFunctionLinkage(CalleeInfo.getCalleeDecl()) ==
- llvm::GlobalValue::InternalLinkage)
+ if (const auto *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl)) {
+ if (!FD->isExternallyVisible())
FuncAttrs.addAttribute("sample-profile-suffix-elision-policy",
"selected");
}
@@ -2287,27 +2354,9 @@ void CodeGenModule::ConstructAttributeList(StringRef Name,
const ABIArgInfo &RetAI = FI.getReturnInfo();
const llvm::DataLayout &DL = getDataLayout();
- // C++ explicitly makes returning undefined values UB. C's rule only applies
- // to used values, so we never mark them noundef for now.
- bool HasStrictReturn = getLangOpts().CPlusPlus;
- if (TargetDecl && HasStrictReturn) {
- if (const FunctionDecl *FDecl = dyn_cast<FunctionDecl>(TargetDecl))
- HasStrictReturn &= !FDecl->isExternC();
- else if (const VarDecl *VDecl = dyn_cast<VarDecl>(TargetDecl))
- // Function pointer
- HasStrictReturn &= !VDecl->isExternC();
- }
-
- // We don't want to be too aggressive with the return checking, unless
- // it's explicit in the code opts or we're using an appropriate sanitizer.
- // Try to respect what the programmer intended.
- HasStrictReturn &= getCodeGenOpts().StrictReturn ||
- !MayDropFunctionReturn(getContext(), RetTy) ||
- getLangOpts().Sanitize.has(SanitizerKind::Memory) ||
- getLangOpts().Sanitize.has(SanitizerKind::Return);
-
// Determine if the return type could be partially undef
- if (CodeGenOpts.EnableNoundefAttrs && HasStrictReturn) {
+ if (CodeGenOpts.EnableNoundefAttrs &&
+ HasStrictReturn(*this, RetTy, TargetDecl)) {
if (!RetTy->isVoidType() && RetAI.getKind() != ABIArgInfo::Indirect &&
DetermineNoUndef(RetTy, getTypes(), DL, RetAI))
RetAttrs.addAttribute(llvm::Attribute::NoUndef);
@@ -2319,7 +2368,7 @@ void CodeGenModule::ConstructAttributeList(StringRef Name,
RetAttrs.addAttribute(llvm::Attribute::SExt);
else
RetAttrs.addAttribute(llvm::Attribute::ZExt);
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case ABIArgInfo::Direct:
if (RetAI.getInReg())
RetAttrs.addAttribute(llvm::Attribute::InReg);
@@ -2330,8 +2379,7 @@ void CodeGenModule::ConstructAttributeList(StringRef Name,
case ABIArgInfo::InAlloca:
case ABIArgInfo::Indirect: {
// inalloca and sret disable readnone and readonly
- FuncAttrs.removeAttribute(llvm::Attribute::ReadOnly)
- .removeAttribute(llvm::Attribute::ReadNone);
+ AddPotentialArgAccess();
break;
}
@@ -2350,7 +2398,7 @@ void CodeGenModule::ConstructAttributeList(StringRef Name,
if (!PTy->isIncompleteType() && PTy->isConstantSizeType())
RetAttrs.addDereferenceableAttr(
getMinimumObjectSize(PTy).getQuantity());
- if (getContext().getTargetAddressSpace(PTy) == 0 &&
+ if (getTypes().getTargetAddressSpace(PTy) == 0 &&
!CodeGenOpts.NullPointerIsValid)
RetAttrs.addAttribute(llvm::Attribute::NonNull);
if (PTy->isObjectType()) {
@@ -2399,7 +2447,7 @@ void CodeGenModule::ConstructAttributeList(StringRef Name,
FI.arg_begin()->type.castAs<PointerType>()->getPointeeType();
if (!CodeGenOpts.NullPointerIsValid &&
- getContext().getTargetAddressSpace(FI.arg_begin()->type) == 0) {
+ getTypes().getTargetAddressSpace(FI.arg_begin()->type) == 0) {
Attrs.addAttribute(llvm::Attribute::NonNull);
Attrs.addDereferenceableAttr(getMinimumObjectSize(ThisTy).getQuantity());
} else {
@@ -2455,7 +2503,7 @@ void CodeGenModule::ConstructAttributeList(StringRef Name,
Attrs.addAttribute(llvm::Attribute::SExt);
else
Attrs.addAttribute(llvm::Attribute::ZExt);
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case ABIArgInfo::Direct:
if (ArgNo == 0 && FI.isChainCall())
Attrs.addAttribute(llvm::Attribute::Nest);
@@ -2501,9 +2549,7 @@ void CodeGenModule::ConstructAttributeList(StringRef Name,
Attrs.addAlignmentAttr(Align.getQuantity());
// byval disables readnone and readonly.
- FuncAttrs.removeAttribute(llvm::Attribute::ReadOnly)
- .removeAttribute(llvm::Attribute::ReadNone);
-
+ AddPotentialArgAccess();
break;
}
case ABIArgInfo::IndirectAliased: {
@@ -2519,8 +2565,7 @@ void CodeGenModule::ConstructAttributeList(StringRef Name,
case ABIArgInfo::InAlloca:
// inalloca disables readnone and readonly.
- FuncAttrs.removeAttribute(llvm::Attribute::ReadOnly)
- .removeAttribute(llvm::Attribute::ReadNone);
+ AddPotentialArgAccess();
continue;
}
@@ -2529,7 +2574,7 @@ void CodeGenModule::ConstructAttributeList(StringRef Name,
if (!PTy->isIncompleteType() && PTy->isConstantSizeType())
Attrs.addDereferenceableAttr(
getMinimumObjectSize(PTy).getQuantity());
- if (getContext().getTargetAddressSpace(PTy) == 0 &&
+ if (getTypes().getTargetAddressSpace(PTy) == 0 &&
!CodeGenOpts.NullPointerIsValid)
Attrs.addAttribute(llvm::Attribute::NonNull);
if (PTy->isObjectType()) {
@@ -2851,7 +2896,7 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
llvm::Align Alignment =
CGM.getNaturalTypeAlignment(ETy).getAsAlign();
AI->addAttrs(llvm::AttrBuilder(getLLVMContext()).addAlignmentAttr(Alignment));
- if (!getContext().getTargetAddressSpace(ETy) &&
+ if (!getTypes().getTargetAddressSpace(ETy) &&
!CGM.getCodeGenOpts().NullPointerIsValid)
AI->addAttr(llvm::Attribute::NonNull);
}
@@ -2860,7 +2905,7 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
// Set `align` attribute if any.
const auto *AVAttr = PVD->getAttr<AlignValueAttr>();
if (!AVAttr)
- if (const auto *TOTy = dyn_cast<TypedefType>(OTy))
+ if (const auto *TOTy = OTy->getAs<TypedefType>())
AVAttr = TOTy->getDecl()->getAttr<AlignValueAttr>();
if (AVAttr && !SanOpts.has(SanitizerKind::Alignment)) {
// If alignment-assumption sanitizer is enabled, we do *not* add
@@ -3509,7 +3554,7 @@ void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI,
switch (RetAI.getKind()) {
case ABIArgInfo::InAlloca:
- // Aggregrates get evaluated directly into the destination. Sometimes we
+ // Aggregates get evaluated directly into the destination. Sometimes we
// need to return the sret value in a register, though.
assert(hasAggregateEvaluationKind(RetTy));
if (RetAI.getInAllocaSRet()) {
@@ -3537,7 +3582,7 @@ void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI,
break;
}
case TEK_Aggregate:
- // Do nothing; aggregrates get evaluated directly into the destination.
+ // Do nothing; aggregates get evaluated directly into the destination.
break;
case TEK_Scalar: {
LValueBaseInfo BaseInfo;
@@ -4078,7 +4123,7 @@ void CodeGenFunction::EmitNonNullArgCheck(RValue RV, QualType ArgType,
bool CanCheckNullability = false;
if (SanOpts.has(SanitizerKind::NullabilityArg) && !NNAttr && PVD) {
- auto Nullability = PVD->getType()->getNullability(getContext());
+ auto Nullability = PVD->getType()->getNullability();
CanCheckNullability = Nullability &&
*Nullability == NullabilityKind::NonNull &&
PVD->getTypeSourceInfo();
@@ -4106,7 +4151,7 @@ void CodeGenFunction::EmitNonNullArgCheck(RValue RV, QualType ArgType,
EmitCheckSourceLocation(ArgLoc), EmitCheckSourceLocation(AttrLoc),
llvm::ConstantInt::get(Int32Ty, ArgNo + 1),
};
- EmitCheck(std::make_pair(Cond, CheckKind), Handler, StaticData, None);
+ EmitCheck(std::make_pair(Cond, CheckKind), Handler, StaticData, std::nullopt);
}
// Check if the call is going to use the inalloca convention. This needs to
@@ -4426,7 +4471,7 @@ QualType CodeGenFunction::getVarArgType(const Expr *Arg) {
if (Arg->getType()->isIntegerType() &&
getContext().getTypeSize(Arg->getType()) <
- getContext().getTargetInfo().getPointerWidth(0) &&
+ getContext().getTargetInfo().getPointerWidth(LangAS::Default) &&
Arg->isNullPointerConstant(getContext(),
Expr::NPC_ValueDependentIsNotNull)) {
return getContext().getIntPtrType();
@@ -4449,7 +4494,7 @@ CodeGenFunction::AddObjCARCExceptionMetadata(llvm::Instruction *Inst) {
llvm::CallInst *
CodeGenFunction::EmitNounwindRuntimeCall(llvm::FunctionCallee callee,
const llvm::Twine &name) {
- return EmitNounwindRuntimeCall(callee, None, name);
+ return EmitNounwindRuntimeCall(callee, std::nullopt, name);
}
/// Emits a call to the given nounwind runtime function.
@@ -4466,7 +4511,7 @@ CodeGenFunction::EmitNounwindRuntimeCall(llvm::FunctionCallee callee,
/// runtime function.
llvm::CallInst *CodeGenFunction::EmitRuntimeCall(llvm::FunctionCallee callee,
const llvm::Twine &name) {
- return EmitRuntimeCall(callee, None, name);
+ return EmitRuntimeCall(callee, std::nullopt, name);
}
// Calls which may throw must have operand bundles indicating which funclet
@@ -4530,7 +4575,7 @@ void CodeGenFunction::EmitNoreturnRuntimeCallOrInvoke(
llvm::CallBase *
CodeGenFunction::EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee,
const Twine &name) {
- return EmitRuntimeCallOrInvoke(callee, None, name);
+ return EmitRuntimeCallOrInvoke(callee, std::nullopt, name);
}
/// Emits a call or invoke instruction to the given runtime function.
@@ -4580,7 +4625,7 @@ namespace {
/// Specify given \p NewAlign as the alignment of return value attribute. If
/// such attribute already exists, re-set it to the maximal one of two options.
-LLVM_NODISCARD llvm::AttributeList
+[[nodiscard]] llvm::AttributeList
maybeRaiseRetAlignmentAttribute(llvm::LLVMContext &Ctx,
const llvm::AttributeList &Attrs,
llvm::Align NewAlign) {
@@ -4611,7 +4656,7 @@ protected:
public:
/// If we can, materialize the alignment as an attribute on return value.
- LLVM_NODISCARD llvm::AttributeList
+ [[nodiscard]] llvm::AttributeList
TryEmitAsCallSiteAttribute(const llvm::AttributeList &Attrs) {
if (!AA || OffsetCI || CGF.SanOpts.has(SanitizerKind::Alignment))
return Attrs;
@@ -4680,7 +4725,7 @@ public:
static unsigned getMaxVectorWidth(const llvm::Type *Ty) {
if (auto *VT = dyn_cast<llvm::VectorType>(Ty))
- return VT->getPrimitiveSizeInBits().getKnownMinSize();
+ return VT->getPrimitiveSizeInBits().getKnownMinValue();
if (auto *AT = dyn_cast<llvm::ArrayType>(Ty))
return getMaxVectorWidth(AT->getElementType());
@@ -4821,6 +4866,9 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
unsigned FirstIRArg, NumIRArgs;
std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
+ bool ArgHasMaybeUndefAttr =
+ IsArgumentMaybeUndef(TargetDecl, CallInfo.getNumRequiredArgs(), ArgNo);
+
switch (ArgInfo.getKind()) {
case ABIArgInfo::InAlloca: {
assert(NumIRArgs == 0);
@@ -4879,7 +4927,11 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
// Make a temporary alloca to pass the argument.
Address Addr = CreateMemTempWithoutCast(
I->Ty, ArgInfo.getIndirectAlign(), "indirect-arg-temp");
- IRCallArgs[FirstIRArg] = Addr.getPointer();
+
+ llvm::Value *Val = Addr.getPointer();
+ if (ArgHasMaybeUndefAttr)
+ Val = Builder.CreateFreeze(Addr.getPointer());
+ IRCallArgs[FirstIRArg] = Val;
I->copyInto(*this, Addr);
} else {
@@ -4937,7 +4989,10 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
// Create an aligned temporary, and copy to it.
Address AI = CreateMemTempWithoutCast(
I->Ty, ArgInfo.getIndirectAlign(), "byval-temp");
- IRCallArgs[FirstIRArg] = AI.getPointer();
+ llvm::Value *Val = AI.getPointer();
+ if (ArgHasMaybeUndefAttr)
+ Val = Builder.CreateFreeze(AI.getPointer());
+ IRCallArgs[FirstIRArg] = Val;
// Emit lifetime markers for the temporary alloca.
llvm::TypeSize ByvalTempElementSize =
@@ -4956,9 +5011,13 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
auto *T = llvm::PointerType::getWithSamePointeeType(
cast<llvm::PointerType>(V->getType()),
CGM.getDataLayout().getAllocaAddrSpace());
- IRCallArgs[FirstIRArg] = getTargetHooks().performAddrSpaceCast(
+
+ llvm::Value *Val = getTargetHooks().performAddrSpaceCast(
*this, V, LangAS::Default, CGM.getASTAllocaAddressSpace(), T,
true);
+ if (ArgHasMaybeUndefAttr)
+ Val = Builder.CreateFreeze(Val);
+ IRCallArgs[FirstIRArg] = Val;
}
}
break;
@@ -5012,6 +5071,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
V->getType() != IRFuncTy->getParamType(FirstIRArg))
V = Builder.CreateBitCast(V, IRFuncTy->getParamType(FirstIRArg));
+ if (ArgHasMaybeUndefAttr)
+ V = Builder.CreateFreeze(V);
IRCallArgs[FirstIRArg] = V;
break;
}
@@ -5056,6 +5117,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
Address EltPtr = Builder.CreateStructGEP(Src, i);
llvm::Value *LI = Builder.CreateLoad(EltPtr);
+ if (ArgHasMaybeUndefAttr)
+ LI = Builder.CreateFreeze(LI);
IRCallArgs[FirstIRArg + i] = LI;
}
} else {
@@ -5072,6 +5135,9 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
if (ATy != nullptr && isa<RecordType>(I->Ty.getCanonicalType()))
Load = EmitCMSEClearRecord(Load, ATy, I->Ty);
}
+
+ if (ArgHasMaybeUndefAttr)
+ Load = Builder.CreateFreeze(Load);
IRCallArgs[FirstIRArg] = Load;
}
@@ -5095,15 +5161,14 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
llvm::Type *scalarType = RV.getScalarVal()->getType();
auto scalarSize = CGM.getDataLayout().getTypeAllocSize(scalarType);
- auto scalarAlign = CGM.getDataLayout().getPrefTypeAlignment(scalarType);
+ auto scalarAlign = CGM.getDataLayout().getPrefTypeAlign(scalarType);
// Materialize to a temporary.
- addr =
- CreateTempAlloca(RV.getScalarVal()->getType(),
- CharUnits::fromQuantity(std::max(
- layout->getAlignment().value(), scalarAlign)),
- "tmp",
- /*ArraySize=*/nullptr, &AllocaAddr);
+ addr = CreateTempAlloca(
+ RV.getScalarVal()->getType(),
+ CharUnits::fromQuantity(std::max(layout->getAlignment(), scalarAlign)),
+ "tmp",
+ /*ArraySize=*/nullptr, &AllocaAddr);
tempSize = EmitLifetimeStart(scalarSize, AllocaAddr.getPointer());
Builder.CreateStore(RV.getScalarVal(), addr);
@@ -5117,6 +5182,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
if (ABIArgInfo::isPaddingForCoerceAndExpand(eltType)) continue;
Address eltAddr = Builder.CreateStructGEP(addr, i);
llvm::Value *elt = Builder.CreateLoad(eltAddr);
+ if (ArgHasMaybeUndefAttr)
+ elt = Builder.CreateFreeze(elt);
IRCallArgs[IRArgPos++] = elt;
}
assert(IRArgPos == FirstIRArg + NumIRArgs);
@@ -5324,6 +5391,10 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
SmallVector<llvm::OperandBundleDef, 1> BundleList =
getBundlesForFunclet(CalleePtr);
+ if (SanOpts.has(SanitizerKind::KCFI) &&
+ !isa_and_nonnull<FunctionDecl>(TargetDecl))
+ EmitKCFIOperandBundle(ConcreteCallee, BundleList);
+
if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(CurFuncDecl))
if (FD->hasAttr<StrictFPAttr>())
// All calls within a strictfp function are marked strictfp
@@ -5506,7 +5577,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
Builder.CreateStore(elt, eltAddr);
}
// FALLTHROUGH
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
}
case ABIArgInfo::InAlloca: