Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 22 May 2020 16:12:18 +0000 (UTC)
From:      Dimitry Andric <dim@FreeBSD.org>
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...
Message-ID:  <202005221612.04MGCIp8087516@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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<TargetArch<["aarch64", "x86", "x86_64"]>> {
+      TargetSpecificAttr<TargetArch<["aarch64", "aarch64_be", "x86", "x86_64"]>> {
   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<TagDecl>(LDC))
       return false;
+    if (const auto *CRD = dyn_cast<CXXRecordDecl>(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<const Expr*> 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<CXXConstructExpr>(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<InitListExpr>(Init);
+      } else if (Init) {
+        ResizedArrayCCE = cast<CXXConstructExpr>(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<SectionAttr>())
      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<const toolchains::Linux &>(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<const toolchains::Generic_ELF &>(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<std::string> 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<std::string> 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<T>*()
+    //   operator std::Foo*()
+    //   operator C<T>::D<U>*()
+    // 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<FunctionDecl>(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<typename Derived>
 void TreeTransform<Derived>::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<typename Derived>
@@ -4075,12 +4033,45 @@ bool TreeTransform<Derived>::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<ValueDecl>(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<Derived>::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 <windows.h>
 #include "WindowsMMap.h"
 #else
-#include <sys/mman.h>
 #include <sys/file.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <unistd.h>
 #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<Chunk *> chunks) {
   // as we push, so sections never appear twice in the list.
   SmallVector<SectionChunk *, 256> 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<SectionChunk>(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 <class ELFT> 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<InputSection>(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<Defined>(&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<Undefined>(sym).discardedSecIdx;
           Elf_Shdr_Impl<ELFT> 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 <class ELFT> 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<InputSectionBase *> 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<ARMExidxSyntheticSection>(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 <class ELFT> void Writer<ELFT>::resolveShfLin
     // but sort must consider them all at once.
     std::vector<InputSection **> scriptSections;
     std::vector<InputSection *> sections;
+    bool started = false, stopped = false;
     for (BaseCommand *base : sec->sectionCommands) {
       if (auto *isd = dyn_cast<InputSectionDescription>(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<UndefValue>(C))
+    if (isa<UndefValue>(C))
+      Res.markUndef();
+    else
       Res.markConstant(C);
     return Res;
   }
   static ValueLatticeElement getNot(Constant *C) {
     ValueLatticeElement Res;
-    if (!isa<UndefValue>(C))
-      Res.markNotConstant(C);
+    assert(!isa<UndefValue>(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<ConstantInt>(V)) {
-      markConstantRange(ConstantRange(CI->getValue()));
-      return;
-    }
+  bool markUndef() {
+    if (isUndef())
+      return false;
+
+    assert(isUnknown());
+    Tag = undef;
+    return true;
+  }
+
+  bool markConstant(Constant *V) {
     if (isa<UndefValue>(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<ConstantInt>(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<ConstantInt>(V)) {
-      markConstantRange(ConstantRange(CI->getValue() + 1, CI->getValue()));
-      return;
-    }
+    if (ConstantInt *CI = dyn_cast<ConstantInt>(V))
+      return markConstantRange(
+          ConstantRange(CI->getValue() + 1, CI->getValue()));
+
     if (isa<UndefValue>(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 ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202005221612.04MGCIp8087516>