From owner-svn-src-vendor@freebsd.org Fri May 22 16:12:24 2020 Return-Path: Delivered-To: svn-src-vendor@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 6EDDC2CD0C4; Fri, 22 May 2020 16:12:24 +0000 (UTC) (envelope-from dim@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 49TBMr2Tznz4Vpb; Fri, 22 May 2020 16:12:24 +0000 (UTC) (envelope-from dim@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 37141215FD; Fri, 22 May 2020 16:12:24 +0000 (UTC) (envelope-from dim@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 04MGCOIF087545; Fri, 22 May 2020 16:12:24 GMT (envelope-from dim@FreeBSD.org) Received: (from dim@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 04MGCIp8087516; Fri, 22 May 2020 16:12:18 GMT (envelope-from dim@FreeBSD.org) Message-Id: <202005221612.04MGCIp8087516@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: dim set sender to dim@FreeBSD.org using -f From: Dimitry Andric Date: Fri, 22 May 2020 16:12:18 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org Subject: svn commit: r361387 - in vendor/llvm-project/release-10.x: clang/include/clang/AST clang/include/clang/Basic clang/lib/AST clang/lib/CodeGen clang/lib/Driver/ToolChains clang/lib/Format clang/lib/S... X-SVN-Group: vendor X-SVN-Commit-Author: dim X-SVN-Commit-Paths: in vendor/llvm-project/release-10.x: clang/include/clang/AST clang/include/clang/Basic clang/lib/AST clang/lib/CodeGen clang/lib/Driver/ToolChains clang/lib/Format clang/lib/Sema compiler-rt/lib/profi... X-SVN-Commit-Revision: 361387 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-vendor@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: SVN commit messages for the vendor work area tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 22 May 2020 16:12:24 -0000 Author: dim Date: Fri May 22 16:12:18 2020 New Revision: 361387 URL: https://svnweb.freebsd.org/changeset/base/361387 Log: Vendor import of llvm-project branch release/10.x llvmorg-10.0.1-rc1-0-gf79cd71e145. Modified: vendor/llvm-project/release-10.x/clang/include/clang/AST/DeclBase.h vendor/llvm-project/release-10.x/clang/include/clang/Basic/Attr.td vendor/llvm-project/release-10.x/clang/lib/AST/DeclBase.cpp vendor/llvm-project/release-10.x/clang/lib/AST/ExprConstant.cpp vendor/llvm-project/release-10.x/clang/lib/AST/RawCommentList.cpp vendor/llvm-project/release-10.x/clang/lib/CodeGen/CGVTables.cpp vendor/llvm-project/release-10.x/clang/lib/CodeGen/CodeGenModule.cpp vendor/llvm-project/release-10.x/clang/lib/Driver/ToolChains/Darwin.cpp vendor/llvm-project/release-10.x/clang/lib/Driver/ToolChains/Gnu.cpp vendor/llvm-project/release-10.x/clang/lib/Driver/ToolChains/Gnu.h vendor/llvm-project/release-10.x/clang/lib/Driver/ToolChains/Hurd.cpp vendor/llvm-project/release-10.x/clang/lib/Driver/ToolChains/Hurd.h vendor/llvm-project/release-10.x/clang/lib/Driver/ToolChains/Linux.cpp vendor/llvm-project/release-10.x/clang/lib/Driver/ToolChains/Linux.h vendor/llvm-project/release-10.x/clang/lib/Format/TokenAnnotator.cpp vendor/llvm-project/release-10.x/clang/lib/Sema/SemaTemplateInstantiate.cpp vendor/llvm-project/release-10.x/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp vendor/llvm-project/release-10.x/clang/lib/Sema/TreeTransform.h vendor/llvm-project/release-10.x/compiler-rt/lib/profile/GCDAProfiling.c vendor/llvm-project/release-10.x/lld/COFF/MarkLive.cpp vendor/llvm-project/release-10.x/lld/ELF/Driver.cpp vendor/llvm-project/release-10.x/lld/ELF/InputSection.cpp vendor/llvm-project/release-10.x/lld/ELF/InputSection.h vendor/llvm-project/release-10.x/lld/ELF/OutputSections.cpp vendor/llvm-project/release-10.x/lld/ELF/Writer.cpp vendor/llvm-project/release-10.x/llvm/include/llvm/Analysis/ValueLattice.h vendor/llvm-project/release-10.x/llvm/include/llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h vendor/llvm-project/release-10.x/llvm/lib/Analysis/LazyValueInfo.cpp vendor/llvm-project/release-10.x/llvm/lib/Analysis/ValueLattice.cpp vendor/llvm-project/release-10.x/llvm/lib/CodeGen/MachineSink.cpp vendor/llvm-project/release-10.x/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp vendor/llvm-project/release-10.x/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp vendor/llvm-project/release-10.x/llvm/lib/DebugInfo/CodeView/MergingTypeTableBuilder.cpp vendor/llvm-project/release-10.x/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp vendor/llvm-project/release-10.x/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp vendor/llvm-project/release-10.x/llvm/lib/MC/MCObjectFileInfo.cpp vendor/llvm-project/release-10.x/llvm/lib/Target/ARM/ARMISelLowering.cpp vendor/llvm-project/release-10.x/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp vendor/llvm-project/release-10.x/llvm/lib/Target/BPF/BPFMISimplifyPatchable.cpp vendor/llvm-project/release-10.x/llvm/lib/Target/PowerPC/PPCISelLowering.cpp vendor/llvm-project/release-10.x/llvm/lib/Target/X86/X86ISelLowering.cpp vendor/llvm-project/release-10.x/llvm/lib/Target/X86/X86IndirectBranchTracking.cpp vendor/llvm-project/release-10.x/llvm/lib/Target/X86/X86TargetMachine.cpp vendor/llvm-project/release-10.x/llvm/lib/Target/X86/X86TargetMachine.h vendor/llvm-project/release-10.x/llvm/lib/Transforms/Coroutines/CoroSplit.cpp vendor/llvm-project/release-10.x/llvm/lib/Transforms/IPO/GlobalOpt.cpp vendor/llvm-project/release-10.x/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp vendor/llvm-project/release-10.x/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp vendor/llvm-project/release-10.x/llvm/tools/llvm-objcopy/ELF/Object.cpp vendor/llvm-project/release-10.x/llvm/tools/llvm-objcopy/llvm-objcopy.cpp Modified: vendor/llvm-project/release-10.x/clang/include/clang/AST/DeclBase.h ============================================================================== --- vendor/llvm-project/release-10.x/clang/include/clang/AST/DeclBase.h Fri May 22 15:42:45 2020 (r361386) +++ vendor/llvm-project/release-10.x/clang/include/clang/AST/DeclBase.h Fri May 22 16:12:18 2020 (r361387) @@ -856,14 +856,15 @@ class alignas(8) Decl { (public) return getParentFunctionOrMethod() == nullptr; } - /// Returns true if this declaration lexically is inside a function. - /// It recognizes non-defining declarations as well as members of local - /// classes: + /// Returns true if this declaration is lexically inside a function or inside + /// a variable initializer. It recognizes non-defining declarations as well + /// as members of local classes: /// \code /// void foo() { void bar(); } /// void foo2() { class ABC { void bar(); }; } + /// inline int x = [](){ return 0; }; /// \endcode - bool isLexicallyWithinFunctionOrMethod() const; + bool isInLocalScope() const; /// If this decl is defined inside a function/method/block it returns /// the corresponding DeclContext, otherwise it returns null. Modified: vendor/llvm-project/release-10.x/clang/include/clang/Basic/Attr.td ============================================================================== --- vendor/llvm-project/release-10.x/clang/include/clang/Basic/Attr.td Fri May 22 15:42:45 2020 (r361386) +++ vendor/llvm-project/release-10.x/clang/include/clang/Basic/Attr.td Fri May 22 16:12:18 2020 (r361387) @@ -685,7 +685,7 @@ def XRayLogArgs : InheritableAttr { def PatchableFunctionEntry : InheritableAttr, - TargetSpecificAttr> { + TargetSpecificAttr> { let Spellings = [GCC<"patchable_function_entry">]; let Subjects = SubjectList<[Function, ObjCMethod]>; let Args = [UnsignedArgument<"Count">, DefaultIntArgument<"Offset", 0>]; Modified: vendor/llvm-project/release-10.x/clang/lib/AST/DeclBase.cpp ============================================================================== --- vendor/llvm-project/release-10.x/clang/lib/AST/DeclBase.cpp Fri May 22 15:42:45 2020 (r361386) +++ vendor/llvm-project/release-10.x/clang/lib/AST/DeclBase.cpp Fri May 22 16:12:18 2020 (r361387) @@ -332,13 +332,16 @@ void Decl::setDeclContextsImpl(DeclContext *SemaDC, De } } -bool Decl::isLexicallyWithinFunctionOrMethod() const { +bool Decl::isInLocalScope() const { const DeclContext *LDC = getLexicalDeclContext(); while (true) { if (LDC->isFunctionOrMethod()) return true; if (!isa(LDC)) return false; + if (const auto *CRD = dyn_cast(LDC)) + if (CRD->isLambda()) + return true; LDC = LDC->getLexicalParent(); } return false; Modified: vendor/llvm-project/release-10.x/clang/lib/AST/ExprConstant.cpp ============================================================================== --- vendor/llvm-project/release-10.x/clang/lib/AST/ExprConstant.cpp Fri May 22 15:42:45 2020 (r361386) +++ vendor/llvm-project/release-10.x/clang/lib/AST/ExprConstant.cpp Fri May 22 16:12:18 2020 (r361387) @@ -8593,6 +8593,10 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const static bool EvaluateArrayNewInitList(EvalInfo &Info, LValue &This, APValue &Result, const InitListExpr *ILE, QualType AllocType); +static bool EvaluateArrayNewConstructExpr(EvalInfo &Info, LValue &This, + APValue &Result, + const CXXConstructExpr *CCE, + QualType AllocType); bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) { if (!Info.getLangOpts().CPlusPlus2a) @@ -8642,6 +8646,7 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNe const Expr *Init = E->getInitializer(); const InitListExpr *ResizedArrayILE = nullptr; + const CXXConstructExpr *ResizedArrayCCE = nullptr; QualType AllocType = E->getAllocatedType(); if (Optional ArraySize = E->getArraySize()) { @@ -8685,7 +8690,7 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNe // -- the new-initializer is a braced-init-list and the number of // array elements for which initializers are provided [...] // exceeds the number of elements to initialize - if (Init) { + if (Init && !isa(Init)) { auto *CAT = Info.Ctx.getAsConstantArrayType(Init->getType()); assert(CAT && "unexpected type for array initializer"); @@ -8708,6 +8713,8 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNe // special handling for this case when we initialize. if (InitBound != AllocBound) ResizedArrayILE = cast(Init); + } else if (Init) { + ResizedArrayCCE = cast(Init); } AllocType = Info.Ctx.getConstantArrayType(AllocType, ArrayBound, nullptr, @@ -8772,6 +8779,10 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNe if (!EvaluateArrayNewInitList(Info, Result, *Val, ResizedArrayILE, AllocType)) return false; + } else if (ResizedArrayCCE) { + if (!EvaluateArrayNewConstructExpr(Info, Result, *Val, ResizedArrayCCE, + AllocType)) + return false; } else if (Init) { if (!EvaluateInPlace(*Val, Info, Result, Init)) return false; @@ -9595,6 +9606,16 @@ static bool EvaluateArrayNewInitList(EvalInfo &Info, L "not an array rvalue"); return ArrayExprEvaluator(Info, This, Result) .VisitInitListExpr(ILE, AllocType); +} + +static bool EvaluateArrayNewConstructExpr(EvalInfo &Info, LValue &This, + APValue &Result, + const CXXConstructExpr *CCE, + QualType AllocType) { + assert(CCE->isRValue() && CCE->getType()->isArrayType() && + "not an array rvalue"); + return ArrayExprEvaluator(Info, This, Result) + .VisitCXXConstructExpr(CCE, This, &Result, AllocType); } // Return true iff the given array filler may depend on the element index. Modified: vendor/llvm-project/release-10.x/clang/lib/AST/RawCommentList.cpp ============================================================================== --- vendor/llvm-project/release-10.x/clang/lib/AST/RawCommentList.cpp Fri May 22 15:42:45 2020 (r361386) +++ vendor/llvm-project/release-10.x/clang/lib/AST/RawCommentList.cpp Fri May 22 16:12:18 2020 (r361387) @@ -430,7 +430,7 @@ std::string RawComment::getFormattedText(const SourceM }; auto DropTrailingNewLines = [](std::string &Str) { - while (Str.back() == '\n') + while (!Str.empty() && Str.back() == '\n') Str.pop_back(); }; Modified: vendor/llvm-project/release-10.x/clang/lib/CodeGen/CGVTables.cpp ============================================================================== --- vendor/llvm-project/release-10.x/clang/lib/CodeGen/CGVTables.cpp Fri May 22 15:42:45 2020 (r361386) +++ vendor/llvm-project/release-10.x/clang/lib/CodeGen/CGVTables.cpp Fri May 22 16:12:18 2020 (r361387) @@ -437,7 +437,8 @@ void CodeGenFunction::EmitMustTailThunk(GlobalDecl GD, // Finish the function to maintain CodeGenFunction invariants. // FIXME: Don't emit unreachable code. EmitBlock(createBasicBlock()); - FinishFunction(); + + FinishThunk(); } void CodeGenFunction::generateThunk(llvm::Function *Fn, @@ -564,7 +565,7 @@ llvm::Constant *CodeGenVTables::maybeEmitThunk(GlobalD CGM.SetLLVMFunctionAttributesForDefinition(GD.getDecl(), ThunkFn); // Thunks for variadic methods are special because in general variadic - // arguments cannot be perferctly forwarded. In the general case, clang + // arguments cannot be perfectly forwarded. In the general case, clang // implements such thunks by cloning the original function body. However, for // thunks with no return adjustment on targets that support musttail, we can // use musttail to perfectly forward the variadic arguments. Modified: vendor/llvm-project/release-10.x/clang/lib/CodeGen/CodeGenModule.cpp ============================================================================== --- vendor/llvm-project/release-10.x/clang/lib/CodeGen/CodeGenModule.cpp Fri May 22 15:42:45 2020 (r361386) +++ vendor/llvm-project/release-10.x/clang/lib/CodeGen/CodeGenModule.cpp Fri May 22 16:12:18 2020 (r361387) @@ -1847,9 +1847,16 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl G else if (const auto *SA = FD->getAttr()) F->setSection(SA->getName()); + // If we plan on emitting this inline builtin, we can't treat it as a builtin. if (FD->isInlineBuiltinDeclaration()) { - F->addAttribute(llvm::AttributeList::FunctionIndex, - llvm::Attribute::NoBuiltin); + const FunctionDecl *FDBody; + bool HasBody = FD->hasBody(FDBody); + (void)HasBody; + assert(HasBody && "Inline builtin declarations should always have an " + "available body!"); + if (shouldEmitFunction(FDBody)) + F->addAttribute(llvm::AttributeList::FunctionIndex, + llvm::Attribute::NoBuiltin); } if (FD->isReplaceableGlobalAllocationFunction()) { Modified: vendor/llvm-project/release-10.x/clang/lib/Driver/ToolChains/Darwin.cpp ============================================================================== --- vendor/llvm-project/release-10.x/clang/lib/Driver/ToolChains/Darwin.cpp Fri May 22 15:42:45 2020 (r361386) +++ vendor/llvm-project/release-10.x/clang/lib/Driver/ToolChains/Darwin.cpp Fri May 22 16:12:18 2020 (r361387) @@ -1146,6 +1146,7 @@ void Darwin::addProfileRTLibs(const ArgList &Args, addExportedSymbol(CmdArgs, "___gcov_flush"); addExportedSymbol(CmdArgs, "_flush_fn_list"); addExportedSymbol(CmdArgs, "_writeout_fn_list"); + addExportedSymbol(CmdArgs, "_reset_fn_list"); } else { addExportedSymbol(CmdArgs, "___llvm_profile_filename"); addExportedSymbol(CmdArgs, "___llvm_profile_raw_version"); Modified: vendor/llvm-project/release-10.x/clang/lib/Driver/ToolChains/Gnu.cpp ============================================================================== --- vendor/llvm-project/release-10.x/clang/lib/Driver/ToolChains/Gnu.cpp Fri May 22 15:42:45 2020 (r361386) +++ vendor/llvm-project/release-10.x/clang/lib/Driver/ToolChains/Gnu.cpp Fri May 22 16:12:18 2020 (r361387) @@ -309,7 +309,7 @@ static const char *getLDMOption(const llvm::Triple &T, } } -static bool getPIE(const ArgList &Args, const toolchains::Linux &ToolChain) { +static bool getPIE(const ArgList &Args, const ToolChain &TC) { if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_static) || Args.hasArg(options::OPT_r) || Args.hasArg(options::OPT_static_pie)) return false; @@ -317,17 +317,16 @@ static bool getPIE(const ArgList &Args, const toolchai Arg *A = Args.getLastArg(options::OPT_pie, options::OPT_no_pie, options::OPT_nopie); if (!A) - return ToolChain.isPIEDefault(); + return TC.isPIEDefault(); return A->getOption().matches(options::OPT_pie); } -static bool getStaticPIE(const ArgList &Args, - const toolchains::Linux &ToolChain) { +static bool getStaticPIE(const ArgList &Args, const ToolChain &TC) { bool HasStaticPIE = Args.hasArg(options::OPT_static_pie); // -no-pie is an alias for -nopie. So, handling -nopie takes care of // -no-pie as well. if (HasStaticPIE && Args.hasArg(options::OPT_nopie)) { - const Driver &D = ToolChain.getDriver(); + const Driver &D = TC.getDriver(); const llvm::opt::OptTable &Opts = D.getOpts(); const char *StaticPIEName = Opts.getOptionName(options::OPT_static_pie); const char *NoPIEName = Opts.getOptionName(options::OPT_nopie); @@ -346,8 +345,12 @@ void tools::gnutools::Linker::ConstructJob(Compilation const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { - const toolchains::Linux &ToolChain = - static_cast(getToolChain()); + // FIXME: The Linker class constructor takes a ToolChain and not a + // Generic_ELF, so the static_cast might return a reference to a invalid + // instance (see PR45061). Ideally, the Linker constructor needs to take a + // Generic_ELF instead. + const toolchains::Generic_ELF &ToolChain = + static_cast(getToolChain()); const Driver &D = ToolChain.getDriver(); const llvm::Triple &Triple = getToolChain().getEffectiveTriple(); @@ -418,8 +421,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation if (isAndroid) CmdArgs.push_back("--warn-shared-textrel"); - for (const auto &Opt : ToolChain.ExtraOpts) - CmdArgs.push_back(Opt.c_str()); + ToolChain.addExtraOpts(CmdArgs); CmdArgs.push_back("--eh-frame-hdr"); Modified: vendor/llvm-project/release-10.x/clang/lib/Driver/ToolChains/Gnu.h ============================================================================== --- vendor/llvm-project/release-10.x/clang/lib/Driver/ToolChains/Gnu.h Fri May 22 15:42:45 2020 (r361386) +++ vendor/llvm-project/release-10.x/clang/lib/Driver/ToolChains/Gnu.h Fri May 22 16:12:18 2020 (r361387) @@ -356,6 +356,12 @@ class LLVM_LIBRARY_VISIBILITY Generic_ELF : public Gen void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, Action::OffloadKind DeviceOffloadKind) const override; + + virtual std::string getDynamicLinker(const llvm::opt::ArgList &Args) const { + return {}; + } + + virtual void addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const {} }; } // end namespace toolchains Modified: vendor/llvm-project/release-10.x/clang/lib/Driver/ToolChains/Hurd.cpp ============================================================================== --- vendor/llvm-project/release-10.x/clang/lib/Driver/ToolChains/Hurd.cpp Fri May 22 15:42:45 2020 (r361386) +++ vendor/llvm-project/release-10.x/clang/lib/Driver/ToolChains/Hurd.cpp Fri May 22 16:12:18 2020 (r361387) @@ -61,8 +61,7 @@ static StringRef getOSLibDir(const llvm::Triple &Tripl return Triple.isArch32Bit() ? "lib" : "lib64"; } -Hurd::Hurd(const Driver &D, const llvm::Triple &Triple, - const ArgList &Args) +Hurd::Hurd(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) : Generic_ELF(D, Triple, Args) { std::string SysRoot = computeSysRoot(); path_list &Paths = getFilePaths(); @@ -169,4 +168,9 @@ void Hurd::AddClangSystemIncludeArgs(const ArgList &Dr addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/include"); addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include"); +} + +void Hurd::addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const { + for (const auto &Opt : ExtraOpts) + CmdArgs.push_back(Opt.c_str()); } Modified: vendor/llvm-project/release-10.x/clang/lib/Driver/ToolChains/Hurd.h ============================================================================== --- vendor/llvm-project/release-10.x/clang/lib/Driver/ToolChains/Hurd.h Fri May 22 15:42:45 2020 (r361386) +++ vendor/llvm-project/release-10.x/clang/lib/Driver/ToolChains/Hurd.h Fri May 22 16:12:18 2020 (r361387) @@ -27,9 +27,11 @@ class LLVM_LIBRARY_VISIBILITY Hurd : public Generic_EL AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; - virtual std::string computeSysRoot() const; + std::string computeSysRoot() const; - virtual std::string getDynamicLinker(const llvm::opt::ArgList &Args) const; + std::string getDynamicLinker(const llvm::opt::ArgList &Args) const override; + + void addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const override; std::vector ExtraOpts; Modified: vendor/llvm-project/release-10.x/clang/lib/Driver/ToolChains/Linux.cpp ============================================================================== --- vendor/llvm-project/release-10.x/clang/lib/Driver/ToolChains/Linux.cpp Fri May 22 15:42:45 2020 (r361386) +++ vendor/llvm-project/release-10.x/clang/lib/Driver/ToolChains/Linux.cpp Fri May 22 16:12:18 2020 (r361387) @@ -986,3 +986,8 @@ void Linux::addProfileRTLibs(const llvm::opt::ArgList Twine("-u", llvm::getInstrProfRuntimeHookVarName()))); ToolChain::addProfileRTLibs(Args, CmdArgs); } + +void Linux::addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const { + for (const auto &Opt : ExtraOpts) + CmdArgs.push_back(Opt.c_str()); +} Modified: vendor/llvm-project/release-10.x/clang/lib/Driver/ToolChains/Linux.h ============================================================================== --- vendor/llvm-project/release-10.x/clang/lib/Driver/ToolChains/Linux.h Fri May 22 15:42:45 2020 (r361386) +++ vendor/llvm-project/release-10.x/clang/lib/Driver/ToolChains/Linux.h Fri May 22 16:12:18 2020 (r361387) @@ -42,7 +42,9 @@ class LLVM_LIBRARY_VISIBILITY Linux : public Generic_E llvm::opt::ArgStringList &CmdArgs) const override; virtual std::string computeSysRoot() const; - virtual std::string getDynamicLinker(const llvm::opt::ArgList &Args) const; + std::string getDynamicLinker(const llvm::opt::ArgList &Args) const override; + + void addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const override; std::vector ExtraOpts; Modified: vendor/llvm-project/release-10.x/clang/lib/Format/TokenAnnotator.cpp ============================================================================== --- vendor/llvm-project/release-10.x/clang/lib/Format/TokenAnnotator.cpp Fri May 22 15:42:45 2020 (r361386) +++ vendor/llvm-project/release-10.x/clang/lib/Format/TokenAnnotator.cpp Fri May 22 16:12:18 2020 (r361387) @@ -2176,6 +2176,10 @@ static bool isFunctionDeclarationName(const FormatToke Next = Next->Next; continue; } + if (Next->is(TT_TemplateOpener) && Next->MatchingParen) { + Next = Next->MatchingParen; + continue; + } break; } @@ -2705,20 +2709,40 @@ bool TokenAnnotator::spaceRequiredBetween(const Annota tok::l_square)); if (Right.is(tok::star) && Left.is(tok::l_paren)) return false; - if (Right.isOneOf(tok::star, tok::amp, tok::ampamp) && - (Left.is(tok::identifier) || Left.isSimpleTypeSpecifier()) && - // Space between the type and the * in: - // operator void*() - // operator char*() - // operator /*comment*/ const char*() - // operator volatile /*comment*/ char*() - // operator Foo*() - // dependent on PointerAlignment style. - Left.Previous && - (Left.Previous->endsSequence(tok::kw_operator) || - Left.Previous->endsSequence(tok::kw_const, tok::kw_operator) || - Left.Previous->endsSequence(tok::kw_volatile, tok::kw_operator))) - return (Style.PointerAlignment != FormatStyle::PAS_Left); + if (Right.is(tok::star) && Left.is(tok::star)) + return false; + if (Right.isOneOf(tok::star, tok::amp, tok::ampamp)) { + const FormatToken *Previous = &Left; + while (Previous && !Previous->is(tok::kw_operator)) { + if (Previous->is(tok::identifier) || Previous->isSimpleTypeSpecifier()) { + Previous = Previous->getPreviousNonComment(); + continue; + } + if (Previous->is(TT_TemplateCloser) && Previous->MatchingParen) { + Previous = Previous->MatchingParen->getPreviousNonComment(); + continue; + } + if (Previous->is(tok::coloncolon)) { + Previous = Previous->getPreviousNonComment(); + continue; + } + break; + } + // Space between the type and the * in: + // operator void*() + // operator char*() + // operator /*comment*/ const char*() + // operator volatile /*comment*/ char*() + // operator Foo*() + // operator C*() + // operator std::Foo*() + // operator C::D*() + // dependent on PointerAlignment style. + if (Previous && (Previous->endsSequence(tok::kw_operator) || + Previous->endsSequence(tok::kw_const, tok::kw_operator) || + Previous->endsSequence(tok::kw_volatile, tok::kw_operator))) + return (Style.PointerAlignment != FormatStyle::PAS_Left); + } const auto SpaceRequiredForArrayInitializerLSquare = [](const FormatToken &LSquareTok, const FormatStyle &Style) { return Style.SpacesInContainerLiterals || Modified: vendor/llvm-project/release-10.x/clang/lib/Sema/SemaTemplateInstantiate.cpp ============================================================================== --- vendor/llvm-project/release-10.x/clang/lib/Sema/SemaTemplateInstantiate.cpp Fri May 22 15:42:45 2020 (r361386) +++ vendor/llvm-project/release-10.x/clang/lib/Sema/SemaTemplateInstantiate.cpp Fri May 22 16:12:18 2020 (r361387) @@ -2343,7 +2343,7 @@ ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldPa UnparsedDefaultArgInstantiations[OldParm].push_back(NewParm); } else if (Expr *Arg = OldParm->getDefaultArg()) { FunctionDecl *OwningFunc = cast(OldParm->getDeclContext()); - if (OwningFunc->isLexicallyWithinFunctionOrMethod()) { + if (OwningFunc->isInLocalScope()) { // Instantiate default arguments for methods of local classes (DR1484) // and non-defining declarations. Sema::ContextRAII SavedContext(*this, OwningFunc); Modified: vendor/llvm-project/release-10.x/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp ============================================================================== --- vendor/llvm-project/release-10.x/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp Fri May 22 15:42:45 2020 (r361386) +++ vendor/llvm-project/release-10.x/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp Fri May 22 16:12:18 2020 (r361387) @@ -4367,7 +4367,7 @@ TemplateDeclInstantiator::InitFunctionInstantiation(Fu EPI.ExceptionSpec.Type != EST_None && EPI.ExceptionSpec.Type != EST_DynamicNone && EPI.ExceptionSpec.Type != EST_BasicNoexcept && - !Tmpl->isLexicallyWithinFunctionOrMethod()) { + !Tmpl->isInLocalScope()) { FunctionDecl *ExceptionSpecTemplate = Tmpl; if (EPI.ExceptionSpec.Type == EST_Uninstantiated) ExceptionSpecTemplate = EPI.ExceptionSpec.SourceTemplate; Modified: vendor/llvm-project/release-10.x/clang/lib/Sema/TreeTransform.h ============================================================================== --- vendor/llvm-project/release-10.x/clang/lib/Sema/TreeTransform.h Fri May 22 15:42:45 2020 (r361386) +++ vendor/llvm-project/release-10.x/clang/lib/Sema/TreeTransform.h Fri May 22 16:12:18 2020 (r361387) @@ -4022,50 +4022,8 @@ template void TreeTransform::InventTemplateArgumentLoc( const TemplateArgument &Arg, TemplateArgumentLoc &Output) { - SourceLocation Loc = getDerived().getBaseLocation(); - switch (Arg.getKind()) { - case TemplateArgument::Null: - llvm_unreachable("null template argument in TreeTransform"); - break; - - case TemplateArgument::Type: - Output = TemplateArgumentLoc(Arg, - SemaRef.Context.getTrivialTypeSourceInfo(Arg.getAsType(), Loc)); - - break; - - case TemplateArgument::Template: - case TemplateArgument::TemplateExpansion: { - NestedNameSpecifierLocBuilder Builder; - TemplateName Template = Arg.getAsTemplateOrTemplatePattern(); - if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) - Builder.MakeTrivial(SemaRef.Context, DTN->getQualifier(), Loc); - else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName()) - Builder.MakeTrivial(SemaRef.Context, QTN->getQualifier(), Loc); - - if (Arg.getKind() == TemplateArgument::Template) - Output = TemplateArgumentLoc(Arg, - Builder.getWithLocInContext(SemaRef.Context), - Loc); - else - Output = TemplateArgumentLoc(Arg, - Builder.getWithLocInContext(SemaRef.Context), - Loc, Loc); - - break; - } - - case TemplateArgument::Expression: - Output = TemplateArgumentLoc(Arg, Arg.getAsExpr()); - break; - - case TemplateArgument::Declaration: - case TemplateArgument::Integral: - case TemplateArgument::Pack: - case TemplateArgument::NullPtr: - Output = TemplateArgumentLoc(Arg, TemplateArgumentLocInfo()); - break; - } + Output = getSema().getTrivialTemplateArgumentLoc( + Arg, QualType(), getDerived().getBaseLocation()); } template @@ -4075,12 +4033,45 @@ bool TreeTransform::TransformTemplateArgument const TemplateArgument &Arg = Input.getArgument(); switch (Arg.getKind()) { case TemplateArgument::Null: - case TemplateArgument::Integral: case TemplateArgument::Pack: - case TemplateArgument::Declaration: - case TemplateArgument::NullPtr: llvm_unreachable("Unexpected TemplateArgument"); + case TemplateArgument::Integral: + case TemplateArgument::NullPtr: + case TemplateArgument::Declaration: { + // Transform a resolved template argument straight to a resolved template + // argument. We get here when substituting into an already-substituted + // template type argument during concept satisfaction checking. + QualType T = Arg.getNonTypeTemplateArgumentType(); + QualType NewT = getDerived().TransformType(T); + if (NewT.isNull()) + return true; + + ValueDecl *D = Arg.getKind() == TemplateArgument::Declaration + ? Arg.getAsDecl() + : nullptr; + ValueDecl *NewD = D ? cast_or_null(getDerived().TransformDecl( + getDerived().getBaseLocation(), D)) + : nullptr; + if (D && !NewD) + return true; + + if (NewT == T && D == NewD) + Output = Input; + else if (Arg.getKind() == TemplateArgument::Integral) + Output = TemplateArgumentLoc( + TemplateArgument(getSema().Context, Arg.getAsIntegral(), NewT), + TemplateArgumentLocInfo()); + else if (Arg.getKind() == TemplateArgument::NullPtr) + Output = TemplateArgumentLoc(TemplateArgument(NewT, /*IsNullPtr=*/true), + TemplateArgumentLocInfo()); + else + Output = TemplateArgumentLoc(TemplateArgument(NewD, NewT), + TemplateArgumentLocInfo()); + + return false; + } + case TemplateArgument::Type: { TypeSourceInfo *DI = Input.getTypeSourceInfo(); if (!DI) @@ -11836,19 +11827,6 @@ TreeTransform::TransformLambdaExpr(LambdaExpr NewTrailingRequiresClause.get()); LSI->CallOperator = NewCallOperator; - - for (unsigned I = 0, NumParams = NewCallOperator->getNumParams(); - I != NumParams; ++I) { - auto *P = NewCallOperator->getParamDecl(I); - if (P->hasUninstantiatedDefaultArg()) { - EnterExpressionEvaluationContext Eval( - getSema(), - Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed, P); - ExprResult R = getDerived().TransformExpr( - E->getCallOperator()->getParamDecl(I)->getDefaultArg()); - P->setDefaultArg(R.get()); - } - } getDerived().transformAttrs(E->getCallOperator(), NewCallOperator); getDerived().transformedLocalDecl(E->getCallOperator(), {NewCallOperator}); Modified: vendor/llvm-project/release-10.x/compiler-rt/lib/profile/GCDAProfiling.c ============================================================================== --- vendor/llvm-project/release-10.x/compiler-rt/lib/profile/GCDAProfiling.c Fri May 22 15:42:45 2020 (r361386) +++ vendor/llvm-project/release-10.x/compiler-rt/lib/profile/GCDAProfiling.c Fri May 22 16:12:18 2020 (r361387) @@ -32,8 +32,10 @@ #include #include "WindowsMMap.h" #else -#include #include +#include +#include +#include #endif #if defined(__FreeBSD__) && defined(__i386__) @@ -119,6 +121,11 @@ struct fn_list writeout_fn_list; */ struct fn_list flush_fn_list; +/* + * A list of reset functions, shared between all dynamic objects. + */ +struct fn_list reset_fn_list; + static void fn_list_insert(struct fn_list* list, fn_ptr fn) { struct fn_node* new_node = malloc(sizeof(struct fn_node)); new_node->fn = fn; @@ -634,7 +641,46 @@ void llvm_delete_flush_function_list(void) { } COMPILER_RT_VISIBILITY -void llvm_gcov_init(fn_ptr wfn, fn_ptr ffn) { +void llvm_register_reset_function(fn_ptr fn) { + fn_list_insert(&reset_fn_list, fn); +} + +COMPILER_RT_VISIBILITY +void llvm_delete_reset_function_list(void) { fn_list_remove(&reset_fn_list); } + +COMPILER_RT_VISIBILITY +void llvm_reset_counters(void) { + struct fn_node *curr = reset_fn_list.head; + + while (curr) { + if (curr->id == CURRENT_ID) { + curr->fn(); + } + curr = curr->next; + } +} + +#if !defined(_WIN32) +COMPILER_RT_VISIBILITY +pid_t __gcov_fork() { + pid_t parent_pid = getpid(); + pid_t pid = fork(); + + if (pid == 0) { + pid_t child_pid = getpid(); + if (child_pid != parent_pid) { + // The pid changed so we've a fork (one could have its own fork function) + // Just reset the counters for this child process + // threads. + llvm_reset_counters(); + } + } + return pid; +} +#endif + +COMPILER_RT_VISIBILITY +void llvm_gcov_init(fn_ptr wfn, fn_ptr ffn, fn_ptr rfn) { static int atexit_ran = 0; if (wfn) @@ -643,10 +689,14 @@ void llvm_gcov_init(fn_ptr wfn, fn_ptr ffn) { if (ffn) llvm_register_flush_function(ffn); + if (rfn) + llvm_register_reset_function(rfn); + if (atexit_ran == 0) { atexit_ran = 1; /* Make sure we write out the data and delete the data structures. */ + atexit(llvm_delete_reset_function_list); atexit(llvm_delete_flush_function_list); atexit(llvm_delete_writeout_function_list); atexit(llvm_writeout_files); Modified: vendor/llvm-project/release-10.x/lld/COFF/MarkLive.cpp ============================================================================== --- vendor/llvm-project/release-10.x/lld/COFF/MarkLive.cpp Fri May 22 15:42:45 2020 (r361386) +++ vendor/llvm-project/release-10.x/lld/COFF/MarkLive.cpp Fri May 22 16:12:18 2020 (r361387) @@ -28,10 +28,12 @@ void markLive(ArrayRef chunks) { // as we push, so sections never appear twice in the list. SmallVector worklist; - // COMDAT section chunks are dead by default. Add non-COMDAT chunks. + // COMDAT section chunks are dead by default. Add non-COMDAT chunks. Do not + // traverse DWARF sections. They are live, but they should not keep other + // sections alive. for (Chunk *c : chunks) if (auto *sc = dyn_cast(c)) - if (sc->live) + if (sc->live && !sc->isDWARF()) worklist.push_back(sc); auto enqueue = [&](SectionChunk *c) { Modified: vendor/llvm-project/release-10.x/lld/ELF/Driver.cpp ============================================================================== --- vendor/llvm-project/release-10.x/lld/ELF/Driver.cpp Fri May 22 15:42:45 2020 (r361386) +++ vendor/llvm-project/release-10.x/lld/ELF/Driver.cpp Fri May 22 16:12:18 2020 (r361387) @@ -1906,8 +1906,17 @@ template void LinkerDriver::link(opt::Inp // We do not want to emit debug sections if --strip-all // or -strip-debug are given. - return config->strip != StripPolicy::None && - (s->name.startswith(".debug") || s->name.startswith(".zdebug")); + if (config->strip == StripPolicy::None) + return false; + + if (isDebugSection(*s)) + return true; + if (auto *isec = dyn_cast(s)) + if (InputSectionBase *rel = isec->getRelocatedSection()) + if (isDebugSection(*rel)) + return true; + + return false; }); // Now that the number of partitions is fixed, save a pointer to the main Modified: vendor/llvm-project/release-10.x/lld/ELF/InputSection.cpp ============================================================================== --- vendor/llvm-project/release-10.x/lld/ELF/InputSection.cpp Fri May 22 15:42:45 2020 (r361386) +++ vendor/llvm-project/release-10.x/lld/ELF/InputSection.cpp Fri May 22 16:12:18 2020 (r361387) @@ -441,8 +441,7 @@ void InputSection::copyRelocations(uint8_t *buf, Array // See the comment in maybeReportUndefined for PPC64 .toc . auto *d = dyn_cast(&sym); if (!d) { - if (!sec->name.startswith(".debug") && - !sec->name.startswith(".zdebug") && sec->name != ".eh_frame" && + if (!isDebugSection(*sec) && sec->name != ".eh_frame" && sec->name != ".gcc_except_table" && sec->name != ".toc") { uint32_t secIdx = cast(sym).discardedSecIdx; Elf_Shdr_Impl sec = Modified: vendor/llvm-project/release-10.x/lld/ELF/InputSection.h ============================================================================== --- vendor/llvm-project/release-10.x/lld/ELF/InputSection.h Fri May 22 15:42:45 2020 (r361386) +++ vendor/llvm-project/release-10.x/lld/ELF/InputSection.h Fri May 22 16:12:18 2020 (r361387) @@ -357,6 +357,10 @@ class InputSection : public InputSectionBase { (privat template void copyShtGroup(uint8_t *buf); }; +inline bool isDebugSection(const InputSectionBase &sec) { + return sec.name.startswith(".debug") || sec.name.startswith(".zdebug"); +} + // The list of all input sections. extern std::vector inputSections; Modified: vendor/llvm-project/release-10.x/lld/ELF/OutputSections.cpp ============================================================================== --- vendor/llvm-project/release-10.x/lld/ELF/OutputSections.cpp Fri May 22 15:42:45 2020 (r361386) +++ vendor/llvm-project/release-10.x/lld/ELF/OutputSections.cpp Fri May 22 16:12:18 2020 (r361387) @@ -114,8 +114,7 @@ void OutputSection::commitSection(InputSection *isec) flags = isec->flags; } else { // Otherwise, check if new type or flags are compatible with existing ones. - unsigned mask = SHF_TLS | SHF_LINK_ORDER; - if ((flags & mask) != (isec->flags & mask)) + if ((flags ^ isec->flags) & SHF_TLS) error("incompatible section flags for " + name + "\n>>> " + toString(isec) + ": 0x" + utohexstr(isec->flags) + "\n>>> output section " + name + ": 0x" + utohexstr(flags)); @@ -367,8 +366,9 @@ void OutputSection::finalize() { // all InputSections in the OutputSection have the same dependency. if (auto *ex = dyn_cast(first)) link = ex->getLinkOrderDep()->getParent()->sectionIndex; - else if (auto *d = first->getLinkOrderDep()) - link = d->getParent()->sectionIndex; + else if (first->flags & SHF_LINK_ORDER) + if (auto *d = first->getLinkOrderDep()) + link = d->getParent()->sectionIndex; } if (type == SHT_GROUP) { Modified: vendor/llvm-project/release-10.x/lld/ELF/Writer.cpp ============================================================================== --- vendor/llvm-project/release-10.x/lld/ELF/Writer.cpp Fri May 22 15:42:45 2020 (r361386) +++ vendor/llvm-project/release-10.x/lld/ELF/Writer.cpp Fri May 22 16:12:18 2020 (r361387) @@ -1523,17 +1523,30 @@ template void Writer::resolveShfLin // but sort must consider them all at once. std::vector scriptSections; std::vector sections; + bool started = false, stopped = false; for (BaseCommand *base : sec->sectionCommands) { if (auto *isd = dyn_cast(base)) { for (InputSection *&isec : isd->sections) { - scriptSections.push_back(&isec); - sections.push_back(isec); + if (!(isec->flags & SHF_LINK_ORDER)) { + if (started) + stopped = true; + } else if (stopped) { + error(toString(isec) + ": SHF_LINK_ORDER sections in " + sec->name + + " are not contiguous"); + } else { + started = true; - InputSection *link = isec->getLinkOrderDep(); - if (!link->getParent()) - error(toString(isec) + ": sh_link points to discarded section " + - toString(link)); + scriptSections.push_back(&isec); + sections.push_back(isec); + + InputSection *link = isec->getLinkOrderDep(); + if (!link->getParent()) + error(toString(isec) + ": sh_link points to discarded section " + + toString(link)); + } } + } else if (started) { + stopped = true; } } Modified: vendor/llvm-project/release-10.x/llvm/include/llvm/Analysis/ValueLattice.h ============================================================================== --- vendor/llvm-project/release-10.x/llvm/include/llvm/Analysis/ValueLattice.h Fri May 22 15:42:45 2020 (r361386) +++ vendor/llvm-project/release-10.x/llvm/include/llvm/Analysis/ValueLattice.h Fri May 22 16:12:18 2020 (r361387) @@ -29,7 +29,7 @@ class ValueLatticeElement { /// producing instruction is dead. Caution: We use this as the starting /// state in our local meet rules. In this usage, it's taken to mean /// "nothing known yet". - undefined, + unknown, /// This Value has a specific constant value. (For constant integers, /// constantrange is used instead. Integer typed constantexprs can appear @@ -45,7 +45,12 @@ class ValueLatticeElement { constantrange, /// We can not precisely model the dynamic values this value might take. - overdefined + overdefined, + + /// This Value is an UndefValue constant or produces undef. Undefined values + /// can be merged with constants (or single element constant ranges), + /// assuming all uses of the result will be replaced. + undef }; ValueLatticeElementTy Tag; @@ -60,14 +65,15 @@ class ValueLatticeElement { public: // Const and Range are initialized on-demand. - ValueLatticeElement() : Tag(undefined) {} + ValueLatticeElement() : Tag(unknown) {} /// Custom destructor to ensure Range is properly destroyed, when the object /// is deallocated. ~ValueLatticeElement() { switch (Tag) { case overdefined: - case undefined: + case unknown: + case undef: case constant: case notconstant: break; @@ -79,7 +85,7 @@ class ValueLatticeElement { /// Custom copy constructor, to ensure Range gets initialized when /// copying a constant range lattice element. - ValueLatticeElement(const ValueLatticeElement &Other) : Tag(undefined) { + ValueLatticeElement(const ValueLatticeElement &Other) : Tag(unknown) { *this = Other; } @@ -109,7 +115,8 @@ class ValueLatticeElement { ConstVal = Other.ConstVal; break; case overdefined: - case undefined: + case unknown: + case undef: break; } Tag = Other.Tag; @@ -118,14 +125,16 @@ class ValueLatticeElement { static ValueLatticeElement get(Constant *C) { ValueLatticeElement Res; - if (!isa(C)) + if (isa(C)) + Res.markUndef(); + else Res.markConstant(C); return Res; } static ValueLatticeElement getNot(Constant *C) { ValueLatticeElement Res; - if (!isa(C)) - Res.markNotConstant(C); + assert(!isa(C) && "!= undef is not supported"); + Res.markNotConstant(C); return Res; } static ValueLatticeElement getRange(ConstantRange CR) { @@ -139,7 +148,10 @@ class ValueLatticeElement { return Res; } - bool isUndefined() const { return Tag == undefined; } + bool isUndef() const { return Tag == undef; } + bool isUnknown() const { return Tag == unknown; } + bool isUnknownOrUndef() const { return Tag == unknown || Tag == undef; } + bool isUndefined() const { return isUnknownOrUndef(); } bool isConstant() const { return Tag == constant; } bool isNotConstant() const { return Tag == notconstant; } bool isConstantRange() const { return Tag == constantrange; } @@ -170,89 +182,123 @@ class ValueLatticeElement { return None; } -private: - void markOverdefined() { + bool markOverdefined() { if (isOverdefined()) - return; + return false; if (isConstant() || isNotConstant()) ConstVal = nullptr; if (isConstantRange()) Range.~ConstantRange(); Tag = overdefined; + return true; } - void markConstant(Constant *V) { - assert(V && "Marking constant with NULL"); - if (ConstantInt *CI = dyn_cast(V)) { - markConstantRange(ConstantRange(CI->getValue())); - return; - } + bool markUndef() { + if (isUndef()) + return false; + + assert(isUnknown()); + Tag = undef; + return true; + } + + bool markConstant(Constant *V) { if (isa(V)) - return; + return markUndef(); - assert((!isConstant() || getConstant() == V) && - "Marking constant with different value"); - assert(isUndefined()); + if (isConstant()) { + assert(getConstant() == V && "Marking constant with different value"); + return false; + } + + if (ConstantInt *CI = dyn_cast(V)) + return markConstantRange(ConstantRange(CI->getValue())); + + assert(isUnknown() || isUndef()); Tag = constant; ConstVal = V; + return true; } - void markNotConstant(Constant *V) { + bool markNotConstant(Constant *V) { assert(V && "Marking constant with NULL"); - if (ConstantInt *CI = dyn_cast(V)) { - markConstantRange(ConstantRange(CI->getValue() + 1, CI->getValue())); - return; - } + if (ConstantInt *CI = dyn_cast(V)) + return markConstantRange( + ConstantRange(CI->getValue() + 1, CI->getValue())); + if (isa(V)) - return; + return false; - assert((!isConstant() || getConstant() != V) && - "Marking constant !constant with same value"); - assert((!isNotConstant() || getNotConstant() == V) && - "Marking !constant with different value"); - assert(isUndefined() || isConstant()); + if (isNotConstant()) { + assert(getNotConstant() == V && "Marking !constant with different value"); + return false; + } + + assert(isUnknown()); Tag = notconstant; ConstVal = V; + return true; } - void markConstantRange(ConstantRange NewR) { + /// Mark the object as constant range with \p NewR. If the object is already a + /// constant range, nothing changes if the existing range is equal to \p + /// NewR. Otherwise \p NewR must be a superset of the existing range or the + /// object must be undef. + bool markConstantRange(ConstantRange NewR) { if (isConstantRange()) { + if (getConstantRange() == NewR) + return false; + if (NewR.isEmptySet()) - markOverdefined(); - else { - Range = std::move(NewR); - } - return; + return markOverdefined(); + + assert(NewR.contains(getConstantRange()) && + "Existing range must be a subset of NewR"); + Range = std::move(NewR); + return true; } - assert(isUndefined()); + assert(isUnknown() || isUndef()); if (NewR.isEmptySet()) - markOverdefined(); - else { - Tag = constantrange; - new (&Range) ConstantRange(std::move(NewR)); - } + return markOverdefined(); + + Tag = constantrange; + new (&Range) ConstantRange(std::move(NewR)); + return true; } -public: /// Updates this object to approximate both this object and RHS. Returns /// true if this object has been changed. bool mergeIn(const ValueLatticeElement &RHS, const DataLayout &DL) { - if (RHS.isUndefined() || isOverdefined()) + if (RHS.isUnknown() || isOverdefined()) return false; if (RHS.isOverdefined()) { markOverdefined(); return true; } - if (isUndefined()) { + if (isUndef()) { + assert(!RHS.isUnknown()); + if (RHS.isUndef()) + return false; + if (RHS.isConstant()) + return markConstant(RHS.getConstant()); + if (RHS.isConstantRange() && RHS.getConstantRange().isSingleElement()) + return markConstantRange(RHS.getConstantRange()); + return markOverdefined(); + } + + if (isUnknown()) { + assert(!RHS.isUnknown() && "Unknow RHS should be handled earlier"); *this = RHS; - return !RHS.isUndefined(); + return true; } if (isConstant()) { if (RHS.isConstant() && getConstant() == RHS.getConstant()) return false; *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***