diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:04:05 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:04:05 +0000 |
commit | 676fbe8105eeb6ff4bb2ed261cb212fcfdbe7b63 (patch) | |
tree | 02a1ac369cb734d0abfa5000dd86e5b7797e6a74 /lib/CodeGen/CodeGenFunction.cpp | |
parent | c7e70c433efc6953dc3888b9fbf9f3512d7da2b0 (diff) |
Notes
Diffstat (limited to 'lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r-- | lib/CodeGen/CodeGenFunction.cpp | 325 |
1 files changed, 215 insertions, 110 deletions
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index 3c582688e91e5..1713e40c312b7 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -28,10 +28,10 @@ #include "clang/AST/StmtCXX.h" #include "clang/AST/StmtObjC.h" #include "clang/Basic/Builtins.h" +#include "clang/Basic/CodeGenOptions.h" #include "clang/Basic/TargetInfo.h" #include "clang/CodeGen/CGFunctionInfo.h" -#include "clang/Frontend/CodeGenOptions.h" -#include "clang/Sema/SemaDiagnostic.h" +#include "clang/Frontend/FrontendDiagnostic.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Intrinsics.h" @@ -430,10 +430,25 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { NormalCleanupDest = Address::invalid(); } - // Add the required-vector-width attribute. - if (LargestVectorWidth != 0) - CurFn->addFnAttr("min-legal-vector-width", - llvm::utostr(LargestVectorWidth)); + // Scan function arguments for vector width. + for (llvm::Argument &A : CurFn->args()) + if (auto *VT = dyn_cast<llvm::VectorType>(A.getType())) + LargestVectorWidth = std::max(LargestVectorWidth, + VT->getPrimitiveSizeInBits()); + + // Update vector width based on return type. + if (auto *VT = dyn_cast<llvm::VectorType>(CurFn->getReturnType())) + LargestVectorWidth = std::max(LargestVectorWidth, + VT->getPrimitiveSizeInBits()); + + // Add the required-vector-width attribute. This contains the max width from: + // 1. min-vector-width attribute used in the source program. + // 2. Any builtins used that have a vector width specified. + // 3. Values passed in and out of inline assembly. + // 4. Width of vector arguments and return types for this function. + // 5. Width of vector aguments and return types for functions called by this + // function. + CurFn->addFnAttr("min-legal-vector-width", llvm::utostr(LargestVectorWidth)); } /// ShouldInstrumentFunction - Return true if the current function should be @@ -772,9 +787,11 @@ static bool endsWithReturn(const Decl* F) { return false; } -static void markAsIgnoreThreadCheckingAtRuntime(llvm::Function *Fn) { - Fn->addFnAttr("sanitize_thread_no_checking_at_run_time"); - Fn->removeFnAttr(llvm::Attribute::SanitizeThread); +void CodeGenFunction::markAsIgnoreThreadCheckingAtRuntime(llvm::Function *Fn) { + if (SanOpts.has(SanitizerKind::Thread)) { + Fn->addFnAttr("sanitize_thread_no_checking_at_run_time"); + Fn->removeFnAttr(llvm::Attribute::SanitizeThread); + } } static bool matchesStlAllocatorFn(const Decl *D, const ASTContext &Ctx) { @@ -866,7 +883,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress); if (SanOpts.has(SanitizerKind::Thread)) Fn->addFnAttr(llvm::Attribute::SanitizeThread); - if (SanOpts.has(SanitizerKind::Memory)) + if (SanOpts.hasOneOf(SanitizerKind::Memory | SanitizerKind::KernelMemory)) Fn->addFnAttr(llvm::Attribute::SanitizeMemory); if (SanOpts.has(SanitizerKind::SafeStack)) Fn->addFnAttr(llvm::Attribute::SafeStack); @@ -887,10 +904,6 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, (OMD->getSelector().isUnarySelector() && II->isStr(".cxx_destruct"))) { markAsIgnoreThreadCheckingAtRuntime(Fn); } - } else if (const auto *FD = dyn_cast_or_null<FunctionDecl>(D)) { - IdentifierInfo *II = FD->getIdentifier(); - if (II && II->isStr("__destroy_helper_block_")) - markAsIgnoreThreadCheckingAtRuntime(Fn); } } @@ -903,21 +916,21 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, } // Apply xray attributes to the function (as a string, for now) - bool InstrumentXray = ShouldXRayInstrumentFunction() && - CGM.getCodeGenOpts().XRayInstrumentationBundle.has( - XRayInstrKind::Function); - if (D && InstrumentXray) { + if (D) { if (const auto *XRayAttr = D->getAttr<XRayInstrumentAttr>()) { - if (XRayAttr->alwaysXRayInstrument()) - Fn->addFnAttr("function-instrument", "xray-always"); - if (XRayAttr->neverXRayInstrument()) - Fn->addFnAttr("function-instrument", "xray-never"); - if (const auto *LogArgs = D->getAttr<XRayLogArgsAttr>()) { - Fn->addFnAttr("xray-log-args", - llvm::utostr(LogArgs->getArgumentCount())); + if (CGM.getCodeGenOpts().XRayInstrumentationBundle.has( + XRayInstrKind::Function)) { + if (XRayAttr->alwaysXRayInstrument() && ShouldXRayInstrumentFunction()) + Fn->addFnAttr("function-instrument", "xray-always"); + if (XRayAttr->neverXRayInstrument()) + Fn->addFnAttr("function-instrument", "xray-never"); + if (const auto *LogArgs = D->getAttr<XRayLogArgsAttr>()) + if (ShouldXRayInstrumentFunction()) + Fn->addFnAttr("xray-log-args", + llvm::utostr(LogArgs->getArgumentCount())); } } else { - if (!CGM.imbueXRayAttrs(Fn, Loc)) + if (ShouldXRayInstrumentFunction() && !CGM.imbueXRayAttrs(Fn, Loc)) Fn->addFnAttr( "xray-instruction-threshold", llvm::itostr(CGM.getCodeGenOpts().XRayInstructionThreshold)); @@ -981,6 +994,13 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, if (FD->isMain()) Fn->addFnAttr(llvm::Attribute::NoRecurse); + // If a custom alignment is used, force realigning to this alignment on + // any main function which certainly will need it. + if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) + if ((FD->isMain() || FD->isMSVCRTEntryPoint()) && + CGM.getCodeGenOpts().StackAlignment) + Fn->addFnAttr("stackrealign"); + llvm::BasicBlock *EntryBB = createBasicBlock("entry", CurFn); // Create a marker to make it easy to insert allocas into the entryblock @@ -1053,9 +1073,8 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, // Count the implicit return. if (!endsWithReturn(D)) ++NumReturnExprs; - } else if (CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect && - !hasScalarEvaluationKind(CurFnInfo->getReturnType())) { - // Indirect aggregate return; emit returned value directly into sret slot. + } else if (CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect) { + // Indirect return; emit returned value directly into sret slot. // This reduces code size, and affects correctness in C++. auto AI = CurFn->arg_begin(); if (CurFnInfo->getReturnInfo().isSRetAfterThis()) @@ -1137,7 +1156,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, if (CXXABIThisValue) { SanitizerSet SkippedChecks; SkippedChecks.set(SanitizerKind::ObjectSize, true); - QualType ThisTy = MD->getThisType(getContext()); + QualType ThisTy = MD->getThisType(); // If this is the call operator of a lambda with no capture-default, it // may have a static invoker function, which may call this operator with @@ -1183,8 +1202,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, LargestVectorWidth = VecWidth->getVectorWidth(); } -void CodeGenFunction::EmitFunctionBody(FunctionArgList &Args, - const Stmt *Body) { +void CodeGenFunction::EmitFunctionBody(const Stmt *Body) { incrementProfileCounter(Body); if (const CompoundStmt *S = dyn_cast<CompoundStmt>(Body)) EmitCompoundStmtWithoutScope(*S); @@ -1238,7 +1256,7 @@ QualType CodeGenFunction::BuildFunctionArgList(GlobalDecl GD, const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD); if (MD && MD->isInstance()) { if (CGM.getCXXABI().HasThisReturn(GD)) - ResTy = MD->getThisType(getContext()); + ResTy = MD->getThisType(); else if (CGM.getCXXABI().hasMostDerivedReturn(GD)) ResTy = CGM.getContext().VoidPtrTy; CGM.getCXXABI().buildThisParam(*this, Args); @@ -1352,7 +1370,7 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn, // copy-constructors. emitImplicitAssignmentOperatorBody(Args); } else if (Body) { - EmitFunctionBody(Args, Body); + EmitFunctionBody(Body); } else llvm_unreachable("no definition for emitted function"); @@ -1493,10 +1511,11 @@ bool CodeGenFunction::ConstantFoldsToSimpleInteger(const Expr *Cond, bool AllowLabels) { // FIXME: Rename and handle conversion of other evaluatable things // to bool. - llvm::APSInt Int; - if (!Cond->EvaluateAsInt(Int, getContext())) + Expr::EvalResult Result; + if (!Cond->EvaluateAsInt(Result, getContext())) return false; // Not foldable, not integer or not fully evaluatable. + llvm::APSInt Int = Result.Val.getInt(); if (!AllowLabels && CodeGenFunction::ContainsLabel(Cond)) return false; // Contains a label. @@ -1681,7 +1700,7 @@ void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond, // create metadata that specifies that the branch is unpredictable. // Don't bother if not optimizing because that metadata would not be used. llvm::MDNode *Unpredictable = nullptr; - auto *Call = dyn_cast<CallExpr>(Cond); + auto *Call = dyn_cast<CallExpr>(Cond->IgnoreImpCasts()); if (Call && CGM.getCodeGenOpts().OptimizationLevel != 0) { auto *FD = dyn_cast_or_null<FunctionDecl>(Call->getCalleeDecl()); if (FD && FD->getBuiltinID() == Builtin::BI__builtin_unpredictable) { @@ -2089,9 +2108,8 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) { SanitizerScope SanScope(this); llvm::Value *Zero = llvm::Constant::getNullValue(Size->getType()); llvm::Constant *StaticArgs[] = { - EmitCheckSourceLocation(size->getLocStart()), - EmitCheckTypeDescriptor(size->getType()) - }; + EmitCheckSourceLocation(size->getBeginLoc()), + EmitCheckTypeDescriptor(size->getType())}; EmitCheck(std::make_pair(Builder.CreateICmpSGT(Size, Zero), SanitizerKind::VLABound), SanitizerHandler::VLABoundNotPositive, StaticArgs, Size); @@ -2189,6 +2207,49 @@ void CodeGenFunction::unprotectFromPeepholes(PeepholeProtection protection) { protection.Inst->eraseFromParent(); } +void CodeGenFunction::EmitAlignmentAssumption(llvm::Value *PtrValue, + QualType Ty, SourceLocation Loc, + SourceLocation AssumptionLoc, + llvm::Value *Alignment, + llvm::Value *OffsetValue) { + llvm::Value *TheCheck; + llvm::Instruction *Assumption = Builder.CreateAlignmentAssumption( + CGM.getDataLayout(), PtrValue, Alignment, OffsetValue, &TheCheck); + if (SanOpts.has(SanitizerKind::Alignment)) { + EmitAlignmentAssumptionCheck(PtrValue, Ty, Loc, AssumptionLoc, Alignment, + OffsetValue, TheCheck, Assumption); + } +} + +void CodeGenFunction::EmitAlignmentAssumption(llvm::Value *PtrValue, + QualType Ty, SourceLocation Loc, + SourceLocation AssumptionLoc, + unsigned Alignment, + llvm::Value *OffsetValue) { + llvm::Value *TheCheck; + llvm::Instruction *Assumption = Builder.CreateAlignmentAssumption( + CGM.getDataLayout(), PtrValue, Alignment, OffsetValue, &TheCheck); + if (SanOpts.has(SanitizerKind::Alignment)) { + llvm::Value *AlignmentVal = llvm::ConstantInt::get(IntPtrTy, Alignment); + EmitAlignmentAssumptionCheck(PtrValue, Ty, Loc, AssumptionLoc, AlignmentVal, + OffsetValue, TheCheck, Assumption); + } +} + +void CodeGenFunction::EmitAlignmentAssumption(llvm::Value *PtrValue, + const Expr *E, + SourceLocation AssumptionLoc, + unsigned Alignment, + llvm::Value *OffsetValue) { + if (auto *CE = dyn_cast<CastExpr>(E)) + E = CE->getSubExprAsWritten(); + QualType Ty = E->getType(); + SourceLocation Loc = E->getExprLoc(); + + EmitAlignmentAssumption(PtrValue, Ty, Loc, AssumptionLoc, Alignment, + OffsetValue); +} + llvm::Value *CodeGenFunction::EmitAnnotationCall(llvm::Value *AnnotationFn, llvm::Value *AnnotatedVal, StringRef AnnotationStr, @@ -2225,7 +2286,7 @@ Address CodeGenFunction::EmitFieldAnnotations(const FieldDecl *D, // annotation on the first field of a struct and annotation on the struct // itself. if (VTy != CGM.Int8PtrTy) - V = Builder.Insert(new llvm::BitCastInst(V, CGM.Int8PtrTy)); + V = Builder.CreateBitCast(V, CGM.Int8PtrTy); V = EmitAnnotationCall(F, V, I->getAnnotation(), D->getLocation()); V = Builder.CreateBitCast(V, VTy); } @@ -2272,7 +2333,7 @@ static bool hasRequiredFeatures(const SmallVectorImpl<StringRef> &ReqFeatures, // Now build up the set of caller features and verify that all the required // features are there. llvm::StringMap<bool> CallerFeatureMap; - CGM.getFunctionFeatureMap(CallerFeatureMap, FD); + CGM.getFunctionFeatureMap(CallerFeatureMap, GlobalDecl().getWithDecl(FD)); // If we have at least one of the features in the feature list return // true, otherwise return false. @@ -2280,14 +2341,13 @@ static bool hasRequiredFeatures(const SmallVectorImpl<StringRef> &ReqFeatures, ReqFeatures.begin(), ReqFeatures.end(), [&](StringRef Feature) { SmallVector<StringRef, 1> OrFeatures; Feature.split(OrFeatures, '|'); - return std::any_of(OrFeatures.begin(), OrFeatures.end(), - [&](StringRef Feature) { - if (!CallerFeatureMap.lookup(Feature)) { - FirstMissing = Feature.str(); - return false; - } - return true; - }); + return llvm::any_of(OrFeatures, [&](StringRef Feature) { + if (!CallerFeatureMap.lookup(Feature)) { + FirstMissing = Feature.str(); + return false; + } + return true; + }); }); } @@ -2319,7 +2379,7 @@ void CodeGenFunction::checkTargetFeatures(const CallExpr *E, return; StringRef(FeatureList).split(ReqFeatures, ','); if (!hasRequiredFeatures(ReqFeatures, CGM, FD, MissingFeature)) - CGM.getDiags().Report(E->getLocStart(), diag::err_builtin_needs_feature) + CGM.getDiags().Report(E->getBeginLoc(), diag::err_builtin_needs_feature) << TargetDecl->getDeclName() << CGM.getContext().BuiltinInfo.getRequiredFeatures(BuiltinID); @@ -2345,7 +2405,7 @@ void CodeGenFunction::checkTargetFeatures(const CallExpr *E, ReqFeatures.push_back(F.getKey()); } if (!hasRequiredFeatures(ReqFeatures, CGM, FD, MissingFeature)) - CGM.getDiags().Report(E->getLocStart(), diag::err_function_needs_feature) + CGM.getDiags().Report(E->getBeginLoc(), diag::err_function_needs_feature) << FD->getDeclName() << TargetDecl->getDeclName() << MissingFeature; } } @@ -2359,91 +2419,81 @@ void CodeGenFunction::EmitSanitizerStatReport(llvm::SanitizerStatKind SSK) { CGM.getSanStats().create(IRB, SSK); } -llvm::Value *CodeGenFunction::FormResolverCondition( - const TargetMultiVersionResolverOption &RO) { - llvm::Value *TrueCondition = nullptr; - if (!RO.ParsedAttribute.Architecture.empty()) - TrueCondition = EmitX86CpuIs(RO.ParsedAttribute.Architecture); +llvm::Value * +CodeGenFunction::FormResolverCondition(const MultiVersionResolverOption &RO) { + llvm::Value *Condition = nullptr; + + if (!RO.Conditions.Architecture.empty()) + Condition = EmitX86CpuIs(RO.Conditions.Architecture); - if (!RO.ParsedAttribute.Features.empty()) { - SmallVector<StringRef, 8> FeatureList; - llvm::for_each(RO.ParsedAttribute.Features, - [&FeatureList](const std::string &Feature) { - FeatureList.push_back(StringRef{Feature}.substr(1)); - }); - llvm::Value *FeatureCmp = EmitX86CpuSupports(FeatureList); - TrueCondition = TrueCondition ? Builder.CreateAnd(TrueCondition, FeatureCmp) - : FeatureCmp; + if (!RO.Conditions.Features.empty()) { + llvm::Value *FeatureCond = EmitX86CpuSupports(RO.Conditions.Features); + Condition = + Condition ? Builder.CreateAnd(Condition, FeatureCond) : FeatureCond; } - return TrueCondition; + return Condition; } -void CodeGenFunction::EmitTargetMultiVersionResolver( - llvm::Function *Resolver, - ArrayRef<TargetMultiVersionResolverOption> Options) { - assert((getContext().getTargetInfo().getTriple().getArch() == - llvm::Triple::x86 || - getContext().getTargetInfo().getTriple().getArch() == - llvm::Triple::x86_64) && - "Only implemented for x86 targets"); - - // Main function's basic block. - llvm::BasicBlock *CurBlock = createBasicBlock("entry", Resolver); - Builder.SetInsertPoint(CurBlock); - EmitX86CpuInit(); +static void CreateMultiVersionResolverReturn(CodeGenModule &CGM, + llvm::Function *Resolver, + CGBuilderTy &Builder, + llvm::Function *FuncToReturn, + bool SupportsIFunc) { + if (SupportsIFunc) { + Builder.CreateRet(FuncToReturn); + return; + } - llvm::Function *DefaultFunc = nullptr; - for (const TargetMultiVersionResolverOption &RO : Options) { - Builder.SetInsertPoint(CurBlock); - llvm::Value *TrueCondition = FormResolverCondition(RO); + llvm::SmallVector<llvm::Value *, 10> Args; + llvm::for_each(Resolver->args(), + [&](llvm::Argument &Arg) { Args.push_back(&Arg); }); - if (!TrueCondition) { - DefaultFunc = RO.Function; - } else { - llvm::BasicBlock *RetBlock = createBasicBlock("ro_ret", Resolver); - llvm::IRBuilder<> RetBuilder(RetBlock); - RetBuilder.CreateRet(RO.Function); - CurBlock = createBasicBlock("ro_else", Resolver); - Builder.CreateCondBr(TrueCondition, RetBlock, CurBlock); - } - } + llvm::CallInst *Result = Builder.CreateCall(FuncToReturn, Args); + Result->setTailCallKind(llvm::CallInst::TCK_MustTail); - assert(DefaultFunc && "No default version?"); - // Emit return from the 'else-ist' block. - Builder.SetInsertPoint(CurBlock); - Builder.CreateRet(DefaultFunc); + if (Resolver->getReturnType()->isVoidTy()) + Builder.CreateRetVoid(); + else + Builder.CreateRet(Result); } -void CodeGenFunction::EmitCPUDispatchMultiVersionResolver( - llvm::Function *Resolver, - ArrayRef<CPUDispatchMultiVersionResolverOption> Options) { +void CodeGenFunction::EmitMultiVersionResolver( + llvm::Function *Resolver, ArrayRef<MultiVersionResolverOption> Options) { assert((getContext().getTargetInfo().getTriple().getArch() == llvm::Triple::x86 || getContext().getTargetInfo().getTriple().getArch() == llvm::Triple::x86_64) && "Only implemented for x86 targets"); + bool SupportsIFunc = getContext().getTargetInfo().supportsIFunc(); + // Main function's basic block. llvm::BasicBlock *CurBlock = createBasicBlock("resolver_entry", Resolver); Builder.SetInsertPoint(CurBlock); EmitX86CpuInit(); - for (const CPUDispatchMultiVersionResolverOption &RO : Options) { + for (const MultiVersionResolverOption &RO : Options) { Builder.SetInsertPoint(CurBlock); - - // "generic" case should catch-all. - if (RO.FeatureMask == 0) { - Builder.CreateRet(RO.Function); + llvm::Value *Condition = FormResolverCondition(RO); + + // The 'default' or 'generic' case. + if (!Condition) { + assert(&RO == Options.end() - 1 && + "Default or Generic case must be last"); + CreateMultiVersionResolverReturn(CGM, Resolver, Builder, RO.Function, + SupportsIFunc); return; } + llvm::BasicBlock *RetBlock = createBasicBlock("resolver_return", Resolver); - llvm::IRBuilder<> RetBuilder(RetBlock); - RetBuilder.CreateRet(RO.Function); + CGBuilderTy RetBuilder(*this, RetBlock); + CreateMultiVersionResolverReturn(CGM, Resolver, RetBuilder, RO.Function, + SupportsIFunc); CurBlock = createBasicBlock("resolver_else", Resolver); - llvm::Value *TrueCondition = EmitX86CpuSupports(RO.FeatureMask); - Builder.CreateCondBr(TrueCondition, RetBlock, CurBlock); + Builder.CreateCondBr(Condition, RetBlock, CurBlock); } + // If no generic/default, emit an unreachable. Builder.SetInsertPoint(CurBlock); llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap); TrapCall->setDoesNotReturn(); @@ -2452,6 +2502,61 @@ void CodeGenFunction::EmitCPUDispatchMultiVersionResolver( Builder.ClearInsertionPoint(); } +// Loc - where the diagnostic will point, where in the source code this +// alignment has failed. +// SecondaryLoc - if present (will be present if sufficiently different from +// Loc), the diagnostic will additionally point a "Note:" to this location. +// It should be the location where the __attribute__((assume_aligned)) +// was written e.g. +void CodeGenFunction::EmitAlignmentAssumptionCheck( + llvm::Value *Ptr, QualType Ty, SourceLocation Loc, + SourceLocation SecondaryLoc, llvm::Value *Alignment, + llvm::Value *OffsetValue, llvm::Value *TheCheck, + llvm::Instruction *Assumption) { + assert(Assumption && isa<llvm::CallInst>(Assumption) && + cast<llvm::CallInst>(Assumption)->getCalledValue() == + llvm::Intrinsic::getDeclaration( + Builder.GetInsertBlock()->getParent()->getParent(), + llvm::Intrinsic::assume) && + "Assumption should be a call to llvm.assume()."); + assert(&(Builder.GetInsertBlock()->back()) == Assumption && + "Assumption should be the last instruction of the basic block, " + "since the basic block is still being generated."); + + if (!SanOpts.has(SanitizerKind::Alignment)) + return; + + // Don't check pointers to volatile data. The behavior here is implementation- + // defined. + if (Ty->getPointeeType().isVolatileQualified()) + return; + + // We need to temorairly remove the assumption so we can insert the + // sanitizer check before it, else the check will be dropped by optimizations. + Assumption->removeFromParent(); + + { + SanitizerScope SanScope(this); + + if (!OffsetValue) + OffsetValue = Builder.getInt1(0); // no offset. + + llvm::Constant *StaticData[] = {EmitCheckSourceLocation(Loc), + EmitCheckSourceLocation(SecondaryLoc), + EmitCheckTypeDescriptor(Ty)}; + llvm::Value *DynamicData[] = {EmitCheckValue(Ptr), + EmitCheckValue(Alignment), + EmitCheckValue(OffsetValue)}; + EmitCheck({std::make_pair(TheCheck, SanitizerKind::Alignment)}, + SanitizerHandler::AlignmentAssumption, StaticData, DynamicData); + } + + // We are now in the (new, empty) "cont" basic block. + // Reintroduce the assumption. + Builder.Insert(Assumption); + // FIXME: Assumption still has it's original basic block as it's Parent. +} + llvm::DebugLoc CodeGenFunction::SourceLocToDebugLoc(SourceLocation Location) { if (CGDebugInfo *DI = getDebugInfo()) return DI->SourceLocToDebugLoc(Location); |