aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGExpr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CGExpr.cpp')
-rw-r--r--lib/CodeGen/CGExpr.cpp386
1 files changed, 257 insertions, 129 deletions
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index 34a921e2dc00..5a4b1188b711 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -1,9 +1,8 @@
//===--- CGExpr.cpp - Emit LLVM Code from Expressions ---------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -26,6 +25,7 @@
#include "clang/AST/Attr.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/NSAPI.h"
+#include "clang/Basic/Builtins.h"
#include "clang/Basic/CodeGenOptions.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/StringExtras.h"
@@ -331,7 +331,7 @@ pushTemporaryCleanup(CodeGenFunction &CGF, const MaterializeTemporaryExpr *M,
switch (M->getStorageDuration()) {
case SD_Static:
case SD_Thread: {
- llvm::Constant *CleanupFn;
+ llvm::FunctionCallee CleanupFn;
llvm::Constant *CleanupArg;
if (E->getType()->isArrayType()) {
CleanupFn = CodeGenFunction(CGF.CGM).generateDestroyHelper(
@@ -340,8 +340,8 @@ pushTemporaryCleanup(CodeGenFunction &CGF, const MaterializeTemporaryExpr *M,
dyn_cast_or_null<VarDecl>(M->getExtendingDecl()));
CleanupArg = llvm::Constant::getNullValue(CGF.Int8PtrTy);
} else {
- CleanupFn = CGF.CGM.getAddrOfCXXStructor(ReferenceTemporaryDtor,
- StructorType::Complete);
+ CleanupFn = CGF.CGM.getAddrAndTypeOfCXXStructor(
+ GlobalDecl(ReferenceTemporaryDtor, Dtor_Complete));
CleanupArg = cast<llvm::Constant>(ReferenceTemporary.getPointer());
}
CGF.CGM.getCXXABI().registerGlobalDtor(
@@ -653,7 +653,8 @@ bool CodeGenFunction::sanitizePerformTypeCheck() const {
void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
llvm::Value *Ptr, QualType Ty,
CharUnits Alignment,
- SanitizerSet SkippedChecks) {
+ SanitizerSet SkippedChecks,
+ llvm::Value *ArraySize) {
if (!sanitizePerformTypeCheck())
return;
@@ -711,21 +712,28 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
if (SanOpts.has(SanitizerKind::ObjectSize) &&
!SkippedChecks.has(SanitizerKind::ObjectSize) &&
!Ty->isIncompleteType()) {
- uint64_t Size = getContext().getTypeSizeInChars(Ty).getQuantity();
-
- // The glvalue must refer to a large enough storage region.
- // FIXME: If Address Sanitizer is enabled, insert dynamic instrumentation
- // to check this.
- // FIXME: Get object address space
- llvm::Type *Tys[2] = { IntPtrTy, Int8PtrTy };
- llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::objectsize, Tys);
- llvm::Value *Min = Builder.getFalse();
- llvm::Value *NullIsUnknown = Builder.getFalse();
- llvm::Value *CastAddr = Builder.CreateBitCast(Ptr, Int8PtrTy);
- llvm::Value *LargeEnough = Builder.CreateICmpUGE(
- Builder.CreateCall(F, {CastAddr, Min, NullIsUnknown}),
- llvm::ConstantInt::get(IntPtrTy, Size));
- Checks.push_back(std::make_pair(LargeEnough, SanitizerKind::ObjectSize));
+ uint64_t TySize = getContext().getTypeSizeInChars(Ty).getQuantity();
+ llvm::Value *Size = llvm::ConstantInt::get(IntPtrTy, TySize);
+ if (ArraySize)
+ Size = Builder.CreateMul(Size, ArraySize);
+
+ // Degenerate case: new X[0] does not need an objectsize check.
+ llvm::Constant *ConstantSize = dyn_cast<llvm::Constant>(Size);
+ if (!ConstantSize || !ConstantSize->isNullValue()) {
+ // The glvalue must refer to a large enough storage region.
+ // FIXME: If Address Sanitizer is enabled, insert dynamic instrumentation
+ // to check this.
+ // FIXME: Get object address space
+ llvm::Type *Tys[2] = { IntPtrTy, Int8PtrTy };
+ llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::objectsize, Tys);
+ llvm::Value *Min = Builder.getFalse();
+ llvm::Value *NullIsUnknown = Builder.getFalse();
+ llvm::Value *Dynamic = Builder.getFalse();
+ llvm::Value *CastAddr = Builder.CreateBitCast(Ptr, Int8PtrTy);
+ llvm::Value *LargeEnough = Builder.CreateICmpUGE(
+ Builder.CreateCall(F, {CastAddr, Min, NullIsUnknown, Dynamic}), Size);
+ Checks.push_back(std::make_pair(LargeEnough, SanitizerKind::ObjectSize));
+ }
}
uint64_t AlignVal = 0;
@@ -1288,7 +1296,7 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {
case Expr::CXXUuidofExprClass:
return EmitCXXUuidofLValue(cast<CXXUuidofExpr>(E));
case Expr::LambdaExprClass:
- return EmitLambdaLValue(cast<LambdaExpr>(E));
+ return EmitAggExprToLValue(E);
case Expr::ExprWithCleanupsClass: {
const auto *cleanups = cast<ExprWithCleanups>(E);
@@ -1308,11 +1316,15 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {
return LV;
}
- case Expr::CXXDefaultArgExprClass:
- return EmitLValue(cast<CXXDefaultArgExpr>(E)->getExpr());
+ case Expr::CXXDefaultArgExprClass: {
+ auto *DAE = cast<CXXDefaultArgExpr>(E);
+ CXXDefaultArgExprScope Scope(*this, DAE);
+ return EmitLValue(DAE->getExpr());
+ }
case Expr::CXXDefaultInitExprClass: {
- CXXDefaultInitExprScope Scope(*this);
- return EmitLValue(cast<CXXDefaultInitExpr>(E)->getExpr());
+ auto *DIE = cast<CXXDefaultInitExpr>(E);
+ CXXDefaultInitExprScope Scope(*this, DIE);
+ return EmitLValue(DIE->getExpr());
}
case Expr::CXXTypeidExprClass:
return EmitCXXTypeidLValue(cast<CXXTypeidExpr>(E));
@@ -1387,7 +1399,7 @@ static bool isConstantEmittableObjectType(QualType type) {
/// Can we constant-emit a load of a reference to a variable of the
/// given type? This is different from predicates like
-/// Decl::isUsableInConstantExpressions because we do want it to apply
+/// Decl::mightBeUsableInConstantExpressions because we do want it to apply
/// in situations that don't necessarily satisfy the language's rules
/// for this (e.g. C++'s ODR-use rules). For example, we want to able
/// to do this with const float variables even if those variables
@@ -1411,10 +1423,11 @@ static ConstantEmissionKind checkVarTypeForConstantEmission(QualType type) {
}
/// Try to emit a reference to the given value without producing it as
-/// an l-value. This is actually more than an optimization: we can't
-/// produce an l-value for variables that we never actually captured
-/// in a block or lambda, which means const int variables or constexpr
-/// literals or similar.
+/// an l-value. This is just an optimization, but it avoids us needing
+/// to emit global copies of variables if they're named without triggering
+/// a formal use in a context where we can't emit a direct reference to them,
+/// for instance if a block or lambda or a member of a local class uses a
+/// const int variable or constexpr variable from an enclosing function.
CodeGenFunction::ConstantEmission
CodeGenFunction::tryEmitAsConstant(DeclRefExpr *refExpr) {
ValueDecl *value = refExpr->getDecl();
@@ -1485,7 +1498,7 @@ static DeclRefExpr *tryToConvertMemberExprToDeclRefExpr(CodeGenFunction &CGF,
return DeclRefExpr::Create(
CGF.getContext(), NestedNameSpecifierLoc(), SourceLocation(), VD,
/*RefersToEnclosingVariableOrCapture=*/false, ME->getExprLoc(),
- ME->getType(), ME->getValueKind());
+ ME->getType(), ME->getValueKind(), nullptr, nullptr, ME->isNonOdrUse());
}
return nullptr;
}
@@ -1879,7 +1892,6 @@ Address CodeGenFunction::EmitExtVectorElementLValue(LValue LV) {
Address VectorBasePtrPlusIx =
Builder.CreateConstInBoundsGEP(CastToPointerElement, ix,
- getContext().getTypeSizeInChars(EQT),
"vector.elt");
return VectorBasePtrPlusIx;
@@ -1899,7 +1911,7 @@ RValue CodeGenFunction::EmitLoadOfGlobalRegLValue(LValue LV) {
Ty = CGM.getTypes().getDataLayout().getIntPtrType(OrigTy);
llvm::Type *Types[] = { Ty };
- llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::read_register, Types);
+ llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::read_register, Types);
llvm::Value *Call = Builder.CreateCall(
F, llvm::MetadataAsValue::get(Ty->getContext(), RegName));
if (OrigTy->isPointerTy())
@@ -2019,7 +2031,7 @@ void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,
// Cast the source to the storage type and shift it into place.
SrcVal = Builder.CreateIntCast(SrcVal, Ptr.getElementType(),
- /*IsSigned=*/false);
+ /*isSigned=*/false);
llvm::Value *MaskedVal = SrcVal;
// See if there are other bits in the bitfield's storage we'll need to load
@@ -2160,7 +2172,7 @@ void CodeGenFunction::EmitStoreThroughGlobalRegLValue(RValue Src, LValue Dst) {
Ty = CGM.getTypes().getDataLayout().getIntPtrType(OrigTy);
llvm::Type *Types[] = { Ty };
- llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::write_register, Types);
+ llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::write_register, Types);
llvm::Value *Value = Src.getScalarVal();
if (OrigTy->isPointerTy())
Value = Builder.CreatePtrToInt(Value, Ty);
@@ -2284,15 +2296,22 @@ static LValue EmitThreadPrivateVarDeclLValue(
return CGF.MakeAddrLValue(Addr, T, AlignmentSource::Decl);
}
-static Address emitDeclTargetLinkVarDeclLValue(CodeGenFunction &CGF,
- const VarDecl *VD, QualType T) {
+static Address emitDeclTargetVarDeclLValue(CodeGenFunction &CGF,
+ const VarDecl *VD, QualType T) {
llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
- if (!Res || *Res == OMPDeclareTargetDeclAttr::MT_To)
+ // Return an invalid address if variable is MT_To and unified
+ // memory is not enabled. For all other cases: MT_Link and
+ // MT_To with unified memory, return a valid address.
+ if (!Res || (*Res == OMPDeclareTargetDeclAttr::MT_To &&
+ !CGF.CGM.getOpenMPRuntime().hasRequiresUnifiedSharedMemory()))
return Address::invalid();
- assert(*Res == OMPDeclareTargetDeclAttr::MT_Link && "Expected link clause");
+ assert(((*Res == OMPDeclareTargetDeclAttr::MT_Link) ||
+ (*Res == OMPDeclareTargetDeclAttr::MT_To &&
+ CGF.CGM.getOpenMPRuntime().hasRequiresUnifiedSharedMemory())) &&
+ "Expected link clause OR to clause with unified memory enabled.");
QualType PtrTy = CGF.getContext().getPointerType(VD->getType());
- Address Addr = CGF.CGM.getOpenMPRuntime().getAddrOfDeclareTargetLink(VD);
+ Address Addr = CGF.CGM.getOpenMPRuntime().getAddrOfDeclareTargetVar(VD);
return CGF.EmitLoadOfPointer(Addr, PtrTy->castAs<PointerType>());
}
@@ -2348,7 +2367,7 @@ static LValue EmitGlobalVarDeclLValue(CodeGenFunction &CGF,
// Check if the variable is marked as declare target with link clause in
// device codegen.
if (CGF.getLangOpts().OpenMPIsDevice) {
- Address Addr = emitDeclTargetLinkVarDeclLValue(CGF, VD, T);
+ Address Addr = emitDeclTargetVarDeclLValue(CGF, VD, T);
if (Addr.isValid())
return CGF.MakeAddrLValue(Addr, T, AlignmentSource::Decl);
}
@@ -2440,45 +2459,101 @@ static LValue EmitGlobalNamedRegister(const VarDecl *VD, CodeGenModule &CGM) {
return LValue::MakeGlobalReg(Address(Ptr, Alignment), VD->getType());
}
+/// Determine whether we can emit a reference to \p VD from the current
+/// context, despite not necessarily having seen an odr-use of the variable in
+/// this context.
+static bool canEmitSpuriousReferenceToVariable(CodeGenFunction &CGF,
+ const DeclRefExpr *E,
+ const VarDecl *VD,
+ bool IsConstant) {
+ // For a variable declared in an enclosing scope, do not emit a spurious
+ // reference even if we have a capture, as that will emit an unwarranted
+ // reference to our capture state, and will likely generate worse code than
+ // emitting a local copy.
+ if (E->refersToEnclosingVariableOrCapture())
+ return false;
+
+ // For a local declaration declared in this function, we can always reference
+ // it even if we don't have an odr-use.
+ if (VD->hasLocalStorage()) {
+ return VD->getDeclContext() ==
+ dyn_cast_or_null<DeclContext>(CGF.CurCodeDecl);
+ }
+
+ // For a global declaration, we can emit a reference to it if we know
+ // for sure that we are able to emit a definition of it.
+ VD = VD->getDefinition(CGF.getContext());
+ if (!VD)
+ return false;
+
+ // Don't emit a spurious reference if it might be to a variable that only
+ // exists on a different device / target.
+ // FIXME: This is unnecessarily broad. Check whether this would actually be a
+ // cross-target reference.
+ if (CGF.getLangOpts().OpenMP || CGF.getLangOpts().CUDA ||
+ CGF.getLangOpts().OpenCL) {
+ return false;
+ }
+
+ // We can emit a spurious reference only if the linkage implies that we'll
+ // be emitting a non-interposable symbol that will be retained until link
+ // time.
+ switch (CGF.CGM.getLLVMLinkageVarDefinition(VD, IsConstant)) {
+ case llvm::GlobalValue::ExternalLinkage:
+ case llvm::GlobalValue::LinkOnceODRLinkage:
+ case llvm::GlobalValue::WeakODRLinkage:
+ case llvm::GlobalValue::InternalLinkage:
+ case llvm::GlobalValue::PrivateLinkage:
+ return true;
+ default:
+ return false;
+ }
+}
+
LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
const NamedDecl *ND = E->getDecl();
QualType T = E->getType();
+ assert(E->isNonOdrUse() != NOUR_Unevaluated &&
+ "should not emit an unevaluated operand");
+
if (const auto *VD = dyn_cast<VarDecl>(ND)) {
// Global Named registers access via intrinsics only
if (VD->getStorageClass() == SC_Register &&
VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())
return EmitGlobalNamedRegister(VD, CGM);
- // A DeclRefExpr for a reference initialized by a constant expression can
- // appear without being odr-used. Directly emit the constant initializer.
- const Expr *Init = VD->getAnyInitializer(VD);
- const auto *BD = dyn_cast_or_null<BlockDecl>(CurCodeDecl);
- if (Init && !isa<ParmVarDecl>(VD) && VD->getType()->isReferenceType() &&
- VD->isUsableInConstantExpressions(getContext()) &&
- VD->checkInitIsICE() &&
- // Do not emit if it is private OpenMP variable.
- !(E->refersToEnclosingVariableOrCapture() &&
- ((CapturedStmtInfo &&
- (LocalDeclMap.count(VD->getCanonicalDecl()) ||
- CapturedStmtInfo->lookup(VD->getCanonicalDecl()))) ||
- LambdaCaptureFields.lookup(VD->getCanonicalDecl()) ||
- (BD && BD->capturesVariable(VD))))) {
- llvm::Constant *Val =
- ConstantEmitter(*this).emitAbstract(E->getLocation(),
- *VD->evaluateValue(),
- VD->getType());
- assert(Val && "failed to emit reference constant expression");
- // FIXME: Eventually we will want to emit vector element references.
-
- // Should we be using the alignment of the constant pointer we emitted?
- CharUnits Alignment = getNaturalTypeAlignment(E->getType(),
- /* BaseInfo= */ nullptr,
- /* TBAAInfo= */ nullptr,
- /* forPointeeType= */ true);
- return MakeAddrLValue(Address(Val, Alignment), T, AlignmentSource::Decl);
+ // If this DeclRefExpr does not constitute an odr-use of the variable,
+ // we're not permitted to emit a reference to it in general, and it might
+ // not be captured if capture would be necessary for a use. Emit the
+ // constant value directly instead.
+ if (E->isNonOdrUse() == NOUR_Constant &&
+ (VD->getType()->isReferenceType() ||
+ !canEmitSpuriousReferenceToVariable(*this, E, VD, true))) {
+ VD->getAnyInitializer(VD);
+ llvm::Constant *Val = ConstantEmitter(*this).emitAbstract(
+ E->getLocation(), *VD->evaluateValue(), VD->getType());
+ assert(Val && "failed to emit constant expression");
+
+ Address Addr = Address::invalid();
+ if (!VD->getType()->isReferenceType()) {
+ // Spill the constant value to a global.
+ Addr = CGM.createUnnamedGlobalFrom(*VD, Val,
+ getContext().getDeclAlign(VD));
+ } else {
+ // Should we be using the alignment of the constant pointer we emitted?
+ CharUnits Alignment =
+ getNaturalTypeAlignment(E->getType(),
+ /* BaseInfo= */ nullptr,
+ /* TBAAInfo= */ nullptr,
+ /* forPointeeType= */ true);
+ Addr = Address(Val, Alignment);
+ }
+ return MakeAddrLValue(Addr, T, AlignmentSource::Decl);
}
+ // FIXME: Handle other kinds of non-odr-use DeclRefExprs.
+
// Check for captured variables.
if (E->refersToEnclosingVariableOrCapture()) {
VD = VD->getCanonicalDecl();
@@ -2510,7 +2585,7 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
// FIXME: We should be able to assert this for FunctionDecls as well!
// FIXME: We should be able to assert this for all DeclRefExprs, not just
// those with a valid source location.
- assert((ND->isUsed(false) || !isa<VarDecl>(ND) ||
+ assert((ND->isUsed(false) || !isa<VarDecl>(ND) || E->isNonOdrUse() ||
!E->getLocation().isValid()) &&
"Should not use decl without marking it used!");
@@ -2536,7 +2611,7 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
// some reason; most likely, because it's in an outer function.
} else if (VD->isStaticLocal()) {
addr = Address(CGM.getOrCreateStaticVarDecl(
- *VD, CGM.getLLVMLinkageVarDefinition(VD, /*isConstant=*/false)),
+ *VD, CGM.getLLVMLinkageVarDefinition(VD, /*IsConstant=*/false)),
getContext().getDeclAlign(VD));
// No other cases for now.
@@ -2851,16 +2926,13 @@ enum class CheckRecoverableKind {
}
static CheckRecoverableKind getRecoverableKind(SanitizerMask Kind) {
- assert(llvm::countPopulation(Kind) == 1);
- switch (Kind) {
- case SanitizerKind::Vptr:
+ assert(Kind.countPopulation() == 1);
+ if (Kind == SanitizerKind::Function || Kind == SanitizerKind::Vptr)
return CheckRecoverableKind::AlwaysRecoverable;
- case SanitizerKind::Return:
- case SanitizerKind::Unreachable:
+ else if (Kind == SanitizerKind::Return || Kind == SanitizerKind::Unreachable)
return CheckRecoverableKind::Unrecoverable;
- default:
+ else
return CheckRecoverableKind::Recoverable;
- }
}
namespace {
@@ -2910,7 +2982,7 @@ static void emitCheckHandlerCall(CodeGenFunction &CGF,
}
B.addAttribute(llvm::Attribute::UWTable);
- llvm::Value *Fn = CGF.CGM.CreateRuntimeFunction(
+ llvm::FunctionCallee Fn = CGF.CGM.CreateRuntimeFunction(
FnType, FnName,
llvm::AttributeList::get(CGF.getLLVMContext(),
llvm::AttributeList::FunctionIndex, B),
@@ -3051,7 +3123,7 @@ void CodeGenFunction::EmitCfiSlowPathCheck(
bool WithDiag = !CGM.getCodeGenOpts().SanitizeTrap.has(Kind);
llvm::CallInst *CheckCall;
- llvm::Constant *SlowPathFn;
+ llvm::FunctionCallee SlowPathFn;
if (WithDiag) {
llvm::Constant *Info = llvm::ConstantStruct::getAnon(StaticArgs);
auto *InfoPtr =
@@ -3073,7 +3145,8 @@ void CodeGenFunction::EmitCfiSlowPathCheck(
CheckCall = Builder.CreateCall(SlowPathFn, {TypeId, Ptr});
}
- CGM.setDSOLocal(cast<llvm::GlobalValue>(SlowPathFn->stripPointerCasts()));
+ CGM.setDSOLocal(
+ cast<llvm::GlobalValue>(SlowPathFn.getCallee()->stripPointerCasts()));
CheckCall->setDoesNotThrow();
EmitBlock(Cont);
@@ -3252,7 +3325,7 @@ Address CodeGenFunction::EmitArrayToPointerDecay(const Expr *E,
if (!E->getType()->isVariableArrayType()) {
assert(isa<llvm::ArrayType>(Addr.getElementType()) &&
"Expected pointer to array");
- Addr = Builder.CreateStructGEP(Addr, 0, CharUnits::Zero(), "arraydecay");
+ Addr = Builder.CreateConstArrayGEP(Addr, 0, "arraydecay");
}
// The result of this decay conversion points to an array element within the
@@ -3346,8 +3419,20 @@ static Address emitArraySubscriptGEP(CodeGenFunction &CGF, Address addr,
CharUnits eltAlign =
getArrayElementAlign(addr.getAlignment(), indices.back(), eltSize);
- llvm::Value *eltPtr = emitArraySubscriptGEP(
- CGF, addr.getPointer(), indices, inbounds, signedIndices, loc, name);
+ llvm::Value *eltPtr;
+ auto LastIndex = dyn_cast<llvm::ConstantInt>(indices.back());
+ if (!CGF.IsInPreservedAIRegion || !LastIndex) {
+ eltPtr = emitArraySubscriptGEP(
+ CGF, addr.getPointer(), indices, inbounds, signedIndices,
+ loc, name);
+ } else {
+ // Remember the original array subscript for bpf target
+ unsigned idx = LastIndex->getZExtValue();
+ eltPtr = CGF.Builder.CreatePreserveArrayAccessIndex(addr.getPointer(),
+ indices.size() - 1,
+ idx);
+ }
+
return Address(eltPtr, eltAlign);
}
@@ -3529,8 +3614,7 @@ static Address emitOMPArraySectionBase(CodeGenFunction &CGF, const Expr *Base,
if (!BaseTy->isVariableArrayType()) {
assert(isa<llvm::ArrayType>(Addr.getElementType()) &&
"Expected pointer to array");
- Addr = CGF.Builder.CreateStructGEP(Addr, 0, CharUnits::Zero(),
- "arraydecay");
+ Addr = CGF.Builder.CreateConstArrayGEP(Addr, 0, "arraydecay");
}
return CGF.Builder.CreateElementBitCast(Addr,
@@ -3665,7 +3749,7 @@ LValue CodeGenFunction::EmitOMPArraySectionExpr(const OMPArraySectionExpr *E,
Idx = Builder.CreateNSWMul(Idx, NumElements);
EltPtr = emitArraySubscriptGEP(*this, Base, Idx, VLA->getElementType(),
!getLangOpts().isSignedOverflowDefined(),
- /*SignedIndices=*/false, E->getExprLoc());
+ /*signedIndices=*/false, E->getExprLoc());
} else if (const Expr *Array = isSimpleArrayDecayOperand(E->getBase())) {
// If this is A[i] where A is an array, the frontend will have decayed the
// base to be a ArrayToPointerDecay implicit cast. While correct, it is
@@ -3685,7 +3769,7 @@ LValue CodeGenFunction::EmitOMPArraySectionExpr(const OMPArraySectionExpr *E,
EltPtr = emitArraySubscriptGEP(
*this, ArrayLV.getAddress(), {CGM.getSize(CharUnits::Zero()), Idx},
ResultExprTy, !getLangOpts().isSignedOverflowDefined(),
- /*SignedIndices=*/false, E->getExprLoc());
+ /*signedIndices=*/false, E->getExprLoc());
BaseInfo = ArrayLV.getBaseInfo();
TBAAInfo = CGM.getTBAAInfoForSubobject(ArrayLV, ResultExprTy);
} else {
@@ -3694,7 +3778,7 @@ LValue CodeGenFunction::EmitOMPArraySectionExpr(const OMPArraySectionExpr *E,
IsLowerBound);
EltPtr = emitArraySubscriptGEP(*this, Base, Idx, ResultExprTy,
!getLangOpts().isSignedOverflowDefined(),
- /*SignedIndices=*/false, E->getExprLoc());
+ /*signedIndices=*/false, E->getExprLoc());
}
return MakeAddrLValue(EltPtr, ResultExprTy, BaseInfo, TBAAInfo);
@@ -3808,31 +3892,63 @@ LValue CodeGenFunction::EmitLValueForLambdaField(const FieldDecl *Field) {
return EmitLValueForField(LambdaLV, Field);
}
+/// Get the field index in the debug info. The debug info structure/union
+/// will ignore the unnamed bitfields.
+unsigned CodeGenFunction::getDebugInfoFIndex(const RecordDecl *Rec,
+ unsigned FieldIndex) {
+ unsigned I = 0, Skipped = 0;
+
+ for (auto F : Rec->getDefinition()->fields()) {
+ if (I == FieldIndex)
+ break;
+ if (F->isUnnamedBitfield())
+ Skipped++;
+ I++;
+ }
+
+ return FieldIndex - Skipped;
+}
+
+/// Get the address of a zero-sized field within a record. The resulting
+/// address doesn't necessarily have the right type.
+static Address emitAddrOfZeroSizeField(CodeGenFunction &CGF, Address Base,
+ const FieldDecl *Field) {
+ CharUnits Offset = CGF.getContext().toCharUnitsFromBits(
+ CGF.getContext().getFieldOffset(Field));
+ if (Offset.isZero())
+ return Base;
+ Base = CGF.Builder.CreateElementBitCast(Base, CGF.Int8Ty);
+ return CGF.Builder.CreateConstInBoundsByteGEP(Base, Offset);
+}
+
/// Drill down to the storage of a field without walking into
/// reference types.
///
/// The resulting address doesn't necessarily have the right type.
static Address emitAddrOfFieldStorage(CodeGenFunction &CGF, Address base,
const FieldDecl *field) {
+ if (field->isZeroSize(CGF.getContext()))
+ return emitAddrOfZeroSizeField(CGF, base, field);
+
const RecordDecl *rec = field->getParent();
unsigned idx =
CGF.CGM.getTypes().getCGRecordLayout(rec).getLLVMFieldNo(field);
- CharUnits offset;
- // Adjust the alignment down to the given offset.
- // As a special case, if the LLVM field index is 0, we know that this
- // is zero.
- assert((idx != 0 || CGF.getContext().getASTRecordLayout(rec)
- .getFieldOffset(field->getFieldIndex()) == 0) &&
- "LLVM field at index zero had non-zero offset?");
- if (idx != 0) {
- auto &recLayout = CGF.getContext().getASTRecordLayout(rec);
- auto offsetInBits = recLayout.getFieldOffset(field->getFieldIndex());
- offset = CGF.getContext().toCharUnitsFromBits(offsetInBits);
- }
+ return CGF.Builder.CreateStructGEP(base, idx, field->getName());
+}
+
+static Address emitPreserveStructAccess(CodeGenFunction &CGF, Address base,
+ const FieldDecl *field) {
+ const RecordDecl *rec = field->getParent();
+ llvm::DIType *DbgInfo = CGF.getDebugInfo()->getOrCreateRecordType(
+ CGF.getContext().getRecordType(rec), rec->getLocation());
+
+ unsigned idx =
+ CGF.CGM.getTypes().getCGRecordLayout(rec).getLLVMFieldNo(field);
- return CGF.Builder.CreateStructGEP(base, idx, offset, field->getName());
+ return CGF.Builder.CreatePreserveStructAccessIndex(
+ base, idx, CGF.getDebugInfoFIndex(rec, field->getFieldIndex()), DbgInfo);
}
static bool hasAnyVptr(const QualType Type, const ASTContext &Context) {
@@ -3866,8 +3982,7 @@ LValue CodeGenFunction::EmitLValueForField(LValue base,
unsigned Idx = RL.getLLVMFieldNo(field);
if (Idx != 0)
// For structs, we GEP to the field that the record layout suggests.
- Addr = Builder.CreateStructGEP(Addr, Idx, Info.StorageOffset,
- field->getName());
+ Addr = Builder.CreateStructGEP(Addr, Idx, field->getName());
// Get the access type.
llvm::Type *FieldIntTy =
llvm::Type::getIntNTy(getLLVMContext(), Info.StorageSize);
@@ -3943,9 +4058,24 @@ LValue CodeGenFunction::EmitLValueForField(LValue base,
// a barrier every time CXXRecord field with vptr is referenced.
addr = Address(Builder.CreateLaunderInvariantGroup(addr.getPointer()),
addr.getAlignment());
+
+ if (IsInPreservedAIRegion) {
+ // Remember the original union field index
+ llvm::DIType *DbgInfo = getDebugInfo()->getOrCreateRecordType(
+ getContext().getRecordType(rec), rec->getLocation());
+ addr = Address(
+ Builder.CreatePreserveUnionAccessIndex(
+ addr.getPointer(), getDebugInfoFIndex(rec, field->getFieldIndex()), DbgInfo),
+ addr.getAlignment());
+ }
} else {
- // For structs, we GEP to the field that the record layout suggests.
- addr = emitAddrOfFieldStorage(*this, addr, field);
+
+ if (!IsInPreservedAIRegion)
+ // For structs, we GEP to the field that the record layout suggests.
+ addr = emitAddrOfFieldStorage(*this, addr, field);
+ else
+ // Remember the original struct field index
+ addr = emitPreserveStructAccess(*this, addr, field);
// If this is a reference field, load the reference right now.
if (FieldType->isReferenceType()) {
@@ -4137,6 +4267,7 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
switch (E->getCastKind()) {
case CK_ToVoid:
case CK_BitCast:
+ case CK_LValueToRValueBitCast:
case CK_ArrayToPointerDecay:
case CK_FunctionToPointerDecay:
case CK_NullToMemberPointer:
@@ -4175,6 +4306,8 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
case CK_IntToOCLSampler:
case CK_FixedPointCast:
case CK_FixedPointToBoolean:
+ case CK_FixedPointToIntegral:
+ case CK_IntegralToFixedPoint:
return EmitUnsupportedLValue(E, "unexpected cast lvalue");
case CK_Dependent:
@@ -4548,13 +4681,6 @@ CodeGenFunction::EmitCXXBindTemporaryLValue(const CXXBindTemporaryExpr *E) {
return MakeAddrLValue(Slot.getAddress(), E->getType(), AlignmentSource::Decl);
}
-LValue
-CodeGenFunction::EmitLambdaLValue(const LambdaExpr *E) {
- AggValueSlot Slot = CreateAggTemp(E->getType(), "temp.lvalue");
- EmitLambdaExpr(E, Slot);
- return MakeAddrLValue(Slot.getAddress(), E->getType(), AlignmentSource::Decl);
-}
-
LValue CodeGenFunction::EmitObjCMessageExprLValue(const ObjCMessageExpr *E) {
RValue RV = EmitObjCMessageExpr(E);
@@ -4630,17 +4756,6 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, const CGCallee &OrigCallee
const Decl *TargetDecl =
OrigCallee.getAbstractInfo().getCalleeDecl().getDecl();
- if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl))
- // We can only guarantee that a function is called from the correct
- // context/function based on the appropriate target attributes,
- // so only check in the case where we have both always_inline and target
- // since otherwise we could be making a conditional call after a check for
- // the proper cpu features (and it won't cause code generation issues due to
- // function based code generation).
- if (TargetDecl->hasAttr<AlwaysInlineAttr>() &&
- TargetDecl->hasAttr<TargetAttr>())
- checkTargetFeatures(E, FD);
-
CalleeType = getContext().getCanonicalType(CalleeType);
auto PointeeType = cast<PointerType>(CalleeType)->getPointeeType();
@@ -4688,7 +4803,8 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, const CGCallee &OrigCallee
llvm::Constant *StaticData[] = {EmitCheckSourceLocation(E->getBeginLoc()),
EmitCheckTypeDescriptor(CalleeType)};
EmitCheck(std::make_pair(CalleeRTTIMatch, SanitizerKind::Function),
- SanitizerHandler::FunctionTypeMismatch, StaticData, CalleePtr);
+ SanitizerHandler::FunctionTypeMismatch, StaticData,
+ {CalleePtr, CalleeRTTI, FTRTTIConst});
Builder.CreateBr(Cont);
EmitBlock(Cont);
@@ -4768,7 +4884,7 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, const CGCallee &OrigCallee
E->getDirectCallee(), /*ParamsToSkip*/ 0, Order);
const CGFunctionInfo &FnInfo = CGM.getTypes().arrangeFreeFunctionCall(
- Args, FnType, /*isChainCall=*/Chain);
+ Args, FnType, /*ChainCall=*/Chain);
// C99 6.5.2.2p6:
// If the expression that denotes the called function has a type
@@ -4799,7 +4915,19 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, const CGCallee &OrigCallee
Callee.setFunctionPointer(CalleePtr);
}
- return EmitCall(FnInfo, Callee, ReturnValue, Args, nullptr, E->getExprLoc());
+ llvm::CallBase *CallOrInvoke = nullptr;
+ RValue Call = EmitCall(FnInfo, Callee, ReturnValue, Args, &CallOrInvoke,
+ E->getExprLoc());
+
+ // Generate function declaration DISuprogram in order to be used
+ // in debug info about call sites.
+ if (CGDebugInfo *DI = getDebugInfo()) {
+ if (auto *CalleeDecl = dyn_cast_or_null<FunctionDecl>(TargetDecl))
+ DI->EmitFuncDeclForCallSite(CallOrInvoke, QualType(FnType, 0),
+ CalleeDecl);
+ }
+
+ return Call;
}
LValue CodeGenFunction::