namespace clang {
namespace CodeGen {
+// Indicates whether a pointer is known not to be null.
+enum KnownNonNull_t { NotKnownNonNull, KnownNonNull };
+
// We try to save some space by using 6 bits over two PointerIntPairs to store
// the alignment. However, some arches don't support 3 bits in a PointerIntPair
// so we fallback to storing the alignment separately.
template <typename T, bool = alignof(llvm::Value *) >= 8> class AddressImpl {};
template <typename T> class AddressImpl<T, false> {
- llvm::Value *Pointer;
+ llvm::PointerIntPair<llvm::Value *, 1, bool> PointerAndKnownNonNull;
llvm::Type *ElementType;
CharUnits Alignment;
public:
AddressImpl(llvm::Value *Pointer, llvm::Type *ElementType,
- CharUnits Alignment)
- : Pointer(Pointer), ElementType(ElementType), Alignment(Alignment) {}
- llvm::Value *getPointer() const { return Pointer; }
+ CharUnits Alignment, KnownNonNull_t IsKnownNonNull)
+ : PointerAndKnownNonNull(Pointer, IsKnownNonNull),
+ ElementType(ElementType), Alignment(Alignment) {}
+ llvm::Value *getPointer() const {
+ return PointerAndKnownNonNull.getPointer();
+ }
llvm::Type *getElementType() const { return ElementType; }
CharUnits getAlignment() const { return Alignment; }
+ KnownNonNull_t isKnownNonNull() const {
+ return (KnownNonNull_t)PointerAndKnownNonNull.getInt();
+ }
+ void setKnownNonNull() { PointerAndKnownNonNull.setInt(true); }
};
template <typename T> class AddressImpl<T, true> {
- // Int portion stores upper 3 bits of the log of the alignment.
+ // Int portion stores the non-null bit and the upper 2 bits of the log of the
+ // alignment.
llvm::PointerIntPair<llvm::Value *, 3, unsigned> Pointer;
// Int portion stores lower 3 bits of the log of the alignment.
llvm::PointerIntPair<llvm::Type *, 3, unsigned> ElementType;
public:
AddressImpl(llvm::Value *Pointer, llvm::Type *ElementType,
- CharUnits Alignment)
+ CharUnits Alignment, KnownNonNull_t IsKnownNonNull)
: Pointer(Pointer), ElementType(ElementType) {
- if (Alignment.isZero())
+ if (Alignment.isZero()) {
+ this->Pointer.setInt(IsKnownNonNull << 2);
return;
- // Currently the max supported alignment is much less than 1 << 63 and is
+ }
+ // Currently the max supported alignment is exactly 1 << 32 and is
// guaranteed to be a power of 2, so we can store the log of the alignment
- // into 6 bits.
+ // into 5 bits.
assert(Alignment.isPowerOfTwo() && "Alignment cannot be zero");
auto AlignLog = llvm::Log2_64(Alignment.getQuantity());
- assert(AlignLog < (1 << 6) && "cannot fit alignment into 6 bits");
- this->Pointer.setInt(AlignLog >> 3);
+ assert(AlignLog < (1 << 5) && "cannot fit alignment into 5 bits");
+ this->Pointer.setInt(IsKnownNonNull << 2 | AlignLog >> 3);
this->ElementType.setInt(AlignLog & 7);
}
llvm::Value *getPointer() const { return Pointer.getPointer(); }
llvm::Type *getElementType() const { return ElementType.getPointer(); }
CharUnits getAlignment() const {
- unsigned AlignLog = (Pointer.getInt() << 3) | ElementType.getInt();
+ unsigned AlignLog = ((Pointer.getInt() & 0x3) << 3) | ElementType.getInt();
return CharUnits::fromQuantity(CharUnits::QuantityType(1) << AlignLog);
}
+ KnownNonNull_t isKnownNonNull() const {
+ return (KnownNonNull_t)(!!(Pointer.getInt() & 0x4));
+ }
+ void setKnownNonNull() { Pointer.setInt(Pointer.getInt() | 0x4); }
};
/// An aligned address.
AddressImpl<void> A;
protected:
- Address(std::nullptr_t) : A(nullptr, nullptr, CharUnits::Zero()) {}
+ Address(std::nullptr_t)
+ : A(nullptr, nullptr, CharUnits::Zero(), NotKnownNonNull) {}
public:
- Address(llvm::Value *Pointer, llvm::Type *ElementType, CharUnits Alignment)
- : A(Pointer, ElementType, Alignment) {
+ Address(llvm::Value *Pointer, llvm::Type *ElementType, CharUnits Alignment,
+ KnownNonNull_t IsKnownNonNull = NotKnownNonNull)
+ : A(Pointer, ElementType, Alignment, IsKnownNonNull) {
assert(Pointer != nullptr && "Pointer cannot be null");
assert(ElementType != nullptr && "Element type cannot be null");
assert(llvm::cast<llvm::PointerType>(Pointer->getType())
/// Return address with different pointer, but same element type and
/// alignment.
- Address withPointer(llvm::Value *NewPointer) const {
- return Address(NewPointer, getElementType(), getAlignment());
+ Address withPointer(llvm::Value *NewPointer,
+ KnownNonNull_t IsKnownNonNull) const {
+ return Address(NewPointer, getElementType(), getAlignment(),
+ IsKnownNonNull);
}
/// Return address with different alignment, but same pointer and element
/// type.
Address withAlignment(CharUnits NewAlignment) const {
- return Address(getPointer(), getElementType(), NewAlignment);
+ return Address(getPointer(), getElementType(), NewAlignment,
+ isKnownNonNull());
+ }
+
+ /// Whether the pointer is known not to be null.
+ KnownNonNull_t isKnownNonNull() const {
+ assert(isValid());
+ return A.isKnownNonNull();
+ }
+
+ /// Set the non-null bit.
+ Address setKnownNonNull() {
+ assert(isValid());
+ A.setKnownNonNull();
+ return *this;
}
};
assert(cast<llvm::PointerType>(Ty)->isOpaqueOrPointeeTypeMatches(
Addr.getElementType()) &&
"Should not change the element type");
- return Addr.withPointer(CreateAddrSpaceCast(Addr.getPointer(), Ty, Name));
+ return Addr.withPointer(CreateAddrSpaceCast(Addr.getPointer(), Ty, Name),
+ Addr.isKnownNonNull());
}
/// Cast the element type of the given address to a different type,
const llvm::Twine &Name = "") {
auto *PtrTy = Ty->getPointerTo(Addr.getAddressSpace());
return Address(CreateBitCast(Addr.getPointer(), PtrTy, Name), Ty,
- Addr.getAlignment());
+ Addr.getAlignment(), Addr.isKnownNonNull());
}
using CGBuilderBaseTy::CreatePointerBitCastOrAddrSpaceCast;
const llvm::Twine &Name = "") {
llvm::Value *Ptr =
CreatePointerBitCastOrAddrSpaceCast(Addr.getPointer(), Ty, Name);
- return Address(Ptr, ElementTy, Addr.getAlignment());
+ return Address(Ptr, ElementTy, Addr.getAlignment(), Addr.isKnownNonNull());
}
/// Given
return Address(
CreateStructGEP(Addr.getElementType(), Addr.getPointer(), Index, Name),
ElTy->getElementType(Index),
- Addr.getAlignment().alignmentAtOffset(Offset));
+ Addr.getAlignment().alignmentAtOffset(Offset), Addr.isKnownNonNull());
}
/// Given
CreateInBoundsGEP(Addr.getElementType(), Addr.getPointer(),
{getSize(CharUnits::Zero()), getSize(Index)}, Name),
ElTy->getElementType(),
- Addr.getAlignment().alignmentAtOffset(Index * EltSize));
+ Addr.getAlignment().alignmentAtOffset(Index * EltSize),
+ Addr.isKnownNonNull());
}
/// Given
return Address(CreateInBoundsGEP(Addr.getElementType(), Addr.getPointer(),
getSize(Index), Name),
- ElTy,
- Addr.getAlignment().alignmentAtOffset(Index * EltSize));
+ ElTy, Addr.getAlignment().alignmentAtOffset(Index * EltSize),
+ Addr.isKnownNonNull());
}
/// Given
return Address(CreateGEP(Addr.getElementType(), Addr.getPointer(),
getSize(Index), Name),
Addr.getElementType(),
- Addr.getAlignment().alignmentAtOffset(Index * EltSize));
+ Addr.getAlignment().alignmentAtOffset(Index * EltSize),
+ NotKnownNonNull);
}
/// Create GEP with single dynamic index. The address alignment is reduced
return Address(
CreateGEP(Addr.getElementType(), Addr.getPointer(), Index, Name),
Addr.getElementType(),
- Addr.getAlignment().alignmentOfArrayElement(EltSize));
+ Addr.getAlignment().alignmentOfArrayElement(EltSize), NotKnownNonNull);
}
/// Given a pointer to i8, adjust it by a given constant offset.
return Address(CreateInBoundsGEP(Addr.getElementType(), Addr.getPointer(),
getSize(Offset), Name),
Addr.getElementType(),
- Addr.getAlignment().alignmentAtOffset(Offset));
+ Addr.getAlignment().alignmentAtOffset(Offset),
+ Addr.isKnownNonNull());
}
Address CreateConstByteGEP(Address Addr, CharUnits Offset,
const llvm::Twine &Name = "") {
return Address(CreateGEP(Addr.getElementType(), Addr.getPointer(),
getSize(Offset), Name),
Addr.getElementType(),
- Addr.getAlignment().alignmentAtOffset(Offset));
+ Addr.getAlignment().alignmentAtOffset(Offset),
+ NotKnownNonNull);
}
using CGBuilderBaseTy::CreateConstInBoundsGEP2_32;
llvm_unreachable("offset of GEP with constants is always computable");
return Address(GEP, GEP->getResultElementType(),
Addr.getAlignment().alignmentAtOffset(
- CharUnits::fromQuantity(Offset.getSExtValue())));
+ CharUnits::fromQuantity(Offset.getSExtValue())),
+ Addr.isKnownNonNull());
}
using CGBuilderBaseTy::CreateMemCpy;
using CGBuilderBaseTy::CreateLaunderInvariantGroup;
Address CreateLaunderInvariantGroup(Address Addr) {
- return Addr.withPointer(CreateLaunderInvariantGroup(Addr.getPointer()));
+ return Addr.withPointer(CreateLaunderInvariantGroup(Addr.getPointer()),
+ Addr.isKnownNonNull());
}
};
case ABIArgInfo::IndirectAliased: {
assert(NumIRArgs == 1);
Address ParamAddr = Address(Fn->getArg(FirstIRArg), ConvertTypeForMem(Ty),
- ArgI.getIndirectAlign());
+ ArgI.getIndirectAlign(), KnownNonNull);
if (!hasScalarEvaluationKind(Ty)) {
// Aggregates and complex variables are accessed by reference. All we
}
llvm::Type *Ty = ConvertType(MD->getThisType()->getPointeeType());
- return Address(LoadCXXThis(), Ty, CXXThisAlignment);
+ return Address(LoadCXXThis(), Ty, CXXThisAlignment, KnownNonNull);
}
/// Emit the address of a field using a member data pointer.
llvm::PHINode *PHI = Builder.CreatePHI(BasePtrTy, 2, "cast.result");
PHI->addIncoming(Value.getPointer(), notNullBB);
PHI->addIncoming(llvm::Constant::getNullValue(BasePtrTy), origBB);
- Value = Value.withPointer(PHI);
+ Value = Value.withPointer(PHI, NotKnownNonNull);
}
return Value;
CGM.getDataLayout().getAllocaAddrSpace());
auto DestAS = getContext().getTargetAddressSpace(DestLangAS);
auto *T = DeclPtr.getElementType()->getPointerTo(DestAS);
- DeclPtr = DeclPtr.withPointer(getTargetHooks().performAddrSpaceCast(
- *this, V, SrcLangAS, DestLangAS, T, true));
+ DeclPtr =
+ DeclPtr.withPointer(getTargetHooks().performAddrSpaceCast(
+ *this, V, SrcLangAS, DestLangAS, T, true),
+ DeclPtr.isKnownNonNull());
}
// Push a destructor cleanup for this parameter if the ABI requires it.
llvm::Value *ChildVar =
Builder.CreateBitCast(RecoverCall, ParentVar.getType());
ChildVar->setName(ParentVar.getName());
- return ParentVar.withPointer(ChildVar);
+ return ParentVar.withPointer(ChildVar, KnownNonNull);
}
void CodeGenFunction::EmitCapturedLocals(CodeGenFunction &ParentCGF,
llvm::Value *ArraySize) {
auto Alloca = CreateTempAlloca(Ty, Name, ArraySize);
Alloca->setAlignment(Align.getAsAlign());
- return Address(Alloca, Ty, Align);
+ return Address(Alloca, Ty, Align, KnownNonNull);
}
/// CreateTempAlloca - This creates a alloca and inserts it into the entry
Ty->getPointerTo(DestAddrSpace), /*non-null*/ true);
}
- return Address(V, Ty, Align);
+ return Address(V, Ty, Align, KnownNonNull);
}
/// CreateTempAlloca - This creates an alloca and inserts it into the entry
Result = Address(
Builder.CreateBitCast(Result.getPointer(), VectorTy->getPointerTo()),
- VectorTy, Result.getAlignment());
+ VectorTy, Result.getAlignment(), KnownNonNull);
}
return Result;
}
// LValue Expression Emission
//===----------------------------------------------------------------------===//
-/// EmitPointerWithAlignment - Given an expression of pointer type, try to
-/// derive a more accurate bound on the alignment of the pointer.
-Address CodeGenFunction::EmitPointerWithAlignment(const Expr *E,
- LValueBaseInfo *BaseInfo,
- TBAAAccessInfo *TBAAInfo) {
+static Address EmitPointerWithAlignment(const Expr *E, LValueBaseInfo *BaseInfo,
+ TBAAAccessInfo *TBAAInfo,
+ KnownNonNull_t IsKnownNonNull,
+ CodeGenFunction &CGF) {
// We allow this with ObjC object pointers because of fragile ABIs.
assert(E->getType()->isPointerType() ||
E->getType()->isObjCObjectPointerType());
// Casts:
if (const CastExpr *CE = dyn_cast<CastExpr>(E)) {
if (const auto *ECE = dyn_cast<ExplicitCastExpr>(CE))
- CGM.EmitExplicitCastExprType(ECE, this);
+ CGF.CGM.EmitExplicitCastExprType(ECE, &CGF);
switch (CE->getCastKind()) {
// Non-converting casts (but not C's implicit conversion from void*).
LValueBaseInfo InnerBaseInfo;
TBAAAccessInfo InnerTBAAInfo;
- Address Addr = EmitPointerWithAlignment(CE->getSubExpr(),
- &InnerBaseInfo,
- &InnerTBAAInfo);
+ Address Addr = CGF.EmitPointerWithAlignment(
+ CE->getSubExpr(), &InnerBaseInfo, &InnerTBAAInfo, IsKnownNonNull);
if (BaseInfo) *BaseInfo = InnerBaseInfo;
if (TBAAInfo) *TBAAInfo = InnerTBAAInfo;
if (isa<ExplicitCastExpr>(CE)) {
LValueBaseInfo TargetTypeBaseInfo;
TBAAAccessInfo TargetTypeTBAAInfo;
- CharUnits Align = CGM.getNaturalPointeeTypeAlignment(
+ CharUnits Align = CGF.CGM.getNaturalPointeeTypeAlignment(
E->getType(), &TargetTypeBaseInfo, &TargetTypeTBAAInfo);
if (TBAAInfo)
- *TBAAInfo = CGM.mergeTBAAInfoForCast(*TBAAInfo,
- TargetTypeTBAAInfo);
+ *TBAAInfo =
+ CGF.CGM.mergeTBAAInfoForCast(*TBAAInfo, TargetTypeTBAAInfo);
// If the source l-value is opaque, honor the alignment of the
// casted-to type.
if (InnerBaseInfo.getAlignmentSource() != AlignmentSource::Decl) {
if (BaseInfo)
BaseInfo->mergeForCast(TargetTypeBaseInfo);
- Addr = Address(Addr.getPointer(), Addr.getElementType(), Align);
+ Addr = Address(Addr.getPointer(), Addr.getElementType(), Align,
+ IsKnownNonNull);
}
}
- if (SanOpts.has(SanitizerKind::CFIUnrelatedCast) &&
+ if (CGF.SanOpts.has(SanitizerKind::CFIUnrelatedCast) &&
CE->getCastKind() == CK_BitCast) {
if (auto PT = E->getType()->getAs<PointerType>())
- EmitVTablePtrCheckForCast(PT->getPointeeType(), Addr,
- /*MayBeNull=*/true,
- CodeGenFunction::CFITCK_UnrelatedCast,
- CE->getBeginLoc());
+ CGF.EmitVTablePtrCheckForCast(PT->getPointeeType(), Addr,
+ /*MayBeNull=*/true,
+ CodeGenFunction::CFITCK_UnrelatedCast,
+ CE->getBeginLoc());
}
- llvm::Type *ElemTy = ConvertTypeForMem(E->getType()->getPointeeType());
- Addr = Builder.CreateElementBitCast(Addr, ElemTy);
+ llvm::Type *ElemTy =
+ CGF.ConvertTypeForMem(E->getType()->getPointeeType());
+ Addr = CGF.Builder.CreateElementBitCast(Addr, ElemTy);
if (CE->getCastKind() == CK_AddressSpaceConversion)
- Addr = Builder.CreateAddrSpaceCast(Addr, ConvertType(E->getType()));
+ Addr = CGF.Builder.CreateAddrSpaceCast(Addr,
+ CGF.ConvertType(E->getType()));
return Addr;
}
break;
// Array-to-pointer decay.
case CK_ArrayToPointerDecay:
- return EmitArrayToPointerDecay(CE->getSubExpr(), BaseInfo, TBAAInfo);
+ return CGF.EmitArrayToPointerDecay(CE->getSubExpr(), BaseInfo, TBAAInfo);
// Derived-to-base conversions.
case CK_UncheckedDerivedToBase:
// conservatively pretend that the complete object is of the base class
// type.
if (TBAAInfo)
- *TBAAInfo = CGM.getTBAAAccessInfo(E->getType());
- Address Addr = EmitPointerWithAlignment(CE->getSubExpr(), BaseInfo);
+ *TBAAInfo = CGF.CGM.getTBAAAccessInfo(E->getType());
+ Address Addr = CGF.EmitPointerWithAlignment(
+ CE->getSubExpr(), BaseInfo, nullptr,
+ (KnownNonNull_t)(IsKnownNonNull ||
+ CE->getCastKind() == CK_UncheckedDerivedToBase));
auto Derived = CE->getSubExpr()->getType()->getPointeeCXXRecordDecl();
- return GetAddressOfBaseClass(Addr, Derived,
- CE->path_begin(), CE->path_end(),
- ShouldNullCheckClassCastValue(CE),
- CE->getExprLoc());
+ return CGF.GetAddressOfBaseClass(
+ Addr, Derived, CE->path_begin(), CE->path_end(),
+ CGF.ShouldNullCheckClassCastValue(CE), CE->getExprLoc());
}
// TODO: Is there any reason to treat base-to-derived conversions
// Unary &.
if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
if (UO->getOpcode() == UO_AddrOf) {
- LValue LV = EmitLValue(UO->getSubExpr());
+ LValue LV = CGF.EmitLValue(UO->getSubExpr(), IsKnownNonNull);
if (BaseInfo) *BaseInfo = LV.getBaseInfo();
if (TBAAInfo) *TBAAInfo = LV.getTBAAInfo();
- return LV.getAddress(*this);
+ return LV.getAddress(CGF);
}
}
case Builtin::BIaddressof:
case Builtin::BI__addressof:
case Builtin::BI__builtin_addressof: {
- LValue LV = EmitLValue(Call->getArg(0));
+ LValue LV = CGF.EmitLValue(Call->getArg(0), IsKnownNonNull);
if (BaseInfo) *BaseInfo = LV.getBaseInfo();
if (TBAAInfo) *TBAAInfo = LV.getTBAAInfo();
- return LV.getAddress(*this);
+ return LV.getAddress(CGF);
}
}
}
// Otherwise, use the alignment of the type.
CharUnits Align =
- CGM.getNaturalPointeeTypeAlignment(E->getType(), BaseInfo, TBAAInfo);
- llvm::Type *ElemTy = ConvertTypeForMem(E->getType()->getPointeeType());
- return Address(EmitScalarExpr(E), ElemTy, Align);
+ CGF.CGM.getNaturalPointeeTypeAlignment(E->getType(), BaseInfo, TBAAInfo);
+ llvm::Type *ElemTy = CGF.ConvertTypeForMem(E->getType()->getPointeeType());
+ return Address(CGF.EmitScalarExpr(E), ElemTy, Align, IsKnownNonNull);
+}
+
+/// EmitPointerWithAlignment - Given an expression of pointer type, try to
+/// derive a more accurate bound on the alignment of the pointer.
+Address CodeGenFunction::EmitPointerWithAlignment(
+ const Expr *E, LValueBaseInfo *BaseInfo, TBAAAccessInfo *TBAAInfo,
+ KnownNonNull_t IsKnownNonNull) {
+ Address Addr =
+ ::EmitPointerWithAlignment(E, BaseInfo, TBAAInfo, IsKnownNonNull, *this);
+ if (IsKnownNonNull && !Addr.isKnownNonNull())
+ Addr.setKnownNonNull();
+ return Addr;
}
llvm::Value *CodeGenFunction::EmitNonNullRValueCheck(RValue RV, QualType T) {
/// type of the same size of the lvalue's type. If the lvalue has a variable
/// length type, this is not possible.
///
-LValue CodeGenFunction::EmitLValue(const Expr *E) {
+LValue CodeGenFunction::EmitLValue(const Expr *E,
+ KnownNonNull_t IsKnownNonNull) {
+ LValue LV = EmitLValueHelper(E, IsKnownNonNull);
+ if (IsKnownNonNull && !LV.isKnownNonNull())
+ LV.setKnownNonNull();
+ return LV;
+}
+
+LValue CodeGenFunction::EmitLValueHelper(const Expr *E,
+ KnownNonNull_t IsKnownNonNull) {
ApplyDebugLocation DL(*this, E);
switch (E->getStmtClass()) {
default: return EmitUnsupportedLValue(E, "l-value expression");
case Expr::UserDefinedLiteralClass:
return EmitCallExprLValue(cast<CallExpr>(E));
case Expr::CXXRewrittenBinaryOperatorClass:
- return EmitLValue(cast<CXXRewrittenBinaryOperator>(E)->getSemanticForm());
+ return EmitLValue(cast<CXXRewrittenBinaryOperator>(E)->getSemanticForm(),
+ IsKnownNonNull);
case Expr::VAArgExprClass:
return EmitVAArgExprLValue(cast<VAArgExpr>(E));
case Expr::DeclRefExprClass:
->getPointeeType();
return MakeNaturalAlignAddrLValue(Result, RetType);
}
- return EmitLValue(cast<ConstantExpr>(E)->getSubExpr());
+ return EmitLValue(cast<ConstantExpr>(E)->getSubExpr(), IsKnownNonNull);
}
case Expr::ParenExprClass:
- return EmitLValue(cast<ParenExpr>(E)->getSubExpr());
+ return EmitLValue(cast<ParenExpr>(E)->getSubExpr(), IsKnownNonNull);
case Expr::GenericSelectionExprClass:
- return EmitLValue(cast<GenericSelectionExpr>(E)->getResultExpr());
+ return EmitLValue(cast<GenericSelectionExpr>(E)->getResultExpr(),
+ IsKnownNonNull);
case Expr::PredefinedExprClass:
return EmitPredefinedLValue(cast<PredefinedExpr>(E));
case Expr::StringLiteralClass:
case Expr::ExprWithCleanupsClass: {
const auto *cleanups = cast<ExprWithCleanups>(E);
RunCleanupsScope Scope(*this);
- LValue LV = EmitLValue(cleanups->getSubExpr());
+ LValue LV = EmitLValue(cleanups->getSubExpr(), IsKnownNonNull);
if (LV.isSimple()) {
// Defend against branches out of gnu statement expressions surrounded by
// cleanups.
Address Addr = LV.getAddress(*this);
llvm::Value *V = Addr.getPointer();
Scope.ForceCleanup({&V});
- return LValue::MakeAddr(Addr.withPointer(V), LV.getType(), getContext(),
- LV.getBaseInfo(), LV.getTBAAInfo());
+ return LValue::MakeAddr(Addr.withPointer(V, Addr.isKnownNonNull()),
+ LV.getType(), getContext(), LV.getBaseInfo(),
+ LV.getTBAAInfo());
}
// FIXME: Is it possible to create an ExprWithCleanups that produces a
// bitfield lvalue or some other non-simple lvalue?
case Expr::CXXDefaultArgExprClass: {
auto *DAE = cast<CXXDefaultArgExpr>(E);
CXXDefaultArgExprScope Scope(*this, DAE);
- return EmitLValue(DAE->getExpr());
+ return EmitLValue(DAE->getExpr(), IsKnownNonNull);
}
case Expr::CXXDefaultInitExprClass: {
auto *DIE = cast<CXXDefaultInitExpr>(E);
CXXDefaultInitExprScope Scope(*this, DIE);
- return EmitLValue(DIE->getExpr());
+ return EmitLValue(DIE->getExpr(), IsKnownNonNull);
}
case Expr::CXXTypeidExprClass:
return EmitCXXTypeidLValue(cast<CXXTypeidExpr>(E));
case Expr::BinaryConditionalOperatorClass:
return EmitConditionalOperatorLValue(cast<BinaryConditionalOperator>(E));
case Expr::ChooseExprClass:
- return EmitLValue(cast<ChooseExpr>(E)->getChosenSubExpr());
+ return EmitLValue(cast<ChooseExpr>(E)->getChosenSubExpr(), IsKnownNonNull);
case Expr::OpaqueValueExprClass:
return EmitOpaqueValueLValue(cast<OpaqueValueExpr>(E));
case Expr::SubstNonTypeTemplateParmExprClass:
- return EmitLValue(cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement());
+ return EmitLValue(cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement(),
+ IsKnownNonNull);
case Expr::ImplicitCastExprClass:
case Expr::CStyleCastExprClass:
case Expr::CXXFunctionalCastExprClass:
bool isNontemporal) {
if (auto *GV = dyn_cast<llvm::GlobalValue>(Addr.getPointer()))
if (GV->isThreadLocal())
- Addr = Addr.withPointer(Builder.CreateThreadLocalAddress(GV));
+ Addr = Addr.withPointer(Builder.CreateThreadLocalAddress(GV),
+ NotKnownNonNull);
if (const auto *ClangVecTy = Ty->getAs<VectorType>()) {
// Boolean vectors use `iN` as storage type.
bool isInit, bool isNontemporal) {
if (auto *GV = dyn_cast<llvm::GlobalValue>(Addr.getPointer()))
if (GV->isThreadLocal())
- Addr = Addr.withPointer(Builder.CreateThreadLocalAddress(GV));
+ Addr = Addr.withPointer(Builder.CreateThreadLocalAddress(GV),
+ NotKnownNonNull);
llvm::Type *SrcTy = Value->getType();
if (const auto *ClangVecTy = Ty->getAs<VectorType>()) {
// Handle threadlocal function locals.
if (VD->getTLSKind() != VarDecl::TLS_None)
- addr =
- addr.withPointer(Builder.CreateThreadLocalAddress(addr.getPointer()));
+ addr = addr.withPointer(
+ Builder.CreateThreadLocalAddress(addr.getPointer()), NotKnownNonNull);
// Check for OpenMP threadprivate variables.
if (getLangOpts().OpenMP && !getLangOpts().OpenMPSimd &&
functionType = ptrType->getPointeeType();
} else {
functionType = E->getType();
- calleePtr = EmitLValue(E).getPointer(*this);
+ calleePtr = EmitLValue(E, KnownNonNull).getPointer(*this);
}
assert(functionType->isFunctionType());
// Emit the 'this' pointer.
Address This = Address::invalid();
if (BO->getOpcode() == BO_PtrMemI)
- This = EmitPointerWithAlignment(BaseExpr);
+ This = EmitPointerWithAlignment(BaseExpr, nullptr, nullptr, KnownNonNull);
else
- This = EmitLValue(BaseExpr).getAddress(*this);
+ This = EmitLValue(BaseExpr, KnownNonNull).getAddress(*this);
EmitTypeCheck(TCK_MemberCall, E->getExprLoc(), This.getPointer(),
QualType(MPT->getClass(), 0));
Builder.CreateCondBr(IsNull, DeleteEnd, DeleteNotNull);
EmitBlock(DeleteNotNull);
+ Ptr.setKnownNonNull();
QualType DeleteTy = E->getDestroyedType();
Ptr = Address(Builder.CreateInBoundsGEP(Ptr.getElementType(),
Ptr.getPointer(), GEP, "del.first"),
- ConvertTypeForMem(DeleteTy), Ptr.getAlignment());
+ ConvertTypeForMem(DeleteTy), Ptr.getAlignment(),
+ Ptr.isKnownNonNull());
}
assert(ConvertTypeForMem(DeleteTy) == Ptr.getElementType());
CodeGenFunction *CGF) {
return std::array<Address, N>{
{Address(CGF->Builder.CreateLoad(CGF->GetAddrOfLocalVar(Args[Ints])),
- CGF->VoidPtrTy, Alignments[Ints])...}};
+ CGF->VoidPtrTy, Alignments[Ints], KnownNonNull)...}};
}
// Template classes that are used as bases for classes that emit special
Addr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
Addr, OriginalBaseAddress.getType());
- return OriginalBaseAddress.withPointer(Addr);
+ return OriginalBaseAddress.withPointer(Addr, NotKnownNonNull);
}
static const VarDecl *getBaseDecl(const Expr *Ref, const DeclRefExpr *&DE) {
llvm::PHINode *ElementPHI =
CGF.Builder.CreatePHI(Begin.getType(), 2, "omp.elementPast");
ElementPHI->addIncoming(Begin.getPointer(), EntryBB);
- Begin = Begin.withPointer(ElementPHI);
+ Begin = Begin.withPointer(ElementPHI, KnownNonNull);
Base = CGF.MakeAddrLValue(Begin, KmpDependInfoTy, Base.getBaseInfo(),
Base.getTBAAInfo());
// deps[i].flags = NewDepKind;
// this lvalue.
bool Nontemporal : 1;
+ // The pointer is known not to be null.
+ bool IsKnownNonNull : 1;
+
LValueBaseInfo BaseInfo;
TBAAAccessInfo TBAAInfo;
LValueBaseInfo getBaseInfo() const { return BaseInfo; }
void setBaseInfo(LValueBaseInfo Info) { BaseInfo = Info; }
+ KnownNonNull_t isKnownNonNull() const {
+ return (KnownNonNull_t)IsKnownNonNull;
+ }
+ LValue setKnownNonNull() {
+ IsKnownNonNull = true;
+ return *this;
+ }
+
// simple lvalue
llvm::Value *getPointer(CodeGenFunction &CGF) const {
assert(isSimple());
return V;
}
Address getAddress(CodeGenFunction &CGF) const {
- return Address(getPointer(CGF), ElementType, getAlignment());
+ return Address(getPointer(CGF), ElementType, getAlignment(),
+ isKnownNonNull());
}
void setAddress(Address address) {
assert(isSimple());
V = address.getPointer();
ElementType = address.getElementType();
Alignment = address.getAlignment().getQuantity();
+ IsKnownNonNull = address.isKnownNonNull();
}
// vector elt lvalue
Address getVectorAddress() const {
- return Address(getVectorPointer(), ElementType, getAlignment());
+ return Address(getVectorPointer(), ElementType, getAlignment(),
+ (KnownNonNull_t)isKnownNonNull());
}
llvm::Value *getVectorPointer() const {
assert(isVectorElt());
}
Address getMatrixAddress() const {
- return Address(getMatrixPointer(), ElementType, getAlignment());
+ return Address(getMatrixPointer(), ElementType, getAlignment(),
+ (KnownNonNull_t)isKnownNonNull());
}
llvm::Value *getMatrixPointer() const {
assert(isMatrixElt());
// extended vector elements.
Address getExtVectorAddress() const {
- return Address(getExtVectorPointer(), ElementType, getAlignment());
+ return Address(getExtVectorPointer(), ElementType, getAlignment(),
+ (KnownNonNull_t)isKnownNonNull());
}
llvm::Value *getExtVectorPointer() const {
assert(isExtVectorElt());
// bitfield lvalue
Address getBitFieldAddress() const {
- return Address(getBitFieldPointer(), ElementType, getAlignment());
+ return Address(getBitFieldPointer(), ElementType, getAlignment(),
+ (KnownNonNull_t)isKnownNonNull());
}
llvm::Value *getBitFieldPointer() const { assert(isBitField()); return V; }
const CGBitFieldInfo &getBitFieldInfo() const {
assert(address.getPointer()->getType()->isPointerTy());
R.V = address.getPointer();
R.ElementType = address.getElementType();
+ R.IsKnownNonNull = address.isKnownNonNull();
R.Initialize(type, qs, address.getAlignment(), BaseInfo, TBAAInfo);
return R;
}
R.V = vecAddress.getPointer();
R.ElementType = vecAddress.getElementType();
R.VectorIdx = Idx;
+ R.IsKnownNonNull = vecAddress.isKnownNonNull();
R.Initialize(type, type.getQualifiers(), vecAddress.getAlignment(),
BaseInfo, TBAAInfo);
return R;
R.V = vecAddress.getPointer();
R.ElementType = vecAddress.getElementType();
R.VectorElts = Elts;
+ R.IsKnownNonNull = vecAddress.isKnownNonNull();
R.Initialize(type, type.getQualifiers(), vecAddress.getAlignment(),
BaseInfo, TBAAInfo);
return R;
R.V = Addr.getPointer();
R.ElementType = Addr.getElementType();
R.BitFieldInfo = &Info;
+ R.IsKnownNonNull = Addr.isKnownNonNull();
R.Initialize(type, type.getQualifiers(), Addr.getAlignment(), BaseInfo,
TBAAInfo);
return R;
R.LVType = GlobalReg;
R.V = V;
R.ElementType = nullptr;
+ R.IsKnownNonNull = true;
R.Initialize(type, type.getQualifiers(), alignment,
LValueBaseInfo(AlignmentSource::Decl), TBAAAccessInfo());
return R;
R.V = matAddress.getPointer();
R.ElementType = matAddress.getElementType();
R.VectorIdx = Idx;
+ R.IsKnownNonNull = matAddress.isKnownNonNull();
R.Initialize(type, type.getQualifiers(), matAddress.getAlignment(),
BaseInfo, TBAAInfo);
return R;
Overlap_t mayOverlap,
IsZeroed_t isZeroed = IsNotZeroed,
IsSanitizerChecked_t isChecked = IsNotSanitizerChecked) {
+ if (addr.isValid())
+ addr.setKnownNonNull();
return AggValueSlot(addr, quals, isDestructed, needsGC, isZeroed, isAliased,
mayOverlap, isChecked);
}
auto AI = CurFn->arg_begin();
if (CurFnInfo->getReturnInfo().isSRetAfterThis())
++AI;
- ReturnValue = Address(&*AI, ConvertType(RetTy),
- CurFnInfo->getReturnInfo().getIndirectAlign());
+ ReturnValue =
+ Address(&*AI, ConvertType(RetTy),
+ CurFnInfo->getReturnInfo().getIndirectAlign(), KnownNonNull);
if (!CurFnInfo->getReturnInfo().getIndirectByVal()) {
ReturnValuePointer =
CreateDefaultAlignTempAlloca(Int8PtrTy, "result.ptr");
cast<llvm::GetElementPtrInst>(Addr)->getResultElementType();
ReturnValuePointer = Address(Addr, Ty, getPointerAlign());
Addr = Builder.CreateAlignedLoad(Ty, Addr, getPointerAlign(), "agg.result");
- ReturnValue =
- Address(Addr, ConvertType(RetTy), CGM.getNaturalTypeAlignment(RetTy));
+ ReturnValue = Address(Addr, ConvertType(RetTy),
+ CGM.getNaturalTypeAlignment(RetTy), KnownNonNull);
} else {
ReturnValue = CreateIRTemp(RetTy, "retval");
Address getIndirectAddress() const {
assert(isIndirect());
- return Address(Value, ElementType, CharUnits::fromQuantity(Alignment));
+ return Address(Value, ElementType, CharUnits::fromQuantity(Alignment),
+ KnownNonNull);
}
};
/// an LLVM type of the same size of the lvalue's type. If the lvalue has a
/// variable length type, this is not possible.
///
- LValue EmitLValue(const Expr *E);
+ LValue EmitLValue(const Expr *E,
+ KnownNonNull_t IsKnownNonNull = NotKnownNonNull);
+private:
+ LValue EmitLValueHelper(const Expr *E, KnownNonNull_t IsKnownNonNull);
+
+public:
/// Same as EmitLValue but additionally we generate checking code to
/// guard against undefined behavior. This is only suitable when we know
/// that the address will be used to access the object.
/// into the address of a local variable. In such a case, it's quite
/// reasonable to just ignore the returned alignment when it isn't from an
/// explicit source.
- Address EmitPointerWithAlignment(const Expr *Addr,
- LValueBaseInfo *BaseInfo = nullptr,
- TBAAAccessInfo *TBAAInfo = nullptr);
+ Address
+ EmitPointerWithAlignment(const Expr *Addr, LValueBaseInfo *BaseInfo = nullptr,
+ TBAAAccessInfo *TBAAInfo = nullptr,
+ KnownNonNull_t IsKnownNonNull = NotKnownNonNull);
/// If \p E references a parameter with pass_object_size info or a constant
/// array size modifier, emit the object size divided by the size of \p EltTy.