summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/CodeGen/CGDecl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/CGDecl.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGDecl.cpp143
1 files changed, 101 insertions, 42 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGDecl.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGDecl.cpp
index 0a88b23..2351786 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGDecl.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGDecl.cpp
@@ -11,14 +11,15 @@
//
//===----------------------------------------------------------------------===//
-#include "CodeGenFunction.h"
#include "CGBlocks.h"
#include "CGCXXABI.h"
#include "CGCleanup.h"
#include "CGDebugInfo.h"
#include "CGOpenCLRuntime.h"
#include "CGOpenMPRuntime.h"
+#include "CodeGenFunction.h"
#include "CodeGenModule.h"
+#include "TargetInfo.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/CharUnits.h"
#include "clang/AST/Decl.h"
@@ -50,6 +51,7 @@ void CodeGenFunction::EmitDecl(const Decl &D) {
case Decl::TemplateTypeParm:
case Decl::UnresolvedUsingValue:
case Decl::NonTypeTemplateParm:
+ case Decl::CXXDeductionGuide:
case Decl::CXXMethod:
case Decl::CXXConstructor:
case Decl::CXXDestructor:
@@ -151,7 +153,14 @@ void CodeGenFunction::EmitDecl(const Decl &D) {
/// EmitVarDecl - This method handles emission of any variable declaration
/// inside a function, including static vars etc.
void CodeGenFunction::EmitVarDecl(const VarDecl &D) {
- if (D.isStaticLocal()) {
+ if (D.hasExternalStorage())
+ // Don't emit it now, allow it to be emitted lazily on its first use.
+ return;
+
+ // Some function-scope variable does not have static storage but still
+ // needs to be emitted like a static variable, e.g. a function-scope
+ // variable in constant address space in OpenCL.
+ if (D.getStorageDuration() != SD_Automatic) {
llvm::GlobalValue::LinkageTypes Linkage =
CGM.getLLVMLinkageVarDefinition(&D, /*isConstant=*/false);
@@ -162,10 +171,6 @@ void CodeGenFunction::EmitVarDecl(const VarDecl &D) {
return EmitStaticVarDecl(D, Linkage);
}
- if (D.hasExternalStorage())
- // Don't emit it now, allow it to be emitted lazily on its first use.
- return;
-
if (D.getType().getAddressSpace() == LangAS::opencl_local)
return CGM.getOpenCLRuntime().EmitWorkGroupLocalVarDecl(*this, D);
@@ -216,8 +221,8 @@ llvm::Constant *CodeGenModule::getOrCreateStaticVarDecl(
Name = getStaticDeclName(*this, D);
llvm::Type *LTy = getTypes().ConvertTypeForMem(Ty);
- unsigned AddrSpace =
- GetGlobalVarAddressSpace(&D, getContext().getTargetAddressSpace(Ty));
+ unsigned AS = GetGlobalVarAddressSpace(&D);
+ unsigned TargetAS = getContext().getTargetAddressSpace(AS);
// Local address space cannot have an initializer.
llvm::Constant *Init = nullptr;
@@ -226,12 +231,9 @@ llvm::Constant *CodeGenModule::getOrCreateStaticVarDecl(
else
Init = llvm::UndefValue::get(LTy);
- llvm::GlobalVariable *GV =
- new llvm::GlobalVariable(getModule(), LTy,
- Ty.isConstant(getContext()), Linkage,
- Init, Name, nullptr,
- llvm::GlobalVariable::NotThreadLocal,
- AddrSpace);
+ llvm::GlobalVariable *GV = new llvm::GlobalVariable(
+ getModule(), LTy, Ty.isConstant(getContext()), Linkage, Init, Name,
+ nullptr, llvm::GlobalVariable::NotThreadLocal, TargetAS);
GV->setAlignment(getContext().getDeclAlign(&D).getQuantity());
setGlobalVisibility(GV, &D);
@@ -249,11 +251,12 @@ llvm::Constant *CodeGenModule::getOrCreateStaticVarDecl(
}
// Make sure the result is of the correct type.
- unsigned ExpectedAddrSpace = getContext().getTargetAddressSpace(Ty);
+ unsigned ExpectedAS = Ty.getAddressSpace();
llvm::Constant *Addr = GV;
- if (AddrSpace != ExpectedAddrSpace) {
- llvm::PointerType *PTy = llvm::PointerType::get(LTy, ExpectedAddrSpace);
- Addr = llvm::ConstantExpr::getAddrSpaceCast(GV, PTy);
+ if (AS != ExpectedAS) {
+ Addr = getTargetCodeGenInfo().performAddrSpaceCast(
+ *this, GV, AS, ExpectedAS,
+ LTy->getPointerTo(getContext().getTargetAddressSpace(ExpectedAS)));
}
setStaticLocalDeclAddress(&D, Addr);
@@ -401,6 +404,13 @@ void CodeGenFunction::EmitStaticVarDecl(const VarDecl &D,
if (D.hasAttr<AnnotateAttr>())
CGM.AddGlobalAnnotations(&D, var);
+ if (auto *SA = D.getAttr<PragmaClangBSSSectionAttr>())
+ var->addAttribute("bss-section", SA->getName());
+ if (auto *SA = D.getAttr<PragmaClangDataSectionAttr>())
+ var->addAttribute("data-section", SA->getName());
+ if (auto *SA = D.getAttr<PragmaClangRodataSectionAttr>())
+ var->addAttribute("rodata-section", SA->getName());
+
if (const SectionAttr *SA = D.getAttr<SectionAttr>())
var->setSection(SA->getName());
@@ -671,6 +681,27 @@ static void drillIntoBlockVariable(CodeGenFunction &CGF,
lvalue.setAddress(CGF.emitBlockByrefAddress(lvalue.getAddress(), var));
}
+void CodeGenFunction::EmitNullabilityCheck(LValue LHS, llvm::Value *RHS,
+ SourceLocation Loc) {
+ if (!SanOpts.has(SanitizerKind::NullabilityAssign))
+ return;
+
+ auto Nullability = LHS.getType()->getNullability(getContext());
+ if (!Nullability || *Nullability != NullabilityKind::NonNull)
+ return;
+
+ // Check if the right hand side of the assignment is nonnull, if the left
+ // hand side must be nonnull.
+ SanitizerScope SanScope(this);
+ llvm::Value *IsNotNull = Builder.CreateIsNotNull(RHS);
+ llvm::Constant *StaticData[] = {
+ EmitCheckSourceLocation(Loc), EmitCheckTypeDescriptor(LHS.getType()),
+ llvm::ConstantInt::get(Int8Ty, 0), // The LogAlignment info is unused.
+ llvm::ConstantInt::get(Int8Ty, TCK_NonnullAssign)};
+ EmitCheck({{IsNotNull, SanitizerKind::NullabilityAssign}},
+ SanitizerHandler::TypeMismatch, StaticData, RHS);
+}
+
void CodeGenFunction::EmitScalarInit(const Expr *init, const ValueDecl *D,
LValue lvalue, bool capturedByInit) {
Qualifiers::ObjCLifetime lifetime = lvalue.getObjCLifetime();
@@ -678,6 +709,7 @@ void CodeGenFunction::EmitScalarInit(const Expr *init, const ValueDecl *D,
llvm::Value *value = EmitScalarExpr(init);
if (capturedByInit)
drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D));
+ EmitNullabilityCheck(lvalue, value, init->getExprLoc());
EmitStoreThroughLValue(RValue::get(value), lvalue, true);
return;
}
@@ -766,6 +798,8 @@ void CodeGenFunction::EmitScalarInit(const Expr *init, const ValueDecl *D,
if (capturedByInit) drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D));
+ EmitNullabilityCheck(lvalue, value, init->getExprLoc());
+
// If the variable might have been accessed by its initializer, we
// might have to initialize with a barrier. We have to do this for
// both __weak and __strong, but __weak got filtered out above.
@@ -899,7 +933,7 @@ llvm::Value *CodeGenFunction::EmitLifetimeStart(uint64_t Size,
return nullptr;
llvm::Value *SizeV = llvm::ConstantInt::get(Int64Ty, Size);
- Addr = Builder.CreateBitCast(Addr, Int8PtrTy);
+ Addr = Builder.CreateBitCast(Addr, AllocaInt8PtrTy);
llvm::CallInst *C =
Builder.CreateCall(CGM.getLLVMLifetimeStartFn(), {SizeV, Addr});
C->setDoesNotThrow();
@@ -907,7 +941,7 @@ llvm::Value *CodeGenFunction::EmitLifetimeStart(uint64_t Size,
}
void CodeGenFunction::EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr) {
- Addr = Builder.CreateBitCast(Addr, Int8PtrTy);
+ Addr = Builder.CreateBitCast(Addr, AllocaInt8PtrTy);
llvm::CallInst *C =
Builder.CreateCall(CGM.getLLVMLifetimeEndFn(), {Size, Addr});
C->setDoesNotThrow();
@@ -918,6 +952,7 @@ void CodeGenFunction::EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr) {
CodeGenFunction::AutoVarEmission
CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
QualType Ty = D.getType();
+ assert(Ty.getAddressSpace() == LangAS::Default);
AutoVarEmission emission(D);
@@ -1010,8 +1045,7 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
// Create the alloca. Note that we set the name separately from
// building the instruction so that it's there even in no-asserts
// builds.
- address = CreateTempAlloca(allocaTy, allocaAlignment);
- address.getPointer()->setName(D.getName());
+ address = CreateTempAlloca(allocaTy, allocaAlignment, D.getName());
// Don't emit lifetime markers for MSVC catch parameters. The lifetime of
// the catch parameter starts in the catchpad instruction, and we can't
@@ -1022,11 +1056,21 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
// Emit a lifetime intrinsic if meaningful. There's no point in doing this
// if we don't have a valid insertion point (?).
if (HaveInsertPoint() && !IsMSCatchParam) {
- // goto or switch-case statements can break lifetime into several
- // regions which need more efforts to handle them correctly. PR28267
- // This is rare case, but it's better just omit intrinsics than have
- // them incorrectly placed.
- if (!Bypasses.IsBypassed(&D)) {
+ // If there's a jump into the lifetime of this variable, its lifetime
+ // gets broken up into several regions in IR, which requires more work
+ // to handle correctly. For now, just omit the intrinsics; this is a
+ // rare case, and it's better to just be conservatively correct.
+ // PR28267.
+ //
+ // We have to do this in all language modes if there's a jump past the
+ // declaration. We also have to do it in C if there's a jump to an
+ // earlier point in the current block because non-VLA lifetimes begin as
+ // soon as the containing block is entered, not when its variables
+ // actually come into scope; suppressing the lifetime annotations
+ // completely in this case is unnecessarily pessimistic, but again, this
+ // is rare.
+ if (!Bypasses.IsBypassed(&D) &&
+ !(!getLangOpts().CPlusPlus && hasLabelBeenSeenInCurrentScope())) {
uint64_t size = CGM.getDataLayout().getTypeAllocSize(allocaTy);
emission.SizeForLifetimeMarkers =
EmitLifetimeStart(size, address.getPointer());
@@ -1061,10 +1105,7 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
llvm::Type *llvmTy = ConvertTypeForMem(elementType);
// Allocate memory for the array.
- llvm::AllocaInst *vla = Builder.CreateAlloca(llvmTy, elementCount, "vla");
- vla->setAlignment(alignment.getQuantity());
-
- address = Address(vla, alignment);
+ address = CreateTempAlloca(llvmTy, alignment, "vla", elementCount);
}
setAddrOfLocalVar(&D, address);
@@ -1083,6 +1124,12 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
if (D.hasAttr<AnnotateAttr>())
EmitVarAnnotations(&D, address.getPointer());
+ // Make sure we call @llvm.lifetime.end.
+ if (emission.useLifetimeMarkers())
+ EHStack.pushCleanup<CallLifetimeEnd>(NormalEHLifetimeMarker,
+ emission.getAllocatedAddress(),
+ emission.getSizeForLifetimeMarkers());
+
return emission;
}
@@ -1373,13 +1420,6 @@ void CodeGenFunction::EmitAutoVarCleanups(const AutoVarEmission &emission) {
const VarDecl &D = *emission.Variable;
- // Make sure we call @llvm.lifetime.end. This needs to happen
- // *last*, so the cleanup needs to be pushed *first*.
- if (emission.useLifetimeMarkers())
- EHStack.pushCleanup<CallLifetimeEnd>(NormalEHLifetimeMarker,
- emission.getAllocatedAddress(),
- emission.getSizeForLifetimeMarkers());
-
// Check the type for a cleanup.
if (QualType::DestructionKind dtorKind = D.getType().isDestructedType())
emitAutoVarTypeCleanup(emission, dtorKind);
@@ -1691,17 +1731,19 @@ void CodeGenFunction::pushRegularPartialArrayCleanup(llvm::Value *arrayBegin,
/// Lazily declare the @llvm.lifetime.start intrinsic.
llvm::Constant *CodeGenModule::getLLVMLifetimeStartFn() {
- if (LifetimeStartFn) return LifetimeStartFn;
+ if (LifetimeStartFn)
+ return LifetimeStartFn;
LifetimeStartFn = llvm::Intrinsic::getDeclaration(&getModule(),
- llvm::Intrinsic::lifetime_start);
+ llvm::Intrinsic::lifetime_start, AllocaInt8PtrTy);
return LifetimeStartFn;
}
/// Lazily declare the @llvm.lifetime.end intrinsic.
llvm::Constant *CodeGenModule::getLLVMLifetimeEndFn() {
- if (LifetimeEndFn) return LifetimeEndFn;
+ if (LifetimeEndFn)
+ return LifetimeEndFn;
LifetimeEndFn = llvm::Intrinsic::getDeclaration(&getModule(),
- llvm::Intrinsic::lifetime_end);
+ llvm::Intrinsic::lifetime_end, AllocaInt8PtrTy);
return LifetimeEndFn;
}
@@ -1816,6 +1858,10 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, ParamValue Arg,
lt = Qualifiers::OCL_ExplicitNone;
}
+ // Load objects passed indirectly.
+ if (Arg.isIndirect() && !ArgVal)
+ ArgVal = Builder.CreateLoad(DeclPtr);
+
if (lt == Qualifiers::OCL_Strong) {
if (!isConsumed) {
if (CGM.getCodeGenOpts().OptimizationLevel == 0) {
@@ -1869,6 +1915,19 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, ParamValue Arg,
if (D.hasAttr<AnnotateAttr>())
EmitVarAnnotations(&D, DeclPtr.getPointer());
+
+ // We can only check return value nullability if all arguments to the
+ // function satisfy their nullability preconditions. This makes it necessary
+ // to emit null checks for args in the function body itself.
+ if (requiresReturnValueNullabilityCheck()) {
+ auto Nullability = Ty->getNullability(getContext());
+ if (Nullability && *Nullability == NullabilityKind::NonNull) {
+ SanitizerScope SanScope(this);
+ RetValNullabilityPrecondition =
+ Builder.CreateAnd(RetValNullabilityPrecondition,
+ Builder.CreateIsNotNull(Arg.getAnyValue()));
+ }
+ }
}
void CodeGenModule::EmitOMPDeclareReduction(const OMPDeclareReductionDecl *D,
OpenPOWER on IntegriCloud