aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-09-11 18:37:24 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-12-08 17:35:11 +0000
commit8a4dda33d67586ca2624f2a38417baa03a533a7f (patch)
treeea87f69d4341b5a653c3747ebbdbedd7b41da233 /contrib/llvm-project/clang
parent06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e (diff)
parent8092e001bcd76c0b9fec2311f3a515aa60d2ed07 (diff)
downloadsrc-8a4dda33d67586ca2624f2a38417baa03a533a7f.tar.gz
src-8a4dda33d67586ca2624f2a38417baa03a533a7f.zip
Merge llvm-project release/17.x llvmorg-17.0.0-rc4-10-g0176e8729ea4
This updates llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp to llvmorg-17.0.0-rc4-10-g0176e8729ea4. PR: 273753 MFC after: 1 month
Diffstat (limited to 'contrib/llvm-project/clang')
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/DeclBase.h6
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ExprConcepts.h14
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.def1
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DiagnosticASTKinds.td2
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DiagnosticGroups.td1
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DiagnosticLexKinds.td4
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/Sanitizers.h4
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/TargetInfo.h4
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/riscv_vector.td52
-rw-r--r--contrib/llvm-project/clang/include/clang/CodeGen/CGFunctionInfo.h29
-rw-r--r--contrib/llvm-project/clang/include/clang/Driver/Options.td14
-rw-r--r--contrib/llvm-project/clang/include/clang/Driver/ToolChain.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/Sema/Sema.h2
-rw-r--r--contrib/llvm-project/clang/lib/AST/ASTContext.cpp5
-rw-r--r--contrib/llvm-project/clang/lib/AST/ExprConstant.cpp27
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/LoongArch.cpp21
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/LoongArch.h13
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/RISCV.cpp4
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/ABIInfoImpl.cpp13
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/ABIInfoImpl.h14
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/BackendUtil.cpp23
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CGCXXABI.cpp3
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CGCall.cpp244
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CGCall.h29
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CGClass.cpp106
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CGCoroutine.cpp33
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CGDebugInfo.cpp13
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CGDebugInfo.h2
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CGDecl.cpp2
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CGDeclCXX.cpp4
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CGExpr.cpp9
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CGExprConstant.cpp2
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntime.cpp11
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CodeGenABITypes.cpp5
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp26
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.h19
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp34
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.h20
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CodeGenTypes.h12
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/ItaniumCXXABI.cpp2
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/MicrosoftCXXABI.cpp3
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/Targets/LoongArch.cpp11
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/Targets/RISCV.cpp24
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/Targets/X86.cpp16
-rw-r--r--contrib/llvm-project/clang/lib/Driver/Driver.cpp17
-rw-r--r--contrib/llvm-project/clang/lib/Driver/SanitizerArgs.cpp32
-rw-r--r--contrib/llvm-project/clang/lib/Driver/ToolChain.cpp6
-rw-r--r--contrib/llvm-project/clang/lib/Driver/ToolChains/AIX.cpp6
-rw-r--r--contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp43
-rw-r--r--contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/LoongArch.h6
-rw-r--r--contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/X86.cpp6
-rw-r--r--contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp39
-rw-r--r--contrib/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.cpp9
-rw-r--r--contrib/llvm-project/clang/lib/Driver/ToolChains/Gnu.cpp22
-rw-r--r--contrib/llvm-project/clang/lib/Driver/ToolChains/Hexagon.cpp5
-rw-r--r--contrib/llvm-project/clang/lib/Driver/ToolChains/Solaris.cpp41
-rw-r--r--contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp5
-rw-r--r--contrib/llvm-project/clang/lib/Frontend/FrontendAction.cpp5
-rw-r--r--contrib/llvm-project/clang/lib/Headers/__clang_cuda_math.h2
-rw-r--r--contrib/llvm-project/clang/lib/Headers/__clang_hip_libdevice_declares.h2
-rw-r--r--contrib/llvm-project/clang/lib/Headers/cpuid.h10
-rw-r--r--contrib/llvm-project/clang/lib/Interpreter/IncrementalExecutor.cpp19
-rw-r--r--contrib/llvm-project/clang/lib/Lex/LiteralSupport.cpp41
-rw-r--r--contrib/llvm-project/clang/lib/Parse/ParseDeclCXX.cpp19
-rw-r--r--contrib/llvm-project/clang/lib/Parse/ParseTentative.cpp1
-rw-r--r--contrib/llvm-project/clang/lib/Sema/SemaAvailability.cpp12
-rw-r--r--contrib/llvm-project/clang/lib/Sema/SemaCast.cpp8
-rw-r--r--contrib/llvm-project/clang/lib/Sema/SemaDecl.cpp3
-rw-r--r--contrib/llvm-project/clang/lib/Sema/SemaExpr.cpp95
-rw-r--r--contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp25
-rw-r--r--contrib/llvm-project/clang/lib/Sema/SemaLookup.cpp68
-rw-r--r--contrib/llvm-project/clang/lib/Sema/SemaTemplateInstantiate.cpp17
-rw-r--r--contrib/llvm-project/clang/lib/Sema/TreeTransform.h4
-rw-r--r--contrib/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp66
-rw-r--r--contrib/llvm-project/clang/lib/Serialization/ASTWriterDecl.cpp4
-rw-r--r--contrib/llvm-project/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc54
76 files changed, 1048 insertions, 529 deletions
diff --git a/contrib/llvm-project/clang/include/clang/AST/DeclBase.h b/contrib/llvm-project/clang/include/clang/AST/DeclBase.h
index 1b99709ca90d..12137387b676 100644
--- a/contrib/llvm-project/clang/include/clang/AST/DeclBase.h
+++ b/contrib/llvm-project/clang/include/clang/AST/DeclBase.h
@@ -1702,7 +1702,7 @@ class DeclContext {
};
/// Number of non-inherited bits in FunctionDeclBitfields.
- enum { NumFunctionDeclBits = 30 };
+ enum { NumFunctionDeclBits = 31 };
/// Stores the bits used by CXXConstructorDecl. If modified
/// NumCXXConstructorDeclBits and the accessor
@@ -1714,12 +1714,12 @@ class DeclContext {
/// For the bits in FunctionDeclBitfields.
uint64_t : NumFunctionDeclBits;
- /// 21 bits to fit in the remaining available space.
+ /// 20 bits to fit in the remaining available space.
/// Note that this makes CXXConstructorDeclBitfields take
/// exactly 64 bits and thus the width of NumCtorInitializers
/// will need to be shrunk if some bit is added to NumDeclContextBitfields,
/// NumFunctionDeclBitfields or CXXConstructorDeclBitfields.
- uint64_t NumCtorInitializers : 18;
+ uint64_t NumCtorInitializers : 17;
uint64_t IsInheritingConstructor : 1;
/// Whether this constructor has a trail-allocated explicit specifier.
diff --git a/contrib/llvm-project/clang/include/clang/AST/ExprConcepts.h b/contrib/llvm-project/clang/include/clang/AST/ExprConcepts.h
index d900e980852b..13d4568119eb 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ExprConcepts.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ExprConcepts.h
@@ -14,20 +14,21 @@
#ifndef LLVM_CLANG_AST_EXPRCONCEPTS_H
#define LLVM_CLANG_AST_EXPRCONCEPTS_H
-#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTConcept.h"
+#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
-#include "clang/AST/DeclarationName.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DeclarationName.h"
#include "clang/AST/Expr.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/Type.h"
#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/STLFunctionalExtras.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TrailingObjects.h"
-#include <utility>
#include <string>
+#include <utility>
namespace clang {
class ASTStmtReader;
@@ -467,6 +468,13 @@ public:
}
};
+using EntityPrinter = llvm::function_ref<void(llvm::raw_ostream &)>;
+
+/// \brief create a Requirement::SubstitutionDiagnostic with only a
+/// SubstitutedEntity and DiagLoc using Sema's allocator.
+Requirement::SubstitutionDiagnostic *
+createSubstDiagAt(Sema &S, SourceLocation Location, EntityPrinter Printer);
+
} // namespace concepts
/// C++2a [expr.prim.req]:
diff --git a/contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.def b/contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.def
index 11aec88c5335..d492b8681c5d 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.def
+++ b/contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.def
@@ -165,7 +165,6 @@ CODEGENOPT(PrepareForThinLTO , 1, 0) ///< Set when -flto=thin is enabled on the
///< compile step.
CODEGENOPT(LTOUnit, 1, 0) ///< Emit IR to support LTO unit features (CFI, whole
///< program vtable opt).
-CODEGENOPT(FatLTO, 1, 0) ///< Set when -ffat-lto-objects is enabled.
CODEGENOPT(EnableSplitLTOUnit, 1, 0) ///< Enable LTO unit splitting to support
/// CFI and traditional whole program
/// devirtualization that require whole
diff --git a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticASTKinds.td b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticASTKinds.td
index 566cdc340605..0794ed7ba683 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticASTKinds.td
+++ b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticASTKinds.td
@@ -70,6 +70,8 @@ def note_consteval_address_accessible : Note<
"is not a constant expression">;
def note_constexpr_uninitialized : Note<
"subobject %0 is not initialized">;
+def note_constexpr_uninitialized_base : Note<
+ "constructor of base class %0 is not called">;
def note_constexpr_static_local : Note<
"control flows through the definition of a %select{static|thread_local}0 variable">;
def note_constexpr_subobject_declared_here : Note<
diff --git a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticGroups.td b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticGroups.td
index 7b4d415bf064..26bc88a980e4 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticGroups.td
@@ -20,6 +20,7 @@ def DeprecatedStaticAnalyzerFlag : DiagGroup<"deprecated-static-analyzer-flag">;
// Empty DiagGroups are recognized by clang but ignored.
def ODR : DiagGroup<"odr">;
def : DiagGroup<"abi">;
+def : DiagGroup<"gnu-empty-initializer">; // Now a C extension, not GNU.
def AbsoluteValue : DiagGroup<"absolute-value">;
def MisspelledAssumption : DiagGroup<"misspelled-assumption">;
def UnknownAssumption : DiagGroup<"unknown-assumption">;
diff --git a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticLexKinds.td b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticLexKinds.td
index 0eb270aeea0e..6ad691975bd5 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticLexKinds.td
+++ b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticLexKinds.td
@@ -285,6 +285,10 @@ def ext_ms_reserved_user_defined_literal : ExtWarn<
def err_unsupported_string_concat : Error<
"unsupported non-standard concatenation of string literals">;
+def warn_unevaluated_string_prefix : Warning<
+ "encoding prefix '%0' on an unevaluated string literal has no effect"
+ "%select{| and is incompatible with c++2c}1">,
+ InGroup<DiagGroup<"invalid-unevaluated-string">>;
def err_unevaluated_string_prefix : Error<
"an unevaluated string literal cannot have an encoding prefix">;
def err_unevaluated_string_udl : Error<
diff --git a/contrib/llvm-project/clang/include/clang/Basic/Sanitizers.h b/contrib/llvm-project/clang/include/clang/Basic/Sanitizers.h
index db53010645ae..4659e45c7883 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/Sanitizers.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/Sanitizers.h
@@ -23,7 +23,11 @@
namespace llvm {
class hash_code;
+class Triple;
+namespace opt {
+class ArgList;
}
+} // namespace llvm
namespace clang {
diff --git a/contrib/llvm-project/clang/include/clang/Basic/TargetInfo.h b/contrib/llvm-project/clang/include/clang/Basic/TargetInfo.h
index 41ef47eb565b..61be52149341 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/TargetInfo.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/TargetInfo.h
@@ -1414,7 +1414,9 @@ public:
/// Identify whether this target supports IFuncs.
bool supportsIFunc() const {
- return getTriple().isOSBinFormatELF() && !getTriple().isOSFuchsia();
+ return getTriple().isOSBinFormatELF() &&
+ ((getTriple().isOSLinux() && !getTriple().isMusl()) ||
+ getTriple().isOSFreeBSD());
}
// Validate the contents of the __builtin_cpu_supports(const char*)
diff --git a/contrib/llvm-project/clang/include/clang/Basic/riscv_vector.td b/contrib/llvm-project/clang/include/clang/Basic/riscv_vector.td
index 7e5889812aec..6adc60031341 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/riscv_vector.td
+++ b/contrib/llvm-project/clang/include/clang/Basic/riscv_vector.td
@@ -112,7 +112,7 @@ multiclass RVVIntBinBuiltinSet
multiclass RVVSlideOneBuiltinSet
: RVVOutOp1BuiltinSet<NAME, "csil",
[["vx", "v", "vve"],
- ["vx", "Uv", "UvUve"]]>;
+ ["vx", "Uv", "UvUvUe"]]>;
multiclass RVVSignedShiftBuiltinSet
: RVVOutOp1BuiltinSet<NAME, "csil",
@@ -990,56 +990,6 @@ multiclass RVVPseudoVNCVTBuiltin<string IR, string MName, string type_range,
}
}
-// Define vread_csr&vwrite_csr described in RVV intrinsics doc.
-let HeaderCode =
-[{
-enum RVV_CSR {
- RVV_VSTART = 0,
- RVV_VXSAT,
- RVV_VXRM,
- RVV_VCSR,
-};
-
-static __inline__ __attribute__((__always_inline__, __nodebug__))
-unsigned long __riscv_vread_csr(enum RVV_CSR __csr) {
- unsigned long __rv = 0;
- switch (__csr) {
- case RVV_VSTART:
- __asm__ __volatile__ ("csrr\t%0, vstart" : "=r"(__rv) : : "memory");
- break;
- case RVV_VXSAT:
- __asm__ __volatile__ ("csrr\t%0, vxsat" : "=r"(__rv) : : "memory");
- break;
- case RVV_VXRM:
- __asm__ __volatile__ ("csrr\t%0, vxrm" : "=r"(__rv) : : "memory");
- break;
- case RVV_VCSR:
- __asm__ __volatile__ ("csrr\t%0, vcsr" : "=r"(__rv) : : "memory");
- break;
- }
- return __rv;
-}
-
-static __inline__ __attribute__((__always_inline__, __nodebug__))
-void __riscv_vwrite_csr(enum RVV_CSR __csr, unsigned long __value) {
- switch (__csr) {
- case RVV_VSTART:
- __asm__ __volatile__ ("csrw\tvstart, %z0" : : "rJ"(__value) : "memory");
- break;
- case RVV_VXSAT:
- __asm__ __volatile__ ("csrw\tvxsat, %z0" : : "rJ"(__value) : "memory");
- break;
- case RVV_VXRM:
- __asm__ __volatile__ ("csrw\tvxrm, %z0" : : "rJ"(__value) : "memory");
- break;
- case RVV_VCSR:
- __asm__ __volatile__ ("csrw\tvcsr, %z0" : : "rJ"(__value) : "memory");
- break;
- }
-}
-}] in
-def vread_vwrite_csr: RVVHeader;
-
let HeaderCode =
[{
#define __riscv_vlenb() __builtin_rvv_vlenb()
diff --git a/contrib/llvm-project/clang/include/clang/CodeGen/CGFunctionInfo.h b/contrib/llvm-project/clang/include/clang/CodeGen/CGFunctionInfo.h
index 39c7a578c8c4..b8971d5793f3 100644
--- a/contrib/llvm-project/clang/include/clang/CodeGen/CGFunctionInfo.h
+++ b/contrib/llvm-project/clang/include/clang/CodeGen/CGFunctionInfo.h
@@ -567,6 +567,10 @@ class CGFunctionInfo final
/// Whether this is a chain call.
unsigned ChainCall : 1;
+ /// Whether this function is called by forwarding arguments.
+ /// This doesn't support inalloca or varargs.
+ unsigned DelegateCall : 1;
+
/// Whether this function is a CMSE nonsecure call
unsigned CmseNSCall : 1;
@@ -616,14 +620,11 @@ class CGFunctionInfo final
CGFunctionInfo() : Required(RequiredArgs::All) {}
public:
- static CGFunctionInfo *create(unsigned llvmCC,
- bool instanceMethod,
- bool chainCall,
- const FunctionType::ExtInfo &extInfo,
- ArrayRef<ExtParameterInfo> paramInfos,
- CanQualType resultType,
- ArrayRef<CanQualType> argTypes,
- RequiredArgs required);
+ static CGFunctionInfo *
+ create(unsigned llvmCC, bool instanceMethod, bool chainCall,
+ bool delegateCall, const FunctionType::ExtInfo &extInfo,
+ ArrayRef<ExtParameterInfo> paramInfos, CanQualType resultType,
+ ArrayRef<CanQualType> argTypes, RequiredArgs required);
void operator delete(void *p) { ::operator delete(p); }
// Friending class TrailingObjects is apparently not good enough for MSVC,
@@ -663,6 +664,8 @@ public:
bool isChainCall() const { return ChainCall; }
+ bool isDelegateCall() const { return DelegateCall; }
+
bool isCmseNSCall() const { return CmseNSCall; }
bool isNoReturn() const { return NoReturn; }
@@ -749,6 +752,7 @@ public:
ID.AddInteger(getASTCallingConvention());
ID.AddBoolean(InstanceMethod);
ID.AddBoolean(ChainCall);
+ ID.AddBoolean(DelegateCall);
ID.AddBoolean(NoReturn);
ID.AddBoolean(ReturnsRetained);
ID.AddBoolean(NoCallerSavedRegs);
@@ -766,17 +770,16 @@ public:
for (const auto &I : arguments())
I.type.Profile(ID);
}
- static void Profile(llvm::FoldingSetNodeID &ID,
- bool InstanceMethod,
- bool ChainCall,
+ static void Profile(llvm::FoldingSetNodeID &ID, bool InstanceMethod,
+ bool ChainCall, bool IsDelegateCall,
const FunctionType::ExtInfo &info,
ArrayRef<ExtParameterInfo> paramInfos,
- RequiredArgs required,
- CanQualType resultType,
+ RequiredArgs required, CanQualType resultType,
ArrayRef<CanQualType> argTypes) {
ID.AddInteger(info.getCC());
ID.AddBoolean(InstanceMethod);
ID.AddBoolean(ChainCall);
+ ID.AddBoolean(IsDelegateCall);
ID.AddBoolean(info.getNoReturn());
ID.AddBoolean(info.getProducesResult());
ID.AddBoolean(info.getNoCallerSavedRegs());
diff --git a/contrib/llvm-project/clang/include/clang/Driver/Options.td b/contrib/llvm-project/clang/include/clang/Driver/Options.td
index 229f6141c750..e04f67bdb1fa 100644
--- a/contrib/llvm-project/clang/include/clang/Driver/Options.td
+++ b/contrib/llvm-project/clang/include/clang/Driver/Options.td
@@ -2375,11 +2375,6 @@ def fthin_link_bitcode_EQ : Joined<["-"], "fthin-link-bitcode=">,
Flags<[CoreOption, CC1Option]>, Group<f_Group>,
HelpText<"Write minimized bitcode to <file> for the ThinLTO thin link only">,
MarshallingInfoString<CodeGenOpts<"ThinLinkBitcodeFile">>;
-defm fat_lto_objects : BoolFOption<"fat-lto-objects",
- CodeGenOpts<"FatLTO">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Enable">,
- NegFlag<SetFalse, [CC1Option], "Disable">,
- BothFlags<[CC1Option], " fat LTO object support">>;
def fmacro_backtrace_limit_EQ : Joined<["-"], "fmacro-backtrace-limit=">,
Group<f_Group>, Flags<[NoXarchOption, CC1Option, CoreOption]>,
HelpText<"Set the maximum number of entries to print in a macro expansion backtrace (0 = no limit)">,
@@ -5097,6 +5092,10 @@ def mretpoline_external_thunk : Flag<["-"], "mretpoline-external-thunk">, Group<
def mno_retpoline_external_thunk : Flag<["-"], "mno-retpoline-external-thunk">, Group<m_x86_Features_Group>;
def mvzeroupper : Flag<["-"], "mvzeroupper">, Group<m_x86_Features_Group>;
def mno_vzeroupper : Flag<["-"], "mno-vzeroupper">, Group<m_x86_Features_Group>;
+def mno_gather : Flag<["-"], "mno-gather">, Group<m_x86_Features_Group>,
+ HelpText<"Disable generation of gather instructions in auto-vectorization(x86 only)">;
+def mno_scatter : Flag<["-"], "mno-scatter">, Group<m_x86_Features_Group>,
+ HelpText<"Disable generation of scatter instructions in auto-vectorization(x86 only)">;
// These are legacy user-facing driver-level option spellings. They are always
// aliases for options that are spelled using the more common Unix / GNU flag
@@ -5162,6 +5161,7 @@ defm caller_saves : BooleanFFlag<"caller-saves">, Group<clang_ignored_gcc_optimi
defm reorder_blocks : BooleanFFlag<"reorder-blocks">, Group<clang_ignored_gcc_optimization_f_Group>;
defm branch_count_reg : BooleanFFlag<"branch-count-reg">, Group<clang_ignored_gcc_optimization_f_Group>;
defm default_inline : BooleanFFlag<"default-inline">, Group<clang_ignored_gcc_optimization_f_Group>;
+defm fat_lto_objects : BooleanFFlag<"fat-lto-objects">, Group<clang_ignored_gcc_optimization_f_Group>;
defm float_store : BooleanFFlag<"float-store">, Group<clang_ignored_gcc_optimization_f_Group>;
defm friend_injection : BooleanFFlag<"friend-injection">, Group<clang_ignored_f_Group>;
defm function_attribute_list : BooleanFFlag<"function-attribute-list">, Group<clang_ignored_f_Group>;
@@ -7152,6 +7152,10 @@ def _SLASH_QIntel_jcc_erratum : CLFlag<"QIntel-jcc-erratum">,
Alias<mbranches_within_32B_boundaries>;
def _SLASH_arm64EC : CLFlag<"arm64EC">,
HelpText<"Set build target to arm64ec">;
+def : CLFlag<"Qgather-">, Alias<mno_gather>,
+ HelpText<"Disable generation of gather instructions in auto-vectorization(x86 only)">;
+def : CLFlag<"Qscatter-">, Alias<mno_scatter>,
+ HelpText<"Disable generation of scatter instructions in auto-vectorization(x86 only)">;
// Non-aliases:
diff --git a/contrib/llvm-project/clang/include/clang/Driver/ToolChain.h b/contrib/llvm-project/clang/include/clang/Driver/ToolChain.h
index e3fcbd9322b0..2e74507f7126 100644
--- a/contrib/llvm-project/clang/include/clang/Driver/ToolChain.h
+++ b/contrib/llvm-project/clang/include/clang/Driver/ToolChain.h
@@ -561,7 +561,7 @@ public:
// Return the DWARF version to emit, in the absence of arguments
// to the contrary.
- virtual unsigned GetDefaultDwarfVersion() const { return 5; }
+ virtual unsigned GetDefaultDwarfVersion() const;
// Some toolchains may have different restrictions on the DWARF version and
// may need to adjust it. E.g. NVPTX may need to enforce DWARF2 even when host
diff --git a/contrib/llvm-project/clang/include/clang/Sema/Sema.h b/contrib/llvm-project/clang/include/clang/Sema/Sema.h
index 3418a37b3077..cfd1c0f977c0 100644
--- a/contrib/llvm-project/clang/include/clang/Sema/Sema.h
+++ b/contrib/llvm-project/clang/include/clang/Sema/Sema.h
@@ -12694,8 +12694,6 @@ public:
QualType CheckBitwiseOperands( // C99 6.5.[10...12]
ExprResult &LHS, ExprResult &RHS, SourceLocation Loc,
BinaryOperatorKind Opc);
- void diagnoseLogicalInsteadOfBitwise(Expr *Op1, Expr *Op2, SourceLocation Loc,
- BinaryOperatorKind Opc);
QualType CheckLogicalOperands( // C99 6.5.[13,14]
ExprResult &LHS, ExprResult &RHS, SourceLocation Loc,
BinaryOperatorKind Opc);
diff --git a/contrib/llvm-project/clang/lib/AST/ASTContext.cpp b/contrib/llvm-project/clang/lib/AST/ASTContext.cpp
index 7acacd7bf4f5..76000156fece 100644
--- a/contrib/llvm-project/clang/lib/AST/ASTContext.cpp
+++ b/contrib/llvm-project/clang/lib/AST/ASTContext.cpp
@@ -9612,9 +9612,8 @@ bool ASTContext::areLaxCompatibleRVVTypes(QualType FirstType,
const LangOptions::LaxVectorConversionKind LVCKind =
getLangOpts().getLaxVectorConversions();
- // If __riscv_v_fixed_vlen != N do not allow GNU vector lax conversion.
- if (VecTy->getVectorKind() == VectorType::GenericVector &&
- getTypeSize(SecondType) != getRVVTypeSize(*this, BT))
+ // If __riscv_v_fixed_vlen != N do not allow vector lax conversion.
+ if (getTypeSize(SecondType) != getRVVTypeSize(*this, BT))
return false;
// If -flax-vector-conversions=all is specified, the types are
diff --git a/contrib/llvm-project/clang/lib/AST/ExprConstant.cpp b/contrib/llvm-project/clang/lib/AST/ExprConstant.cpp
index f1c842e26199..f1bad0c7f7f2 100644
--- a/contrib/llvm-project/clang/lib/AST/ExprConstant.cpp
+++ b/contrib/llvm-project/clang/lib/AST/ExprConstant.cpp
@@ -2418,9 +2418,16 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
if (const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
unsigned BaseIndex = 0;
for (const CXXBaseSpecifier &BS : CD->bases()) {
- if (!CheckEvaluationResult(CERK, Info, DiagLoc, BS.getType(),
- Value.getStructBase(BaseIndex), Kind,
- /*SubobjectDecl=*/nullptr, CheckedTemps))
+ const APValue &BaseValue = Value.getStructBase(BaseIndex);
+ if (!BaseValue.hasValue()) {
+ SourceLocation TypeBeginLoc = BS.getBaseTypeLoc();
+ Info.FFDiag(TypeBeginLoc, diag::note_constexpr_uninitialized_base)
+ << BS.getType() << SourceRange(TypeBeginLoc, BS.getEndLoc());
+ return false;
+ }
+ if (!CheckEvaluationResult(CERK, Info, DiagLoc, BS.getType(), BaseValue,
+ Kind, /*SubobjectDecl=*/nullptr,
+ CheckedTemps))
return false;
++BaseIndex;
}
@@ -15218,14 +15225,6 @@ static bool FastEvaluateAsRValue(const Expr *Exp, Expr::EvalResult &Result,
return true;
}
- // FIXME: Evaluating values of large array and record types can cause
- // performance problems. Only do so in C++11 for now.
- if (Exp->isPRValue() &&
- (Exp->getType()->isArrayType() || Exp->getType()->isRecordType()) &&
- !Ctx.getLangOpts().CPlusPlus11) {
- IsConst = false;
- return true;
- }
return false;
}
@@ -15467,12 +15466,6 @@ bool Expr::EvaluateAsInitializer(APValue &Value, const ASTContext &Ctx,
return Name;
});
- // FIXME: Evaluating initializers for large array and record types can cause
- // performance problems. Only do so in C++11 for now.
- if (isPRValue() && (getType()->isArrayType() || getType()->isRecordType()) &&
- !Ctx.getLangOpts().CPlusPlus11)
- return false;
-
Expr::EvalStatus EStatus;
EStatus.Diag = &Notes;
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/LoongArch.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/LoongArch.cpp
index 6958479cd7c4..4448a2ae10a1 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/LoongArch.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/LoongArch.cpp
@@ -15,7 +15,7 @@
#include "clang/Basic/MacroBuilder.h"
#include "clang/Basic/TargetBuiltins.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/TargetParser/TargetParser.h"
+#include "llvm/TargetParser/LoongArchTargetParser.h"
using namespace clang;
using namespace clang::targets;
@@ -198,7 +198,15 @@ void LoongArchTargetInfo::getTargetDefines(const LangOptions &Opts,
else
Builder.defineMacro("__loongarch_frlen", "0");
- // TODO: define __loongarch_arch and __loongarch_tune.
+ // Define __loongarch_arch.
+ StringRef ArchName = getCPU();
+ Builder.defineMacro("__loongarch_arch", Twine('"') + ArchName + Twine('"'));
+
+ // Define __loongarch_tune.
+ StringRef TuneCPU = getTargetOpts().TuneCPU;
+ if (TuneCPU.empty())
+ TuneCPU = ArchName;
+ Builder.defineMacro("__loongarch_tune", Twine('"') + TuneCPU + Twine('"'));
StringRef ABI = getABI();
if (ABI == "lp64d" || ABI == "lp64f" || ABI == "lp64s")
@@ -270,3 +278,12 @@ bool LoongArchTargetInfo::handleTargetFeatures(
}
return true;
}
+
+bool LoongArchTargetInfo::isValidCPUName(StringRef Name) const {
+ return llvm::LoongArch::isValidCPUName(Name);
+}
+
+void LoongArchTargetInfo::fillValidCPUList(
+ SmallVectorImpl<StringRef> &Values) const {
+ llvm::LoongArch::fillValidCPUList(Values);
+}
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/LoongArch.h b/contrib/llvm-project/clang/lib/Basic/Targets/LoongArch.h
index 52c4ce425368..34143f462a24 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/LoongArch.h
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/LoongArch.h
@@ -24,6 +24,7 @@ namespace targets {
class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo {
protected:
std::string ABI;
+ std::string CPU;
bool HasFeatureD;
bool HasFeatureF;
@@ -40,6 +41,15 @@ public:
WIntType = UnsignedInt;
}
+ bool setCPU(const std::string &Name) override {
+ if (!isValidCPUName(Name))
+ return false;
+ CPU = Name;
+ return true;
+ }
+
+ StringRef getCPU() const { return CPU; }
+
StringRef getABI() const override { return ABI; }
void getTargetDefines(const LangOptions &Opts,
@@ -80,6 +90,9 @@ public:
const std::vector<std::string> &FeaturesVec) const override;
bool hasFeature(StringRef Feature) const override;
+
+ bool isValidCPUName(StringRef Name) const override;
+ void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
};
class LLVM_LIBRARY_VISIBILITY LoongArch32TargetInfo
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.cpp
index 94c894dfec0b..d55ab76395c8 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.cpp
@@ -196,8 +196,8 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts,
if (ISAInfo->hasExtension("zve32x")) {
Builder.defineMacro("__riscv_vector");
- // Currently we support the v0.11 RISC-V V intrinsics.
- Builder.defineMacro("__riscv_v_intrinsic", Twine(getVersionValue(0, 11)));
+ // Currently we support the v0.12 RISC-V V intrinsics.
+ Builder.defineMacro("__riscv_v_intrinsic", Twine(getVersionValue(0, 12)));
}
auto VScale = getVScaleRange(Opts);
diff --git a/contrib/llvm-project/clang/lib/CodeGen/ABIInfoImpl.cpp b/contrib/llvm-project/clang/lib/CodeGen/ABIInfoImpl.cpp
index 7c30cecfdb9b..2b20d5a13346 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/ABIInfoImpl.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/ABIInfoImpl.cpp
@@ -246,7 +246,7 @@ Address CodeGen::emitMergePHI(CodeGenFunction &CGF, Address Addr1,
}
bool CodeGen::isEmptyField(ASTContext &Context, const FieldDecl *FD,
- bool AllowArrays) {
+ bool AllowArrays, bool AsIfNoUniqueAddr) {
if (FD->isUnnamedBitfield())
return true;
@@ -280,13 +280,14 @@ bool CodeGen::isEmptyField(ASTContext &Context, const FieldDecl *FD,
// not arrays of records, so we must also check whether we stripped off an
// array type above.
if (isa<CXXRecordDecl>(RT->getDecl()) &&
- (WasArray || !FD->hasAttr<NoUniqueAddressAttr>()))
+ (WasArray || (!AsIfNoUniqueAddr && !FD->hasAttr<NoUniqueAddressAttr>())))
return false;
- return isEmptyRecord(Context, FT, AllowArrays);
+ return isEmptyRecord(Context, FT, AllowArrays, AsIfNoUniqueAddr);
}
-bool CodeGen::isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays) {
+bool CodeGen::isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays,
+ bool AsIfNoUniqueAddr) {
const RecordType *RT = T->getAs<RecordType>();
if (!RT)
return false;
@@ -297,11 +298,11 @@ bool CodeGen::isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays) {
// If this is a C++ record, check the bases first.
if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
for (const auto &I : CXXRD->bases())
- if (!isEmptyRecord(Context, I.getType(), true))
+ if (!isEmptyRecord(Context, I.getType(), true, AsIfNoUniqueAddr))
return false;
for (const auto *I : RD->fields())
- if (!isEmptyField(Context, I, AllowArrays))
+ if (!isEmptyField(Context, I, AllowArrays, AsIfNoUniqueAddr))
return false;
return true;
}
diff --git a/contrib/llvm-project/clang/lib/CodeGen/ABIInfoImpl.h b/contrib/llvm-project/clang/lib/CodeGen/ABIInfoImpl.h
index 5f0cc289af68..afde08ba100c 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/ABIInfoImpl.h
+++ b/contrib/llvm-project/clang/lib/CodeGen/ABIInfoImpl.h
@@ -122,13 +122,19 @@ Address emitMergePHI(CodeGenFunction &CGF, Address Addr1,
llvm::BasicBlock *Block2, const llvm::Twine &Name = "");
/// isEmptyField - Return true iff a the field is "empty", that is it
-/// is an unnamed bit-field or an (array of) empty record(s).
-bool isEmptyField(ASTContext &Context, const FieldDecl *FD, bool AllowArrays);
+/// is an unnamed bit-field or an (array of) empty record(s). If
+/// AsIfNoUniqueAddr is true, then C++ record fields are considered empty if
+/// the [[no_unique_address]] attribute would have made them empty.
+bool isEmptyField(ASTContext &Context, const FieldDecl *FD, bool AllowArrays,
+ bool AsIfNoUniqueAddr = false);
/// isEmptyRecord - Return true iff a structure contains only empty
/// fields. Note that a structure with a flexible array member is not
-/// considered empty.
-bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays);
+/// considered empty. If AsIfNoUniqueAddr is true, then C++ record fields are
+/// considered empty if the [[no_unique_address]] attribute would have made
+/// them empty.
+bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays,
+ bool AsIfNoUniqueAddr = false);
/// isSingleElementStruct - Determine if a structure is a "single
/// element struct", i.e. it has exactly one non-empty field or
diff --git a/contrib/llvm-project/clang/lib/CodeGen/BackendUtil.cpp b/contrib/llvm-project/clang/lib/CodeGen/BackendUtil.cpp
index cda03d69522d..483f3e787a78 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/BackendUtil.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/BackendUtil.cpp
@@ -55,7 +55,6 @@
#include "llvm/Target/TargetOptions.h"
#include "llvm/TargetParser/SubtargetFeature.h"
#include "llvm/TargetParser/Triple.h"
-#include "llvm/Transforms/IPO/EmbedBitcodePass.h"
#include "llvm/Transforms/IPO/LowerTypeTests.h"
#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
#include "llvm/Transforms/InstCombine/InstCombine.h"
@@ -1016,12 +1015,7 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
});
}
- bool IsThinOrUnifiedLTO = IsThinLTO || (IsLTO && CodeGenOpts.UnifiedLTO);
- if (CodeGenOpts.FatLTO) {
- MPM = PB.buildFatLTODefaultPipeline(Level, IsThinOrUnifiedLTO,
- IsThinOrUnifiedLTO ||
- shouldEmitRegularLTOSummary());
- } else if (IsThinOrUnifiedLTO) {
+ if (IsThinLTO || (IsLTO && CodeGenOpts.UnifiedLTO)) {
MPM = PB.buildThinLTOPreLinkDefaultPipeline(Level);
} else if (IsLTO) {
MPM = PB.buildLTOPreLinkDefaultPipeline(Level);
@@ -1077,21 +1071,6 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
EmitLTOSummary));
}
}
- if (CodeGenOpts.FatLTO) {
- // Set module flags, like EnableSplitLTOUnit and UnifiedLTO, since FatLTO
- // uses a different action than Backend_EmitBC or Backend_EmitLL.
- bool IsThinOrUnifiedLTO =
- CodeGenOpts.PrepareForThinLTO ||
- (CodeGenOpts.PrepareForLTO && CodeGenOpts.UnifiedLTO);
- if (!TheModule->getModuleFlag("ThinLTO"))
- TheModule->addModuleFlag(Module::Error, "ThinLTO",
- uint32_t(IsThinOrUnifiedLTO));
- if (!TheModule->getModuleFlag("EnableSplitLTOUnit"))
- TheModule->addModuleFlag(Module::Error, "EnableSplitLTOUnit",
- uint32_t(CodeGenOpts.EnableSplitLTOUnit));
- if (CodeGenOpts.UnifiedLTO && !TheModule->getModuleFlag("UnifiedLTO"))
- TheModule->addModuleFlag(Module::Error, "UnifiedLTO", uint32_t(1));
- }
// Now that we have all of the passes ready, run them.
{
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGCXXABI.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGCXXABI.cpp
index 7b77dd7875bc..4df6f6505ef6 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CGCXXABI.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/CGCXXABI.cpp
@@ -312,8 +312,7 @@ void CGCXXABI::setCXXDestructorDLLStorage(llvm::GlobalValue *GV,
llvm::GlobalValue::LinkageTypes CGCXXABI::getCXXDestructorLinkage(
GVALinkage Linkage, const CXXDestructorDecl *Dtor, CXXDtorType DT) const {
// Delegate back to CGM by default.
- return CGM.getLLVMLinkageForDeclarator(Dtor, Linkage,
- /*IsConstantVariable=*/false);
+ return CGM.getLLVMLinkageForDeclarator(Dtor, Linkage);
}
bool CGCXXABI::NeedsVTTParameter(GlobalDecl GD) {
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGCall.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGCall.cpp
index bd272e016e92..0d1e9ad439b7 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CGCall.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/CGCall.cpp
@@ -13,6 +13,7 @@
#include "CGCall.h"
#include "ABIInfo.h"
+#include "ABIInfoImpl.h"
#include "CGBlocks.h"
#include "CGCXXABI.h"
#include "CGCleanup.h"
@@ -112,8 +113,7 @@ CodeGenTypes::arrangeFreeFunctionType(CanQual<FunctionNoProtoType> FTNP) {
// When translating an unprototyped function type, always use a
// variadic type.
return arrangeLLVMFunctionInfo(FTNP->getReturnType().getUnqualifiedType(),
- /*instanceMethod=*/false,
- /*chainCall=*/false, std::nullopt,
+ FnInfoOpts::None, std::nullopt,
FTNP->getExtInfo(), {}, RequiredArgs(0));
}
@@ -189,10 +189,10 @@ arrangeLLVMFunctionInfo(CodeGenTypes &CGT, bool instanceMethod,
appendParameterTypes(CGT, prefix, paramInfos, FTP);
CanQualType resultType = FTP->getReturnType().getUnqualifiedType();
- return CGT.arrangeLLVMFunctionInfo(resultType, instanceMethod,
- /*chainCall=*/false, prefix,
- FTP->getExtInfo(), paramInfos,
- Required);
+ FnInfoOpts opts =
+ instanceMethod ? FnInfoOpts::IsInstanceMethod : FnInfoOpts::None;
+ return CGT.arrangeLLVMFunctionInfo(resultType, opts, prefix,
+ FTP->getExtInfo(), paramInfos, Required);
}
/// Arrange the argument and result information for a value of the
@@ -271,7 +271,7 @@ CodeGenTypes::arrangeCXXMethodType(const CXXRecordDecl *RD,
argTypes.push_back(DeriveThisType(RD, MD));
return ::arrangeLLVMFunctionInfo(
- *this, true, argTypes,
+ *this, /*instanceMethod=*/true, argTypes,
FTP->getCanonicalTypeUnqualified().getAs<FunctionProtoType>());
}
@@ -363,9 +363,8 @@ CodeGenTypes::arrangeCXXStructorDeclaration(GlobalDecl GD) {
: TheCXXABI.hasMostDerivedReturn(GD)
? CGM.getContext().VoidPtrTy
: Context.VoidTy;
- return arrangeLLVMFunctionInfo(resultType, /*instanceMethod=*/true,
- /*chainCall=*/false, argTypes, extInfo,
- paramInfos, required);
+ return arrangeLLVMFunctionInfo(resultType, FnInfoOpts::IsInstanceMethod,
+ argTypes, extInfo, paramInfos, required);
}
static SmallVector<CanQualType, 16>
@@ -439,9 +438,9 @@ CodeGenTypes::arrangeCXXConstructorCall(const CallArgList &args,
addExtParameterInfosForCall(ParamInfos, FPT.getTypePtr(), TotalPrefixArgs,
ArgTypes.size());
}
- return arrangeLLVMFunctionInfo(ResultType, /*instanceMethod=*/true,
- /*chainCall=*/false, ArgTypes, Info,
- ParamInfos, Required);
+
+ return arrangeLLVMFunctionInfo(ResultType, FnInfoOpts::IsInstanceMethod,
+ ArgTypes, Info, ParamInfos, Required);
}
/// Arrange the argument and result information for the declaration or
@@ -460,10 +459,9 @@ CodeGenTypes::arrangeFunctionDeclaration(const FunctionDecl *FD) {
// When declaring a function without a prototype, always use a
// non-variadic type.
if (CanQual<FunctionNoProtoType> noProto = FTy.getAs<FunctionNoProtoType>()) {
- return arrangeLLVMFunctionInfo(
- noProto->getReturnType(), /*instanceMethod=*/false,
- /*chainCall=*/false, std::nullopt, noProto->getExtInfo(), {},
- RequiredArgs::All);
+ return arrangeLLVMFunctionInfo(noProto->getReturnType(), FnInfoOpts::None,
+ std::nullopt, noProto->getExtInfo(), {},
+ RequiredArgs::All);
}
return arrangeFreeFunctionType(FTy.castAs<FunctionProtoType>());
@@ -512,9 +510,9 @@ CodeGenTypes::arrangeObjCMessageSendSignature(const ObjCMethodDecl *MD,
RequiredArgs required =
(MD->isVariadic() ? RequiredArgs(argTys.size()) : RequiredArgs::All);
- return arrangeLLVMFunctionInfo(
- GetReturnType(MD->getReturnType()), /*instanceMethod=*/false,
- /*chainCall=*/false, argTys, einfo, extParamInfos, required);
+ return arrangeLLVMFunctionInfo(GetReturnType(MD->getReturnType()),
+ FnInfoOpts::None, argTys, einfo, extParamInfos,
+ required);
}
const CGFunctionInfo &
@@ -523,9 +521,8 @@ CodeGenTypes::arrangeUnprototypedObjCMessageSend(QualType returnType,
auto argTypes = getArgTypesForCall(Context, args);
FunctionType::ExtInfo einfo;
- return arrangeLLVMFunctionInfo(
- GetReturnType(returnType), /*instanceMethod=*/false,
- /*chainCall=*/false, argTypes, einfo, {}, RequiredArgs::All);
+ return arrangeLLVMFunctionInfo(GetReturnType(returnType), FnInfoOpts::None,
+ argTypes, einfo, {}, RequiredArgs::All);
}
const CGFunctionInfo &
@@ -550,8 +547,7 @@ CodeGenTypes::arrangeUnprototypedMustTailThunk(const CXXMethodDecl *MD) {
assert(MD->isVirtual() && "only methods have thunks");
CanQual<FunctionProtoType> FTP = GetFormalType(MD);
CanQualType ArgTys[] = {DeriveThisType(MD->getParent(), MD)};
- return arrangeLLVMFunctionInfo(Context.VoidTy, /*instanceMethod=*/false,
- /*chainCall=*/false, ArgTys,
+ return arrangeLLVMFunctionInfo(Context.VoidTy, FnInfoOpts::None, ArgTys,
FTP->getExtInfo(), {}, RequiredArgs(1));
}
@@ -570,9 +566,8 @@ CodeGenTypes::arrangeMSCtorClosure(const CXXConstructorDecl *CD,
ArgTys.push_back(Context.IntTy);
CallingConv CC = Context.getDefaultCallingConvention(
/*IsVariadic=*/false, /*IsCXXMethod=*/true);
- return arrangeLLVMFunctionInfo(Context.VoidTy, /*instanceMethod=*/true,
- /*chainCall=*/false, ArgTys,
- FunctionType::ExtInfo(CC), {},
+ return arrangeLLVMFunctionInfo(Context.VoidTy, FnInfoOpts::IsInstanceMethod,
+ ArgTys, FunctionType::ExtInfo(CC), {},
RequiredArgs::All);
}
@@ -616,10 +611,10 @@ arrangeFreeFunctionLikeCall(CodeGenTypes &CGT,
SmallVector<CanQualType, 16> argTypes;
for (const auto &arg : args)
argTypes.push_back(CGT.getContext().getCanonicalParamType(arg.Ty));
+ FnInfoOpts opts = chainCall ? FnInfoOpts::IsChainCall : FnInfoOpts::None;
return CGT.arrangeLLVMFunctionInfo(GetReturnType(fnType->getReturnType()),
- /*instanceMethod=*/false, chainCall,
- argTypes, fnType->getExtInfo(), paramInfos,
- required);
+ opts, argTypes, fnType->getExtInfo(),
+ paramInfos, required);
}
/// Figure out the rules for calling a function with the given formal
@@ -650,8 +645,8 @@ CodeGenTypes::arrangeBlockFunctionDeclaration(const FunctionProtoType *proto,
auto argTypes = getArgTypesForDeclaration(Context, params);
return arrangeLLVMFunctionInfo(GetReturnType(proto->getReturnType()),
- /*instanceMethod*/ false, /*chainCall*/ false,
- argTypes, proto->getExtInfo(), paramInfos,
+ FnInfoOpts::None, argTypes,
+ proto->getExtInfo(), paramInfos,
RequiredArgs::forPrototypePlus(proto, 1));
}
@@ -662,10 +657,9 @@ CodeGenTypes::arrangeBuiltinFunctionCall(QualType resultType,
SmallVector<CanQualType, 16> argTypes;
for (const auto &Arg : args)
argTypes.push_back(Context.getCanonicalParamType(Arg.Ty));
- return arrangeLLVMFunctionInfo(
- GetReturnType(resultType), /*instanceMethod=*/false,
- /*chainCall=*/false, argTypes, FunctionType::ExtInfo(),
- /*paramInfos=*/ {}, RequiredArgs::All);
+ return arrangeLLVMFunctionInfo(GetReturnType(resultType), FnInfoOpts::None,
+ argTypes, FunctionType::ExtInfo(),
+ /*paramInfos=*/{}, RequiredArgs::All);
}
const CGFunctionInfo &
@@ -673,17 +667,17 @@ CodeGenTypes::arrangeBuiltinFunctionDeclaration(QualType resultType,
const FunctionArgList &args) {
auto argTypes = getArgTypesForDeclaration(Context, args);
- return arrangeLLVMFunctionInfo(
- GetReturnType(resultType), /*instanceMethod=*/false, /*chainCall=*/false,
- argTypes, FunctionType::ExtInfo(), {}, RequiredArgs::All);
+ return arrangeLLVMFunctionInfo(GetReturnType(resultType), FnInfoOpts::None,
+ argTypes, FunctionType::ExtInfo(), {},
+ RequiredArgs::All);
}
const CGFunctionInfo &
CodeGenTypes::arrangeBuiltinFunctionDeclaration(CanQualType resultType,
ArrayRef<CanQualType> argTypes) {
- return arrangeLLVMFunctionInfo(
- resultType, /*instanceMethod=*/false, /*chainCall=*/false,
- argTypes, FunctionType::ExtInfo(), {}, RequiredArgs::All);
+ return arrangeLLVMFunctionInfo(resultType, FnInfoOpts::None, argTypes,
+ FunctionType::ExtInfo(), {},
+ RequiredArgs::All);
}
/// Arrange a call to a C++ method, passing the given arguments.
@@ -706,15 +700,15 @@ CodeGenTypes::arrangeCXXMethodCall(const CallArgList &args,
auto argTypes = getArgTypesForCall(Context, args);
FunctionType::ExtInfo info = proto->getExtInfo();
- return arrangeLLVMFunctionInfo(
- GetReturnType(proto->getReturnType()), /*instanceMethod=*/true,
- /*chainCall=*/false, argTypes, info, paramInfos, required);
+ return arrangeLLVMFunctionInfo(GetReturnType(proto->getReturnType()),
+ FnInfoOpts::IsInstanceMethod, argTypes, info,
+ paramInfos, required);
}
const CGFunctionInfo &CodeGenTypes::arrangeNullaryFunction() {
- return arrangeLLVMFunctionInfo(
- getContext().VoidTy, /*instanceMethod=*/false, /*chainCall=*/false,
- std::nullopt, FunctionType::ExtInfo(), {}, RequiredArgs::All);
+ return arrangeLLVMFunctionInfo(getContext().VoidTy, FnInfoOpts::None,
+ std::nullopt, FunctionType::ExtInfo(), {},
+ RequiredArgs::All);
}
const CGFunctionInfo &
@@ -734,12 +728,15 @@ CodeGenTypes::arrangeCall(const CGFunctionInfo &signature,
auto argTypes = getArgTypesForCall(Context, args);
assert(signature.getRequiredArgs().allowsOptionalArgs());
- return arrangeLLVMFunctionInfo(signature.getReturnType(),
- signature.isInstanceMethod(),
- signature.isChainCall(),
- argTypes,
- signature.getExtInfo(),
- paramInfos,
+ FnInfoOpts opts = FnInfoOpts::None;
+ if (signature.isInstanceMethod())
+ opts |= FnInfoOpts::IsInstanceMethod;
+ if (signature.isChainCall())
+ opts |= FnInfoOpts::IsChainCall;
+ if (signature.isDelegateCall())
+ opts |= FnInfoOpts::IsDelegateCall;
+ return arrangeLLVMFunctionInfo(signature.getReturnType(), opts, argTypes,
+ signature.getExtInfo(), paramInfos,
signature.getRequiredArgs());
}
@@ -752,21 +749,24 @@ void computeSPIRKernelABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI);
/// Arrange the argument and result information for an abstract value
/// of a given function type. This is the method which all of the
/// above functions ultimately defer to.
-const CGFunctionInfo &
-CodeGenTypes::arrangeLLVMFunctionInfo(CanQualType resultType,
- bool instanceMethod,
- bool chainCall,
- ArrayRef<CanQualType> argTypes,
- FunctionType::ExtInfo info,
- ArrayRef<FunctionProtoType::ExtParameterInfo> paramInfos,
- RequiredArgs required) {
+const CGFunctionInfo &CodeGenTypes::arrangeLLVMFunctionInfo(
+ CanQualType resultType, FnInfoOpts opts, ArrayRef<CanQualType> argTypes,
+ FunctionType::ExtInfo info,
+ ArrayRef<FunctionProtoType::ExtParameterInfo> paramInfos,
+ RequiredArgs required) {
assert(llvm::all_of(argTypes,
[](CanQualType T) { return T.isCanonicalAsParam(); }));
// Lookup or create unique function info.
llvm::FoldingSetNodeID ID;
- CGFunctionInfo::Profile(ID, instanceMethod, chainCall, info, paramInfos,
- required, resultType, argTypes);
+ bool isInstanceMethod =
+ (opts & FnInfoOpts::IsInstanceMethod) == FnInfoOpts::IsInstanceMethod;
+ bool isChainCall =
+ (opts & FnInfoOpts::IsChainCall) == FnInfoOpts::IsChainCall;
+ bool isDelegateCall =
+ (opts & FnInfoOpts::IsDelegateCall) == FnInfoOpts::IsDelegateCall;
+ CGFunctionInfo::Profile(ID, isInstanceMethod, isChainCall, isDelegateCall,
+ info, paramInfos, required, resultType, argTypes);
void *insertPos = nullptr;
CGFunctionInfo *FI = FunctionInfos.FindNodeOrInsertPos(ID, insertPos);
@@ -776,8 +776,8 @@ CodeGenTypes::arrangeLLVMFunctionInfo(CanQualType resultType,
unsigned CC = ClangCallConvToLLVMCallConv(info.getCC());
// Construct the function info. We co-allocate the ArgInfos.
- FI = CGFunctionInfo::create(CC, instanceMethod, chainCall, info,
- paramInfos, resultType, argTypes, required);
+ FI = CGFunctionInfo::create(CC, isInstanceMethod, isChainCall, isDelegateCall,
+ info, paramInfos, resultType, argTypes, required);
FunctionInfos.InsertNode(FI, insertPos);
bool inserted = FunctionsBeingProcessed.insert(FI).second;
@@ -812,9 +812,8 @@ CodeGenTypes::arrangeLLVMFunctionInfo(CanQualType resultType,
return *FI;
}
-CGFunctionInfo *CGFunctionInfo::create(unsigned llvmCC,
- bool instanceMethod,
- bool chainCall,
+CGFunctionInfo *CGFunctionInfo::create(unsigned llvmCC, bool instanceMethod,
+ bool chainCall, bool delegateCall,
const FunctionType::ExtInfo &info,
ArrayRef<ExtParameterInfo> paramInfos,
CanQualType resultType,
@@ -834,6 +833,7 @@ CGFunctionInfo *CGFunctionInfo::create(unsigned llvmCC,
FI->ASTCallingConvention = info.getCC();
FI->InstanceMethod = instanceMethod;
FI->ChainCall = chainCall;
+ FI->DelegateCall = delegateCall;
FI->CmseNSCall = info.getCmseNSCall();
FI->NoReturn = info.getNoReturn();
FI->ReturnsRetained = info.getProducesResult();
@@ -3989,10 +3989,6 @@ void CodeGenFunction::EmitDelegateCallArg(CallArgList &args,
QualType type = param->getType();
- if (isInAllocaArgument(CGM.getCXXABI(), type)) {
- CGM.ErrorUnsupported(param, "forwarded non-trivially copyable parameter");
- }
-
// GetAddrOfLocalVar returns a pointer-to-pointer for references,
// but the argument needs to be the original pointer.
if (type->isReferenceType()) {
@@ -5105,7 +5101,6 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
"indirect argument must be in alloca address space");
bool NeedCopy = false;
-
if (Addr.getAlignment() < Align &&
llvm::getOrEnforceKnownAlignment(V, Align.getAsAlign(), *TD) <
Align.getAsAlign()) {
@@ -5244,30 +5239,50 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
dyn_cast<llvm::StructType>(ArgInfo.getCoerceToType());
if (STy && ArgInfo.isDirect() && ArgInfo.getCanBeFlattened()) {
llvm::Type *SrcTy = Src.getElementType();
- uint64_t SrcSize = CGM.getDataLayout().getTypeAllocSize(SrcTy);
- uint64_t DstSize = CGM.getDataLayout().getTypeAllocSize(STy);
-
- // If the source type is smaller than the destination type of the
- // coerce-to logic, copy the source value into a temp alloca the size
- // of the destination type to allow loading all of it. The bits past
- // the source value are left undef.
- if (SrcSize < DstSize) {
- Address TempAlloca
- = CreateTempAlloca(STy, Src.getAlignment(),
- Src.getName() + ".coerce");
- Builder.CreateMemCpy(TempAlloca, Src, SrcSize);
- Src = TempAlloca;
+ llvm::TypeSize SrcTypeSize =
+ CGM.getDataLayout().getTypeAllocSize(SrcTy);
+ llvm::TypeSize DstTypeSize = CGM.getDataLayout().getTypeAllocSize(STy);
+ if (SrcTypeSize.isScalable()) {
+ assert(STy->containsHomogeneousScalableVectorTypes() &&
+ "ABI only supports structure with homogeneous scalable vector "
+ "type");
+ assert(SrcTypeSize == DstTypeSize &&
+ "Only allow non-fractional movement of structure with "
+ "homogeneous scalable vector type");
+ assert(NumIRArgs == STy->getNumElements());
+
+ llvm::Value *StoredStructValue =
+ Builder.CreateLoad(Src, Src.getName() + ".tuple");
+ for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
+ llvm::Value *Extract = Builder.CreateExtractValue(
+ StoredStructValue, i, Src.getName() + ".extract" + Twine(i));
+ IRCallArgs[FirstIRArg + i] = Extract;
+ }
} else {
- Src = Src.withElementType(STy);
- }
+ uint64_t SrcSize = SrcTypeSize.getFixedValue();
+ uint64_t DstSize = DstTypeSize.getFixedValue();
+
+ // If the source type is smaller than the destination type of the
+ // coerce-to logic, copy the source value into a temp alloca the size
+ // of the destination type to allow loading all of it. The bits past
+ // the source value are left undef.
+ if (SrcSize < DstSize) {
+ Address TempAlloca = CreateTempAlloca(STy, Src.getAlignment(),
+ Src.getName() + ".coerce");
+ Builder.CreateMemCpy(TempAlloca, Src, SrcSize);
+ Src = TempAlloca;
+ } else {
+ Src = Src.withElementType(STy);
+ }
- assert(NumIRArgs == STy->getNumElements());
- for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
- Address EltPtr = Builder.CreateStructGEP(Src, i);
- llvm::Value *LI = Builder.CreateLoad(EltPtr);
- if (ArgHasMaybeUndefAttr)
- LI = Builder.CreateFreeze(LI);
- IRCallArgs[FirstIRArg + i] = LI;
+ assert(NumIRArgs == STy->getNumElements());
+ for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
+ Address EltPtr = Builder.CreateStructGEP(Src, i);
+ llvm::Value *LI = Builder.CreateLoad(EltPtr);
+ if (ArgHasMaybeUndefAttr)
+ LI = Builder.CreateFreeze(LI);
+ IRCallArgs[FirstIRArg + i] = LI;
+ }
}
} else {
// In the simple case, just pass the coerced loaded value.
@@ -5472,6 +5487,30 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
Attrs.addFnAttribute(getLLVMContext(), llvm::Attribute::AlwaysInline);
}
+ // The await_suspend call performed by co_await is essentially asynchronous
+ // to the execution of the coroutine. Inlining it normally into an unsplit
+ // coroutine can cause miscompilation because the coroutine CFG misrepresents
+ // the true control flow of the program: things that happen in the
+ // await_suspend are not guaranteed to happen prior to the resumption of the
+ // coroutine, and things that happen after the resumption of the coroutine
+ // (including its exit and the potential deallocation of the coroutine frame)
+ // are not guaranteed to happen only after the end of await_suspend.
+ //
+ // The short-term solution to this problem is to mark the call as uninlinable.
+ // But we don't want to do this if the call is known to be trivial, which is
+ // very common.
+ //
+ // The long-term solution may introduce patterns like:
+ //
+ // call @llvm.coro.await_suspend(ptr %awaiter, ptr %handle,
+ // ptr @awaitSuspendFn)
+ //
+ // Then it is much easier to perform the safety analysis in the middle end.
+ // If it is safe to inline the call to awaitSuspend, we can replace it in the
+ // CoroEarly pass. Otherwise we could replace it in the CoroSplit pass.
+ if (inSuspendBlock() && mayCoroHandleEscape())
+ Attrs = Attrs.addFnAttribute(getLLVMContext(), llvm::Attribute::NoInline);
+
// Disable inlining inside SEH __try blocks.
if (isSEHTryScope()) {
Attrs = Attrs.addFnAttribute(getLLVMContext(), llvm::Attribute::NoInline);
@@ -5765,9 +5804,14 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
DestIsVolatile = false;
}
- // If the value is offset in memory, apply the offset now.
- Address StorePtr = emitAddressAtOffset(*this, DestPtr, RetAI);
- CreateCoercedStore(CI, StorePtr, DestIsVolatile, *this);
+ // An empty record can overlap other data (if declared with
+ // no_unique_address); omit the store for such types - as there is no
+ // actual data to store.
+ if (!isEmptyRecord(getContext(), RetTy, true)) {
+ // If the value is offset in memory, apply the offset now.
+ Address StorePtr = emitAddressAtOffset(*this, DestPtr, RetAI);
+ CreateCoercedStore(CI, StorePtr, DestIsVolatile, *this);
+ }
return convertTempToRValue(DestPtr, RetTy, SourceLocation());
}
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGCall.h b/contrib/llvm-project/clang/lib/CodeGen/CGCall.h
index eaaf10c4eec6..65a7d8e83288 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CGCall.h
+++ b/contrib/llvm-project/clang/lib/CodeGen/CGCall.h
@@ -383,6 +383,35 @@ void mergeDefaultFunctionDefinitionAttributes(llvm::Function &F,
const TargetOptions &TargetOpts,
bool WillInternalize);
+enum class FnInfoOpts {
+ None = 0,
+ IsInstanceMethod = 1 << 0,
+ IsChainCall = 1 << 1,
+ IsDelegateCall = 1 << 2,
+};
+
+inline FnInfoOpts operator|(FnInfoOpts A, FnInfoOpts B) {
+ return static_cast<FnInfoOpts>(
+ static_cast<std::underlying_type_t<FnInfoOpts>>(A) |
+ static_cast<std::underlying_type_t<FnInfoOpts>>(B));
+}
+
+inline FnInfoOpts operator&(FnInfoOpts A, FnInfoOpts B) {
+ return static_cast<FnInfoOpts>(
+ static_cast<std::underlying_type_t<FnInfoOpts>>(A) &
+ static_cast<std::underlying_type_t<FnInfoOpts>>(B));
+}
+
+inline FnInfoOpts operator|=(FnInfoOpts A, FnInfoOpts B) {
+ A = A | B;
+ return A;
+}
+
+inline FnInfoOpts operator&=(FnInfoOpts A, FnInfoOpts B) {
+ A = A & B;
+ return A;
+}
+
} // end namespace CodeGen
} // end namespace clang
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGClass.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGClass.cpp
index 93e7b54fca04..6ef7d12372d0 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CGClass.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/CGClass.cpp
@@ -2927,14 +2927,16 @@ llvm::Value *CodeGenFunction::EmitVTableTypeCheckedLoad(
}
void CodeGenFunction::EmitForwardingCallToLambda(
- const CXXMethodDecl *callOperator,
- CallArgList &callArgs) {
+ const CXXMethodDecl *callOperator, CallArgList &callArgs,
+ const CGFunctionInfo *calleeFnInfo, llvm::Constant *calleePtr) {
// Get the address of the call operator.
- const CGFunctionInfo &calleeFnInfo =
- CGM.getTypes().arrangeCXXMethodDeclaration(callOperator);
- llvm::Constant *calleePtr =
- CGM.GetAddrOfFunction(GlobalDecl(callOperator),
- CGM.getTypes().GetFunctionType(calleeFnInfo));
+ if (!calleeFnInfo)
+ calleeFnInfo = &CGM.getTypes().arrangeCXXMethodDeclaration(callOperator);
+
+ if (!calleePtr)
+ calleePtr =
+ CGM.GetAddrOfFunction(GlobalDecl(callOperator),
+ CGM.getTypes().GetFunctionType(*calleeFnInfo));
// Prepare the return slot.
const FunctionProtoType *FPT =
@@ -2942,8 +2944,8 @@ void CodeGenFunction::EmitForwardingCallToLambda(
QualType resultType = FPT->getReturnType();
ReturnValueSlot returnSlot;
if (!resultType->isVoidType() &&
- calleeFnInfo.getReturnInfo().getKind() == ABIArgInfo::Indirect &&
- !hasScalarEvaluationKind(calleeFnInfo.getReturnType()))
+ calleeFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect &&
+ !hasScalarEvaluationKind(calleeFnInfo->getReturnType()))
returnSlot =
ReturnValueSlot(ReturnValue, resultType.isVolatileQualified(),
/*IsUnused=*/false, /*IsExternallyDestructed=*/true);
@@ -2954,7 +2956,7 @@ void CodeGenFunction::EmitForwardingCallToLambda(
// Now emit our call.
auto callee = CGCallee::forDirect(calleePtr, GlobalDecl(callOperator));
- RValue RV = EmitCall(calleeFnInfo, callee, returnSlot, callArgs);
+ RValue RV = EmitCall(*calleeFnInfo, callee, returnSlot, callArgs);
// If necessary, copy the returned value into the slot.
if (!resultType->isVoidType() && returnSlot.isNull()) {
@@ -2996,7 +2998,15 @@ void CodeGenFunction::EmitLambdaBlockInvokeBody() {
EmitForwardingCallToLambda(CallOp, CallArgs);
}
-void CodeGenFunction::EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD) {
+void CodeGenFunction::EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD) {
+ if (MD->isVariadic()) {
+ // FIXME: Making this work correctly is nasty because it requires either
+ // cloning the body of the call operator or making the call operator
+ // forward.
+ CGM.ErrorUnsupported(MD, "lambda conversion to variadic function");
+ return;
+ }
+
const CXXRecordDecl *Lambda = MD->getParent();
// Start building arguments for forwarding call
@@ -3007,10 +3017,16 @@ void CodeGenFunction::EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD) {
Address ThisPtr = CreateMemTemp(LambdaType, "unused.capture");
CallArgs.add(RValue::get(ThisPtr.getPointer()), ThisType);
- // Add the rest of the parameters.
+ EmitLambdaDelegatingInvokeBody(MD, CallArgs);
+}
+
+void CodeGenFunction::EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD,
+ CallArgList &CallArgs) {
+ // Add the rest of the forwarded parameters.
for (auto *Param : MD->parameters())
EmitDelegateCallArg(CallArgs, Param, Param->getBeginLoc());
+ const CXXRecordDecl *Lambda = MD->getParent();
const CXXMethodDecl *CallOp = Lambda->getLambdaCallOperator();
// For a generic lambda, find the corresponding call operator specialization
// to which the call to the static-invoker shall be forwarded.
@@ -3024,10 +3040,21 @@ void CodeGenFunction::EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD) {
assert(CorrespondingCallOpSpecialization);
CallOp = cast<CXXMethodDecl>(CorrespondingCallOpSpecialization);
}
+
+ // Special lambda forwarding when there are inalloca parameters.
+ if (hasInAllocaArg(MD)) {
+ const CGFunctionInfo *ImplFnInfo = nullptr;
+ llvm::Function *ImplFn = nullptr;
+ EmitLambdaInAllocaImplFn(CallOp, &ImplFnInfo, &ImplFn);
+
+ EmitForwardingCallToLambda(CallOp, CallArgs, ImplFnInfo, ImplFn);
+ return;
+ }
+
EmitForwardingCallToLambda(CallOp, CallArgs);
}
-void CodeGenFunction::EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD) {
+void CodeGenFunction::EmitLambdaInAllocaCallOpBody(const CXXMethodDecl *MD) {
if (MD->isVariadic()) {
// FIXME: Making this work correctly is nasty because it requires either
// cloning the body of the call operator or making the call operator forward.
@@ -3035,5 +3062,56 @@ void CodeGenFunction::EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD) {
return;
}
- EmitLambdaDelegatingInvokeBody(MD);
+ // Forward %this argument.
+ CallArgList CallArgs;
+ QualType LambdaType = getContext().getRecordType(MD->getParent());
+ QualType ThisType = getContext().getPointerType(LambdaType);
+ llvm::Value *ThisArg = CurFn->getArg(0);
+ CallArgs.add(RValue::get(ThisArg), ThisType);
+
+ EmitLambdaDelegatingInvokeBody(MD, CallArgs);
+}
+
+void CodeGenFunction::EmitLambdaInAllocaImplFn(
+ const CXXMethodDecl *CallOp, const CGFunctionInfo **ImplFnInfo,
+ llvm::Function **ImplFn) {
+ const CGFunctionInfo &FnInfo =
+ CGM.getTypes().arrangeCXXMethodDeclaration(CallOp);
+ llvm::Function *CallOpFn =
+ cast<llvm::Function>(CGM.GetAddrOfFunction(GlobalDecl(CallOp)));
+
+ // Emit function containing the original call op body. __invoke will delegate
+ // to this function.
+ SmallVector<CanQualType, 4> ArgTypes;
+ for (auto I = FnInfo.arg_begin(); I != FnInfo.arg_end(); ++I)
+ ArgTypes.push_back(I->type);
+ *ImplFnInfo = &CGM.getTypes().arrangeLLVMFunctionInfo(
+ FnInfo.getReturnType(), FnInfoOpts::IsDelegateCall, ArgTypes,
+ FnInfo.getExtInfo(), {}, FnInfo.getRequiredArgs());
+
+ // Create mangled name as if this was a method named __impl. If for some
+ // reason the name doesn't look as expected then just tack __impl to the
+ // front.
+ // TODO: Use the name mangler to produce the right name instead of using
+ // string replacement.
+ StringRef CallOpName = CallOpFn->getName();
+ std::string ImplName;
+ if (size_t Pos = CallOpName.find_first_of("<lambda"))
+ ImplName = ("?__impl@" + CallOpName.drop_front(Pos)).str();
+ else
+ ImplName = ("__impl" + CallOpName).str();
+
+ llvm::Function *Fn = CallOpFn->getParent()->getFunction(ImplName);
+ if (!Fn) {
+ Fn = llvm::Function::Create(CGM.getTypes().GetFunctionType(**ImplFnInfo),
+ llvm::GlobalValue::InternalLinkage, ImplName,
+ CGM.getModule());
+ CGM.SetInternalFunctionAttributes(CallOp, Fn, **ImplFnInfo);
+
+ const GlobalDecl &GD = GlobalDecl(CallOp);
+ const auto *D = cast<FunctionDecl>(GD.getDecl());
+ CodeGenFunction(CGM).GenerateCode(GD, Fn, **ImplFnInfo);
+ CGM.SetLLVMFunctionAttributesForDefinition(D, Fn);
+ }
+ *ImplFn = Fn;
}
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGCoroutine.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGCoroutine.cpp
index 8437cda79beb..810ae7d51ec1 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CGCoroutine.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/CGCoroutine.cpp
@@ -139,6 +139,36 @@ static bool memberCallExpressionCanThrow(const Expr *E) {
return true;
}
+/// Return true when the coroutine handle may escape from the await-suspend
+/// (`awaiter.await_suspend(std::coroutine_handle)` expression).
+/// Return false only when the coroutine wouldn't escape in the await-suspend
+/// for sure.
+///
+/// While it is always safe to return true, return falses can bring better
+/// performances.
+///
+/// See https://github.com/llvm/llvm-project/issues/56301 and
+/// https://reviews.llvm.org/D157070 for the example and the full discussion.
+///
+/// FIXME: It will be much better to perform such analysis in the middle end.
+/// See the comments in `CodeGenFunction::EmitCall` for example.
+static bool MayCoroHandleEscape(CoroutineSuspendExpr const &S) {
+ CXXRecordDecl *Awaiter =
+ S.getCommonExpr()->getType().getNonReferenceType()->getAsCXXRecordDecl();
+
+ // Return true conservatively if the awaiter type is not a record type.
+ if (!Awaiter)
+ return true;
+
+ // In case the awaiter type is empty, the suspend wouldn't leak the coroutine
+ // handle.
+ //
+ // TODO: We can improve this by looking into the implementation of
+ // await-suspend and see if the coroutine handle is passed to foreign
+ // functions.
+ return !Awaiter->field_empty();
+}
+
// Emit suspend expression which roughly looks like:
//
// auto && x = CommonExpr();
@@ -199,8 +229,11 @@ static LValueOrRValue emitSuspendExpression(CodeGenFunction &CGF, CGCoroData &Co
auto *SaveCall = Builder.CreateCall(CoroSave, {NullPtr});
CGF.CurCoro.InSuspendBlock = true;
+ CGF.CurCoro.MayCoroHandleEscape = MayCoroHandleEscape(S);
auto *SuspendRet = CGF.EmitScalarExpr(S.getSuspendExpr());
CGF.CurCoro.InSuspendBlock = false;
+ CGF.CurCoro.MayCoroHandleEscape = false;
+
if (SuspendRet != nullptr && SuspendRet->getType()->isIntegerTy(1)) {
// Veto suspension if requested by bool returning await_suspend.
BasicBlock *RealSuspendBlock =
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGDebugInfo.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGDebugInfo.cpp
index f049a682cfed..d8eb2aecb87a 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -391,12 +391,14 @@ llvm::DIFile *CGDebugInfo::getOrCreateFile(SourceLocation Loc) {
SourceManager &SM = CGM.getContext().getSourceManager();
StringRef FileName;
FileID FID;
+ std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
if (Loc.isInvalid()) {
// The DIFile used by the CU is distinct from the main source file. Call
// createFile() below for canonicalization if the source file was specified
// with an absolute path.
FileName = TheCU->getFile()->getFilename();
+ CSInfo = TheCU->getFile()->getChecksum();
} else {
PresumedLoc PLoc = SM.getPresumedLoc(Loc);
FileName = PLoc.getFilename();
@@ -417,13 +419,14 @@ llvm::DIFile *CGDebugInfo::getOrCreateFile(SourceLocation Loc) {
return cast<llvm::DIFile>(V);
}
+ // Put Checksum at a scope where it will persist past the createFile call.
SmallString<64> Checksum;
-
- std::optional<llvm::DIFile::ChecksumKind> CSKind =
+ if (!CSInfo) {
+ std::optional<llvm::DIFile::ChecksumKind> CSKind =
computeChecksum(FID, Checksum);
- std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
- if (CSKind)
- CSInfo.emplace(*CSKind, Checksum);
+ if (CSKind)
+ CSInfo.emplace(*CSKind, Checksum);
+ }
return createFile(FileName, CSInfo, getSource(SM, SM.getFileID(Loc)));
}
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGDebugInfo.h b/contrib/llvm-project/clang/lib/CodeGen/CGDebugInfo.h
index 1fd08626358b..58ee6dd64c4f 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CGDebugInfo.h
+++ b/contrib/llvm-project/clang/lib/CodeGen/CGDebugInfo.h
@@ -148,7 +148,7 @@ class CGDebugInfo {
llvm::BumpPtrAllocator DebugInfoNames;
StringRef CWDName;
- llvm::StringMap<llvm::TrackingMDRef> DIFileCache;
+ llvm::DenseMap<const char *, llvm::TrackingMDRef> DIFileCache;
llvm::DenseMap<const FunctionDecl *, llvm::TrackingMDRef> SPCache;
/// Cache declarations relevant to DW_TAG_imported_declarations (C++
/// using declarations and global alias variables) that aren't covered
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGDecl.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGDecl.cpp
index b0d6eb05acc2..d99dcdba8e43 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CGDecl.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/CGDecl.cpp
@@ -202,7 +202,7 @@ void CodeGenFunction::EmitVarDecl(const VarDecl &D) {
return;
llvm::GlobalValue::LinkageTypes Linkage =
- CGM.getLLVMLinkageVarDefinition(&D, /*IsConstant=*/false);
+ CGM.getLLVMLinkageVarDefinition(&D);
// FIXME: We need to force the emission/use of a guard variable for
// some variables even if we can constant-evaluate them because
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGDeclCXX.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGDeclCXX.cpp
index be8fb6c274db..a9c88110d6f0 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CGDeclCXX.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/CGDeclCXX.cpp
@@ -279,8 +279,8 @@ llvm::Function *CodeGenFunction::createTLSAtExitStub(
}
const CGFunctionInfo &FI = CGM.getTypes().arrangeLLVMFunctionInfo(
- getContext().IntTy, /*instanceMethod=*/false, /*chainCall=*/false,
- {getContext().IntTy}, FunctionType::ExtInfo(), {}, RequiredArgs::All);
+ getContext().IntTy, FnInfoOpts::None, {getContext().IntTy},
+ FunctionType::ExtInfo(), {}, RequiredArgs::All);
// Get the stub function type, int(*)(int,...).
llvm::FunctionType *StubTy =
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGExpr.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGExpr.cpp
index ed6095f7cfeb..fc16b3133f73 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CGExpr.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/CGExpr.cpp
@@ -2692,8 +2692,7 @@ static LValue EmitGlobalNamedRegister(const VarDecl *VD, CodeGenModule &CGM) {
/// this context.
static bool canEmitSpuriousReferenceToVariable(CodeGenFunction &CGF,
const DeclRefExpr *E,
- const VarDecl *VD,
- bool IsConstant) {
+ const VarDecl *VD) {
// For a variable declared in an enclosing scope, do not emit a spurious
// reference even if we have a capture, as that will emit an unwarranted
// reference to our capture state, and will likely generate worse code than
@@ -2726,7 +2725,7 @@ static bool canEmitSpuriousReferenceToVariable(CodeGenFunction &CGF,
// We can emit a spurious reference only if the linkage implies that we'll
// be emitting a non-interposable symbol that will be retained until link
// time.
- switch (CGF.CGM.getLLVMLinkageVarDefinition(VD, IsConstant)) {
+ switch (CGF.CGM.getLLVMLinkageVarDefinition(VD)) {
case llvm::GlobalValue::ExternalLinkage:
case llvm::GlobalValue::LinkOnceODRLinkage:
case llvm::GlobalValue::WeakODRLinkage:
@@ -2757,7 +2756,7 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
// constant value directly instead.
if (E->isNonOdrUse() == NOUR_Constant &&
(VD->getType()->isReferenceType() ||
- !canEmitSpuriousReferenceToVariable(*this, E, VD, true))) {
+ !canEmitSpuriousReferenceToVariable(*this, E, VD))) {
VD->getAnyInitializer(VD);
llvm::Constant *Val = ConstantEmitter(*this).emitAbstract(
E->getLocation(), *VD->evaluateValue(), VD->getType());
@@ -2859,7 +2858,7 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
// some reason; most likely, because it's in an outer function.
} else if (VD->isStaticLocal()) {
llvm::Constant *var = CGM.getOrCreateStaticVarDecl(
- *VD, CGM.getLLVMLinkageVarDefinition(VD, /*IsConstant=*/false));
+ *VD, CGM.getLLVMLinkageVarDefinition(VD));
addr = Address(
var, ConvertTypeForMem(VD->getType()), getContext().getDeclAlign(VD));
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGExprConstant.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGExprConstant.cpp
index 353ee56839f3..942daa4aa577 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CGExprConstant.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/CGExprConstant.cpp
@@ -1918,7 +1918,7 @@ ConstantLValueEmitter::tryEmitBase(const APValue::LValueBase &base) {
if (VD->isLocalVarDecl()) {
return CGM.getOrCreateStaticVarDecl(
- *VD, CGM.getLLVMLinkageVarDefinition(VD, /*IsConstant=*/false));
+ *VD, CGM.getLLVMLinkageVarDefinition(VD));
}
}
}
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index a52ec8909b12..124eade4617f 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -1667,7 +1667,7 @@ Address CGOpenMPRuntime::getAddrOfDeclareTargetVar(const VarDecl *VD) {
auto AddrOfGlobal = [&VD, this]() { return CGM.GetAddrOfGlobal(VD); };
auto LinkageForVariable = [&VD, this]() {
- return CGM.getLLVMLinkageVarDefinition(VD, /*IsConstant=*/false);
+ return CGM.getLLVMLinkageVarDefinition(VD);
};
std::vector<llvm::GlobalVariable *> GeneratedRefs;
@@ -10151,6 +10151,13 @@ void CGOpenMPRuntime::registerTargetGlobalVariable(const VarDecl *VD,
std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
+
+ // If this is an 'extern' declaration we defer to the canonical definition and
+ // do not emit an offloading entry.
+ if (Res && *Res != OMPDeclareTargetDeclAttr::MT_Link &&
+ VD->hasExternalStorage())
+ return;
+
if (!Res) {
if (CGM.getLangOpts().OpenMPIsTargetDevice) {
// Register non-target variables being emitted in device code (debug info
@@ -10163,7 +10170,7 @@ void CGOpenMPRuntime::registerTargetGlobalVariable(const VarDecl *VD,
auto AddrOfGlobal = [&VD, this]() { return CGM.GetAddrOfGlobal(VD); };
auto LinkageForVariable = [&VD, this]() {
- return CGM.getLLVMLinkageVarDefinition(VD, /*IsConstant=*/false);
+ return CGM.getLLVMLinkageVarDefinition(VD);
};
std::vector<llvm::GlobalVariable *> GeneratedRefs;
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CodeGenABITypes.cpp b/contrib/llvm-project/clang/lib/CodeGen/CodeGenABITypes.cpp
index d3a16a1d5acc..a6073e1188d6 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CodeGenABITypes.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/CodeGenABITypes.cpp
@@ -65,9 +65,8 @@ CodeGen::arrangeFreeFunctionCall(CodeGenModule &CGM,
ArrayRef<CanQualType> argTypes,
FunctionType::ExtInfo info,
RequiredArgs args) {
- return CGM.getTypes().arrangeLLVMFunctionInfo(
- returnType, /*instanceMethod=*/false, /*chainCall=*/false, argTypes,
- info, {}, args);
+ return CGM.getTypes().arrangeLLVMFunctionInfo(returnType, FnInfoOpts::None,
+ argTypes, info, {}, args);
}
ImplicitCXXConstructorArgs
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp b/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp
index fab70b66d1d9..7ef893cb1a2d 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -572,7 +572,7 @@ llvm::ConstantInt *
CodeGenFunction::getUBSanFunctionTypeHash(QualType Ty) const {
// Remove any (C++17) exception specifications, to allow calling e.g. a
// noexcept function through a non-noexcept pointer.
- if (!isa<FunctionNoProtoType>(Ty))
+ if (!Ty->isFunctionNoProtoType())
Ty = getContext().getFunctionTypeWithExceptionSpec(Ty, EST_None);
std::string Mangled;
llvm::raw_string_ostream Out(Mangled);
@@ -683,6 +683,19 @@ static bool matchesStlAllocatorFn(const Decl *D, const ASTContext &Ctx) {
return true;
}
+bool CodeGenFunction::isInAllocaArgument(CGCXXABI &ABI, QualType Ty) {
+ const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();
+ return RD && ABI.getRecordArgABI(RD) == CGCXXABI::RAA_DirectInMemory;
+}
+
+bool CodeGenFunction::hasInAllocaArg(const CXXMethodDecl *MD) {
+ return getTarget().getTriple().getArch() == llvm::Triple::x86 &&
+ getTarget().getCXXABI().isMicrosoft() &&
+ llvm::any_of(MD->parameters(), [&](ParmVarDecl *P) {
+ return isInAllocaArgument(CGM.getCXXABI(), P->getType());
+ });
+}
+
/// Return the UBSan prologue signature for \p FD if one is available.
static llvm::Constant *getPrologueSignature(CodeGenModule &CGM,
const FunctionDecl *FD) {
@@ -1447,6 +1460,17 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
// The lambda static invoker function is special, because it forwards or
// clones the body of the function call operator (but is actually static).
EmitLambdaStaticInvokeBody(cast<CXXMethodDecl>(FD));
+ } else if (isa<CXXMethodDecl>(FD) &&
+ isLambdaCallOperator(cast<CXXMethodDecl>(FD)) &&
+ !FnInfo.isDelegateCall() &&
+ cast<CXXMethodDecl>(FD)->getParent()->getLambdaStaticInvoker() &&
+ hasInAllocaArg(cast<CXXMethodDecl>(FD))) {
+ // If emitting a lambda with static invoker on X86 Windows, change
+ // the call operator body.
+ // Make sure that this is a call operator with an inalloca arg and check
+ // for delegate call to make sure this is the original call op and not the
+ // new forwarding function for the static invoker.
+ EmitLambdaInAllocaCallOpBody(cast<CXXMethodDecl>(FD));
} else if (FD->isDefaulted() && isa<CXXMethodDecl>(FD) &&
(cast<CXXMethodDecl>(FD)->isCopyAssignmentOperator() ||
cast<CXXMethodDecl>(FD)->isMoveAssignmentOperator())) {
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.h b/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.h
index 409f48a04906..28ec2b970072 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.h
+++ b/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.h
@@ -334,6 +334,7 @@ public:
struct CGCoroInfo {
std::unique_ptr<CGCoroData> Data;
bool InSuspendBlock = false;
+ bool MayCoroHandleEscape = false;
CGCoroInfo();
~CGCoroInfo();
};
@@ -347,6 +348,10 @@ public:
return isCoroutine() && CurCoro.InSuspendBlock;
}
+ bool mayCoroHandleEscape() const {
+ return isCoroutine() && CurCoro.MayCoroHandleEscape;
+ }
+
/// CurGD - The GlobalDecl for the current function being compiled.
GlobalDecl CurGD;
@@ -1963,6 +1968,9 @@ private:
/// Check if the return value of this function requires sanitization.
bool requiresReturnValueCheck() const;
+ bool isInAllocaArgument(CGCXXABI &ABI, QualType Ty);
+ bool hasInAllocaArg(const CXXMethodDecl *MD);
+
llvm::BasicBlock *TerminateLandingPad = nullptr;
llvm::BasicBlock *TerminateHandler = nullptr;
llvm::SmallVector<llvm::BasicBlock *, 2> TrapBBs;
@@ -2227,10 +2235,17 @@ public:
void EmitBlockWithFallThrough(llvm::BasicBlock *BB, const Stmt *S);
void EmitForwardingCallToLambda(const CXXMethodDecl *LambdaCallOperator,
- CallArgList &CallArgs);
+ CallArgList &CallArgs,
+ const CGFunctionInfo *CallOpFnInfo = nullptr,
+ llvm::Constant *CallOpFn = nullptr);
void EmitLambdaBlockInvokeBody();
- void EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD);
void EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD);
+ void EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD,
+ CallArgList &CallArgs);
+ void EmitLambdaInAllocaImplFn(const CXXMethodDecl *CallOp,
+ const CGFunctionInfo **ImplFnInfo,
+ llvm::Function **ImplFn);
+ void EmitLambdaInAllocaCallOpBody(const CXXMethodDecl *MD);
void EmitLambdaVLACapture(const VariableArrayType *VAT, LValue LV) {
EmitStoreThroughLValue(RValue::get(VLASizeMap[VAT->getSizeExpr()]), LV);
}
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp b/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp
index 07a9dec12f6f..f09d1129b128 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1974,7 +1974,7 @@ CodeGenModule::getFunctionLinkage(GlobalDecl GD) {
return llvm::GlobalValue::InternalLinkage;
}
- return getLLVMLinkageForDeclarator(D, Linkage, /*IsConstantVariable=*/false);
+ return getLLVMLinkageForDeclarator(D, Linkage);
}
llvm::ConstantInt *CodeGenModule::CreateCrossDsoCfiTypeId(llvm::Metadata *MD) {
@@ -2386,7 +2386,7 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
// functions. If the current target's C++ ABI requires this and this is a
// member function, set its alignment accordingly.
if (getTarget().getCXXABI().areMemberFunctionsAligned()) {
- if (F->getPointerAlignment(getDataLayout()) < 2 && isa<CXXMethodDecl>(D))
+ if (isa<CXXMethodDecl>(D) && F->getPointerAlignment(getDataLayout()) < 2)
F->setAlignment(std::max(llvm::Align(2), F->getAlign().valueOrOne()));
}
@@ -3605,6 +3605,13 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) {
// Emit declaration of the must-be-emitted declare target variable.
if (std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) {
+
+ // If this variable has external storage and doesn't require special
+ // link handling we defer to its canonical definition.
+ if (VD->hasExternalStorage() &&
+ Res != OMPDeclareTargetDeclAttr::MT_Link)
+ return;
+
bool UnifiedMemoryEnabled =
getOpenMPRuntime().hasRequiresUnifiedSharedMemory();
if ((*Res == OMPDeclareTargetDeclAttr::MT_To ||
@@ -3638,6 +3645,7 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) {
if (MustBeEmitted(Global) && MayBeEmittedEagerly(Global)) {
// Emit the definition if it can't be deferred.
EmitGlobalDefinition(GD);
+ addEmittedDeferredDecl(GD);
return;
}
@@ -3657,7 +3665,6 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) {
// The value must be emitted, but cannot be emitted eagerly.
assert(!MayBeEmittedEagerly(Global));
addDeferredDeclToEmit(GD);
- EmittedDeferredDecls[MangledName] = GD;
} else {
// Otherwise, remember that we saw a deferred decl with this name. The
// first use of the mangled name will cause it to move into
@@ -4397,7 +4404,6 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(
// DeferredDeclsToEmit list, and remove it from DeferredDecls (since we
// don't need it anymore).
addDeferredDeclToEmit(DDI->second);
- EmittedDeferredDecls[DDI->first] = DDI->second;
DeferredDecls.erase(DDI);
// Otherwise, there are cases we have to worry about where we're
@@ -4678,7 +4684,6 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName, llvm::Type *Ty,
// Move the potentially referenced deferred decl to the DeferredDeclsToEmit
// list, and remove it from DeferredDecls (since we don't need it anymore).
addDeferredDeclToEmit(DDI->second);
- EmittedDeferredDecls[DDI->first] = DDI->second;
DeferredDecls.erase(DDI);
}
@@ -5221,8 +5226,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
AddGlobalAnnotations(D, GV);
// Set the llvm linkage type as appropriate.
- llvm::GlobalValue::LinkageTypes Linkage =
- getLLVMLinkageVarDefinition(D, GV->isConstant());
+ llvm::GlobalValue::LinkageTypes Linkage = getLLVMLinkageVarDefinition(D);
// CUDA B.2.1 "The __device__ qualifier declares a variable that resides on
// the device. [...]"
@@ -5415,8 +5419,9 @@ static bool isVarDeclStrongDefinition(const ASTContext &Context,
return false;
}
-llvm::GlobalValue::LinkageTypes CodeGenModule::getLLVMLinkageForDeclarator(
- const DeclaratorDecl *D, GVALinkage Linkage, bool IsConstantVariable) {
+llvm::GlobalValue::LinkageTypes
+CodeGenModule::getLLVMLinkageForDeclarator(const DeclaratorDecl *D,
+ GVALinkage Linkage) {
if (Linkage == GVA_Internal)
return llvm::Function::InternalLinkage;
@@ -5486,10 +5491,10 @@ llvm::GlobalValue::LinkageTypes CodeGenModule::getLLVMLinkageForDeclarator(
return llvm::GlobalVariable::ExternalLinkage;
}
-llvm::GlobalValue::LinkageTypes CodeGenModule::getLLVMLinkageVarDefinition(
- const VarDecl *VD, bool IsConstant) {
+llvm::GlobalValue::LinkageTypes
+CodeGenModule::getLLVMLinkageVarDefinition(const VarDecl *VD) {
GVALinkage Linkage = getContext().GetGVALinkageForVariable(VD);
- return getLLVMLinkageForDeclarator(VD, Linkage, IsConstant);
+ return getLLVMLinkageForDeclarator(VD, Linkage);
}
/// Replace the uses of a function that was declared with a non-proto type.
@@ -5701,7 +5706,7 @@ void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) {
Aliasee = GetOrCreateLLVMGlobal(AA->getAliasee(), DeclTy, LangAS::Default,
/*D=*/nullptr);
if (const auto *VD = dyn_cast<VarDecl>(GD.getDecl()))
- LT = getLLVMLinkageVarDefinition(VD, D->getType().isConstQualified());
+ LT = getLLVMLinkageVarDefinition(VD);
else
LT = getFunctionLinkage(GD);
}
@@ -6332,8 +6337,7 @@ ConstantAddress CodeGenModule::GetAddrOfGlobalTemporary(
}
// Create a global variable for this lifetime-extended temporary.
- llvm::GlobalValue::LinkageTypes Linkage =
- getLLVMLinkageVarDefinition(VD, Constant);
+ llvm::GlobalValue::LinkageTypes Linkage = getLLVMLinkageVarDefinition(VD);
if (Linkage == llvm::GlobalVariable::ExternalLinkage) {
const VarDecl *InitVD;
if (VD->isStaticDataMember() && VD->getAnyInitializer(InitVD) &&
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.h b/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.h
index 05cb217e2bee..dd97808c7775 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.h
+++ b/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.h
@@ -361,10 +361,19 @@ private:
llvm::DenseMap<llvm::StringRef, GlobalDecl> EmittedDeferredDecls;
void addEmittedDeferredDecl(GlobalDecl GD) {
- if (!llvm::isa<FunctionDecl>(GD.getDecl()))
+ // Reemission is only needed in incremental mode.
+ if (!Context.getLangOpts().IncrementalExtensions)
return;
- llvm::GlobalVariable::LinkageTypes L = getFunctionLinkage(GD);
- if (llvm::GlobalValue::isLinkOnceLinkage(L) ||
+
+ // Assume a linkage by default that does not need reemission.
+ auto L = llvm::GlobalValue::ExternalLinkage;
+ if (llvm::isa<FunctionDecl>(GD.getDecl()))
+ L = getFunctionLinkage(GD);
+ else if (auto *VD = llvm::dyn_cast<VarDecl>(GD.getDecl()))
+ L = getLLVMLinkageVarDefinition(VD);
+
+ if (llvm::GlobalValue::isInternalLinkage(L) ||
+ llvm::GlobalValue::isLinkOnceLinkage(L) ||
llvm::GlobalValue::isWeakLinkage(L)) {
EmittedDeferredDecls[getMangledName(GD)] = GD;
}
@@ -1321,12 +1330,11 @@ public:
/// Returns LLVM linkage for a declarator.
llvm::GlobalValue::LinkageTypes
- getLLVMLinkageForDeclarator(const DeclaratorDecl *D, GVALinkage Linkage,
- bool IsConstantVariable);
+ getLLVMLinkageForDeclarator(const DeclaratorDecl *D, GVALinkage Linkage);
/// Returns LLVM linkage for a declarator.
llvm::GlobalValue::LinkageTypes
- getLLVMLinkageVarDefinition(const VarDecl *VD, bool IsConstant);
+ getLLVMLinkageVarDefinition(const VarDecl *VD);
/// Emit all the global annotations.
void EmitGlobalAnnotations();
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CodeGenTypes.h b/contrib/llvm-project/clang/lib/CodeGen/CodeGenTypes.h
index 9088f77b95c3..a0e846d9a751 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CodeGenTypes.h
+++ b/contrib/llvm-project/clang/lib/CodeGen/CodeGenTypes.h
@@ -252,13 +252,11 @@ public:
/// this.
///
/// \param argTypes - must all actually be canonical as params
- const CGFunctionInfo &arrangeLLVMFunctionInfo(CanQualType returnType,
- bool instanceMethod,
- bool chainCall,
- ArrayRef<CanQualType> argTypes,
- FunctionType::ExtInfo info,
- ArrayRef<FunctionProtoType::ExtParameterInfo> paramInfos,
- RequiredArgs args);
+ const CGFunctionInfo &arrangeLLVMFunctionInfo(
+ CanQualType returnType, FnInfoOpts opts, ArrayRef<CanQualType> argTypes,
+ FunctionType::ExtInfo info,
+ ArrayRef<FunctionProtoType::ExtParameterInfo> paramInfos,
+ RequiredArgs args);
/// Compute a new LLVM record layout object for the given record.
std::unique_ptr<CGRecordLayout> ComputeRecordLayout(const RecordDecl *D,
diff --git a/contrib/llvm-project/clang/lib/CodeGen/ItaniumCXXABI.cpp b/contrib/llvm-project/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 79a926cb9edd..ede9efb019ce 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -2839,7 +2839,7 @@ static bool isThreadWrapperReplaceable(const VarDecl *VD,
static llvm::GlobalValue::LinkageTypes
getThreadLocalWrapperLinkage(const VarDecl *VD, CodeGen::CodeGenModule &CGM) {
llvm::GlobalValue::LinkageTypes VarLinkage =
- CGM.getLLVMLinkageVarDefinition(VD, /*IsConstant=*/false);
+ CGM.getLLVMLinkageVarDefinition(VD);
// For internal linkage variables, we don't need an external or weak wrapper.
if (llvm::GlobalValue::isLocalLinkage(VarLinkage))
diff --git a/contrib/llvm-project/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/contrib/llvm-project/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index a692abaf3b75..a14efbdba76b 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -1379,8 +1379,7 @@ llvm::GlobalValue::LinkageTypes MicrosoftCXXABI::getCXXDestructorLinkage(
case Dtor_Base:
// The base destructor most closely tracks the user-declared constructor, so
// we delegate back to the normal declarator case.
- return CGM.getLLVMLinkageForDeclarator(Dtor, Linkage,
- /*IsConstantVariable=*/false);
+ return CGM.getLLVMLinkageForDeclarator(Dtor, Linkage);
case Dtor_Complete:
// The complete destructor is like an inline function, but it may be
// imported and therefore must be exported as well. This requires changing
diff --git a/contrib/llvm-project/clang/lib/CodeGen/Targets/LoongArch.cpp b/contrib/llvm-project/clang/lib/CodeGen/Targets/LoongArch.cpp
index 6391a8aeaa67..7483bf6d6d1e 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/Targets/LoongArch.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/Targets/LoongArch.cpp
@@ -148,6 +148,13 @@ bool LoongArchABIInfo::detectFARsEligibleStructHelper(
if (const ConstantArrayType *ATy = getContext().getAsConstantArrayType(Ty)) {
uint64_t ArraySize = ATy->getSize().getZExtValue();
QualType EltTy = ATy->getElementType();
+ // Non-zero-length arrays of empty records make the struct ineligible to be
+ // passed via FARs in C++.
+ if (const auto *RTy = EltTy->getAs<RecordType>()) {
+ if (ArraySize != 0 && isa<CXXRecordDecl>(RTy->getDecl()) &&
+ isEmptyRecord(getContext(), EltTy, true, true))
+ return false;
+ }
CharUnits EltSize = getContext().getTypeSizeInChars(EltTy);
for (uint64_t i = 0; i < ArraySize; ++i) {
if (!detectFARsEligibleStructHelper(EltTy, CurOff, Field1Ty, Field1Off,
@@ -163,7 +170,7 @@ bool LoongArchABIInfo::detectFARsEligibleStructHelper(
// copy constructor are not eligible for the FP calling convention.
if (getRecordArgABI(Ty, CGT.getCXXABI()))
return false;
- if (isEmptyRecord(getContext(), Ty, true))
+ if (isEmptyRecord(getContext(), Ty, true, true))
return true;
const RecordDecl *RD = RTy->getDecl();
// Unions aren't eligible unless they're empty (which is caught above).
@@ -222,6 +229,8 @@ bool LoongArchABIInfo::detectFARsEligibleStruct(
if (!detectFARsEligibleStructHelper(Ty, CharUnits::Zero(), Field1Ty,
Field1Off, Field2Ty, Field2Off))
return false;
+ if (!Field1Ty)
+ return false;
// Not really a candidate if we have a single int but no float.
if (Field1Ty && !Field2Ty && !Field1Ty->isFloatingPointTy())
return false;
diff --git a/contrib/llvm-project/clang/lib/CodeGen/Targets/RISCV.cpp b/contrib/llvm-project/clang/lib/CodeGen/Targets/RISCV.cpp
index b6d8ae462675..b12c3025f607 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/Targets/RISCV.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/Targets/RISCV.cpp
@@ -8,7 +8,6 @@
#include "ABIInfoImpl.h"
#include "TargetInfo.h"
-#include "llvm/TargetParser/RISCVTargetParser.h"
using namespace clang;
using namespace clang::CodeGen;
@@ -152,6 +151,13 @@ bool RISCVABIInfo::detectFPCCEligibleStructHelper(QualType Ty, CharUnits CurOff,
if (const ConstantArrayType *ATy = getContext().getAsConstantArrayType(Ty)) {
uint64_t ArraySize = ATy->getSize().getZExtValue();
QualType EltTy = ATy->getElementType();
+ // Non-zero-length arrays of empty records make the struct ineligible for
+ // the FP calling convention in C++.
+ if (const auto *RTy = EltTy->getAs<RecordType>()) {
+ if (ArraySize != 0 && isa<CXXRecordDecl>(RTy->getDecl()) &&
+ isEmptyRecord(getContext(), EltTy, true, true))
+ return false;
+ }
CharUnits EltSize = getContext().getTypeSizeInChars(EltTy);
for (uint64_t i = 0; i < ArraySize; ++i) {
bool Ret = detectFPCCEligibleStructHelper(EltTy, CurOff, Field1Ty,
@@ -168,7 +174,7 @@ bool RISCVABIInfo::detectFPCCEligibleStructHelper(QualType Ty, CharUnits CurOff,
// copy constructor are not eligible for the FP calling convention.
if (getRecordArgABI(Ty, CGT.getCXXABI()))
return false;
- if (isEmptyRecord(getContext(), Ty, true))
+ if (isEmptyRecord(getContext(), Ty, true, true))
return true;
const RecordDecl *RD = RTy->getDecl();
// Unions aren't eligible unless they're empty (which is caught above).
@@ -238,6 +244,8 @@ bool RISCVABIInfo::detectFPCCEligibleStruct(QualType Ty, llvm::Type *&Field1Ty,
NeededArgFPRs = 0;
bool IsCandidate = detectFPCCEligibleStructHelper(
Ty, CharUnits::Zero(), Field1Ty, Field1Off, Field2Ty, Field2Off);
+ if (!Field1Ty)
+ return false;
// Not really a candidate if we have a single int but no float.
if (Field1Ty && !Field2Ty && !Field1Ty->isFloatingPointTy())
return false;
@@ -315,11 +323,15 @@ ABIArgInfo RISCVABIInfo::coerceVLSVector(QualType Ty) const {
assert(VT->getElementType()->isBuiltinType() && "expected builtin type!");
- const auto *BT = VT->getElementType()->castAs<BuiltinType>();
- unsigned EltSize = getContext().getTypeSize(BT);
+ auto VScale =
+ getContext().getTargetInfo().getVScaleRange(getContext().getLangOpts());
+ // The MinNumElts is simplified from equation:
+ // NumElts / VScale =
+ // (EltSize * NumElts / (VScale * RVVBitsPerBlock))
+ // * (RVVBitsPerBlock / EltSize)
llvm::ScalableVectorType *ResType =
- llvm::ScalableVectorType::get(CGT.ConvertType(VT->getElementType()),
- llvm::RISCV::RVVBitsPerBlock / EltSize);
+ llvm::ScalableVectorType::get(CGT.ConvertType(VT->getElementType()),
+ VT->getNumElements() / VScale->first);
return ABIArgInfo::getDirect(ResType);
}
diff --git a/contrib/llvm-project/clang/lib/CodeGen/Targets/X86.cpp b/contrib/llvm-project/clang/lib/CodeGen/Targets/X86.cpp
index 31679d899a44..9f5c3258d65c 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/Targets/X86.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/Targets/X86.cpp
@@ -140,7 +140,8 @@ class X86_32ABIInfo : public ABIInfo {
Class classify(QualType Ty) const;
ABIArgInfo classifyReturnType(QualType RetTy, CCState &State) const;
- ABIArgInfo classifyArgumentType(QualType RetTy, CCState &State) const;
+ ABIArgInfo classifyArgumentType(QualType RetTy, CCState &State,
+ bool isDelegateCall) const;
/// Updates the number of available free registers, returns
/// true if any registers were allocated.
@@ -737,8 +738,8 @@ void X86_32ABIInfo::runVectorCallFirstPass(CGFunctionInfo &FI, CCState &State) c
}
}
-ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
- CCState &State) const {
+ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, CCState &State,
+ bool isDelegateCall) const {
// FIXME: Set alignment on indirect arguments.
bool IsFastCall = State.CC == llvm::CallingConv::X86_FastCall;
bool IsRegCall = State.CC == llvm::CallingConv::X86_RegCall;
@@ -753,6 +754,12 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
CGCXXABI::RecordArgABI RAA = getRecordArgABI(RT, getCXXABI());
if (RAA == CGCXXABI::RAA_Indirect) {
return getIndirectResult(Ty, false, State);
+ } else if (isDelegateCall) {
+ // Avoid having different alignments on delegate call args by always
+ // setting the alignment to 4, which is what we do for inallocas.
+ ABIArgInfo Res = getIndirectResult(Ty, false, State);
+ Res.setIndirectAlign(CharUnits::fromQuantity(4));
+ return Res;
} else if (RAA == CGCXXABI::RAA_DirectInMemory) {
// The field index doesn't matter, we'll fix it up later.
return ABIArgInfo::getInAlloca(/*FieldIndex=*/0);
@@ -940,7 +947,8 @@ void X86_32ABIInfo::computeInfo(CGFunctionInfo &FI) const {
if (State.IsPreassigned.test(I))
continue;
- Args[I].info = classifyArgumentType(Args[I].type, State);
+ Args[I].info =
+ classifyArgumentType(Args[I].type, State, FI.isDelegateCall());
UsedInAlloca |= (Args[I].info.getKind() == ABIArgInfo::InAlloca);
}
diff --git a/contrib/llvm-project/clang/lib/Driver/Driver.cpp b/contrib/llvm-project/clang/lib/Driver/Driver.cpp
index 488350169efa..bdbdad9362e1 100644
--- a/contrib/llvm-project/clang/lib/Driver/Driver.cpp
+++ b/contrib/llvm-project/clang/lib/Driver/Driver.cpp
@@ -4741,13 +4741,8 @@ Action *Driver::ConstructPhaseAction(
}
case phases::Backend: {
if (isUsingLTO() && TargetDeviceOffloadKind == Action::OFK_None) {
- types::ID Output;
- if (Args.hasArg(options::OPT_S))
- Output = types::TY_LTO_IR;
- else if (Args.hasArg(options::OPT_ffat_lto_objects))
- Output = types::TY_PP_Asm;
- else
- Output = types::TY_LTO_BC;
+ types::ID Output =
+ Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
return C.MakeAction<BackendJobAction>(Input, Output);
}
if (isUsingLTO(/* IsOffload */ true) &&
@@ -4941,6 +4936,12 @@ void Driver::BuildJobs(Compilation &C) const {
(void)C.getArgs().hasArg(options::OPT_driver_mode);
(void)C.getArgs().hasArg(options::OPT_rsp_quoting);
+ bool HasAssembleJob = llvm::any_of(C.getJobs(), [](auto &J) {
+ // Match ClangAs and other derived assemblers of Tool. ClangAs uses a
+ // longer ShortName "clang integrated assembler" while other assemblers just
+ // use "assembler".
+ return strstr(J.getCreator().getShortName(), "assembler");
+ });
for (Arg *A : C.getArgs()) {
// FIXME: It would be nice to be able to send the argument to the
// DiagnosticsEngine, so that extra values, position, and so on could be
@@ -4970,7 +4971,7 @@ void Driver::BuildJobs(Compilation &C) const {
// already been warned about.
if (!IsCLMode() || !A->getOption().matches(options::OPT_UNKNOWN)) {
if (A->getOption().hasFlag(options::TargetSpecific) &&
- !A->isIgnoredTargetSpecific()) {
+ !A->isIgnoredTargetSpecific() && !HasAssembleJob) {
Diag(diag::err_drv_unsupported_opt_for_target)
<< A->getSpelling() << getTargetTriple();
} else {
diff --git a/contrib/llvm-project/clang/lib/Driver/SanitizerArgs.cpp b/contrib/llvm-project/clang/lib/Driver/SanitizerArgs.cpp
index c3ce13f93464..12fe55be9113 100644
--- a/contrib/llvm-project/clang/lib/Driver/SanitizerArgs.cpp
+++ b/contrib/llvm-project/clang/lib/Driver/SanitizerArgs.cpp
@@ -37,6 +37,8 @@ static const SanitizerMask NeedsUbsanCxxRt =
SanitizerKind::Vptr | SanitizerKind::CFI;
static const SanitizerMask NotAllowedWithTrap = SanitizerKind::Vptr;
static const SanitizerMask NotAllowedWithMinimalRuntime = SanitizerKind::Vptr;
+static const SanitizerMask NotAllowedWithExecuteOnly =
+ SanitizerKind::Function | SanitizerKind::KCFI;
static const SanitizerMask RequiresPIE =
SanitizerKind::DataFlow | SanitizerKind::Scudo;
static const SanitizerMask NeedsUnwindTables =
@@ -141,6 +143,16 @@ static std::string describeSanitizeArg(const llvm::opt::Arg *A,
/// Sanitizers set.
static std::string toString(const clang::SanitizerSet &Sanitizers);
+/// Return true if an execute-only target disallows data access to code
+/// sections.
+static bool isExecuteOnlyTarget(const llvm::Triple &Triple,
+ const llvm::opt::ArgList &Args) {
+ if (Triple.isPS5())
+ return true;
+ return Args.hasFlagNoClaim(options::OPT_mexecute_only,
+ options::OPT_mno_execute_only, false);
+}
+
static void validateSpecialCaseListFormat(const Driver &D,
std::vector<std::string> &SCLFiles,
unsigned MalformedSCLErrorDiagID,
@@ -395,6 +407,22 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
DiagnosedKinds |= SanitizerKind::Function;
}
}
+ // -fsanitize=function and -fsanitize=kcfi instrument indirect function
+ // calls to load a type hash before the function label. Therefore, an
+ // execute-only target doesn't support the function and kcfi sanitizers.
+ const llvm::Triple &Triple = TC.getTriple();
+ if (isExecuteOnlyTarget(Triple, Args)) {
+ if (SanitizerMask KindsToDiagnose =
+ Add & NotAllowedWithExecuteOnly & ~DiagnosedKinds) {
+ if (DiagnoseErrors) {
+ std::string Desc = describeSanitizeArg(Arg, KindsToDiagnose);
+ D.Diag(diag::err_drv_argument_not_allowed_with)
+ << Desc << Triple.str();
+ }
+ DiagnosedKinds |= KindsToDiagnose;
+ }
+ Add &= ~NotAllowedWithExecuteOnly;
+ }
// FIXME: Make CFI on member function calls compatible with cross-DSO CFI.
// There are currently two problems:
@@ -457,6 +485,10 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
if (MinimalRuntime) {
Add &= ~NotAllowedWithMinimalRuntime;
}
+ // NotAllowedWithExecuteOnly is silently discarded on an execute-only
+ // target if implicitly enabled through group expansion.
+ if (isExecuteOnlyTarget(Triple, Args))
+ Add &= ~NotAllowedWithExecuteOnly;
if (CfiCrossDso)
Add &= ~SanitizerKind::CFIMFCall;
Add &= Supported;
diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChain.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChain.cpp
index d60fdbc17968..8dafc3d481c2 100644
--- a/contrib/llvm-project/clang/lib/Driver/ToolChain.cpp
+++ b/contrib/llvm-project/clang/lib/Driver/ToolChain.cpp
@@ -427,6 +427,12 @@ ToolChain::getDefaultUnwindTableLevel(const ArgList &Args) const {
return UnwindTableLevel::None;
}
+unsigned ToolChain::GetDefaultDwarfVersion() const {
+ // TODO: Remove the RISC-V special case when R_RISCV_SET_ULEB128 linker
+ // support becomes more widely available.
+ return getTriple().isRISCV() ? 4 : 5;
+}
+
Tool *ToolChain::getClang() const {
if (!Clang)
Clang.reset(new tools::Clang(*this, useIntegratedBackend()));
diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/AIX.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/AIX.cpp
index 97217eba9ca0..bfc86d9f3471 100644
--- a/contrib/llvm-project/clang/lib/Driver/ToolChains/AIX.cpp
+++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/AIX.cpp
@@ -30,6 +30,7 @@ void aix::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfoList &Inputs,
const ArgList &Args,
const char *LinkingOutput) const {
+ const Driver &D = getToolChain().getDriver();
ArgStringList CmdArgs;
const bool IsArch32Bit = getToolChain().getTriple().isArch32Bit();
@@ -38,6 +39,11 @@ void aix::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
if (!IsArch32Bit && !IsArch64Bit)
llvm_unreachable("Unsupported bit width value.");
+ if (Arg *A = C.getArgs().getLastArg(options::OPT_G)) {
+ D.Diag(diag::err_drv_unsupported_opt_for_target)
+ << A->getSpelling() << D.getTargetTriple();
+ }
+
// Specify the mode in which the as(1) command operates.
if (IsArch32Bit) {
CmdArgs.push_back("-a32");
diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp
index 856ad58f3bd9..65925e9ed610 100644
--- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp
+++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp
@@ -12,6 +12,7 @@
#include "clang/Driver/Driver.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/Options.h"
+#include "llvm/TargetParser/Host.h"
#include "llvm/TargetParser/LoongArchTargetParser.h"
using namespace clang::driver;
@@ -126,23 +127,11 @@ void loongarch::getLoongArchTargetFeatures(const Driver &D,
const llvm::Triple &Triple,
const ArgList &Args,
std::vector<StringRef> &Features) {
- StringRef ArchName;
- if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
- if (!llvm::LoongArch::isValidArchName(A->getValue())) {
- D.Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
- return;
- }
+ std::string ArchName;
+ if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
ArchName = A->getValue();
- }
-
- // TODO: handle -march=native and -mtune=xx.
-
- // Select a default arch name.
- if (ArchName.empty() && Triple.isLoongArch64())
- ArchName = "loongarch64";
-
- if (!ArchName.empty())
- llvm::LoongArch::getArchFeatures(ArchName, Features);
+ ArchName = postProcessTargetCPUString(ArchName, Triple);
+ llvm::LoongArch::getArchFeatures(ArchName, Features);
// Select floating-point features determined by -mdouble-float,
// -msingle-float, -msoft-float and -mfpu.
@@ -187,3 +176,25 @@ void loongarch::getLoongArchTargetFeatures(const Driver &D,
if (Arg *A = Args.getLastArgNoClaim(options::OPT_mfpu_EQ))
A->ignoreTargetSpecific();
}
+
+std::string loongarch::postProcessTargetCPUString(const std::string &CPU,
+ const llvm::Triple &Triple) {
+ std::string CPUString = CPU;
+ if (CPUString == "native") {
+ CPUString = llvm::sys::getHostCPUName();
+ if (CPUString == "generic")
+ CPUString = llvm::LoongArch::getDefaultArch(Triple.isLoongArch64());
+ }
+ if (CPUString.empty())
+ CPUString = llvm::LoongArch::getDefaultArch(Triple.isLoongArch64());
+ return CPUString;
+}
+
+std::string loongarch::getLoongArchTargetCPU(const llvm::opt::ArgList &Args,
+ const llvm::Triple &Triple) {
+ std::string CPU;
+ // If we have -march, use that.
+ if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
+ CPU = A->getValue();
+ return postProcessTargetCPUString(CPU, Triple);
+}
diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/LoongArch.h b/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/LoongArch.h
index 0084474e7ed3..d8280cd836f8 100644
--- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/LoongArch.h
+++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/LoongArch.h
@@ -23,6 +23,12 @@ void getLoongArchTargetFeatures(const Driver &D, const llvm::Triple &Triple,
StringRef getLoongArchABI(const Driver &D, const llvm::opt::ArgList &Args,
const llvm::Triple &Triple);
+
+std::string postProcessTargetCPUString(const std::string &CPU,
+ const llvm::Triple &Triple);
+
+std::string getLoongArchTargetCPU(const llvm::opt::ArgList &Args,
+ const llvm::Triple &Triple);
} // end namespace loongarch
} // end namespace tools
} // end namespace driver
diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/X86.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/X86.cpp
index 286bac2e7a2b..cf2bc63d74ad 100644
--- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/X86.cpp
+++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/X86.cpp
@@ -267,4 +267,10 @@ void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple,
<< A->getSpelling() << Scope;
}
}
+
+ // -mno-gather, -mno-scatter support
+ if (Args.hasArg(options::OPT_mno_gather))
+ Features.push_back("+prefer-no-gather");
+ if (Args.hasArg(options::OPT_mno_scatter))
+ Features.push_back("+prefer-no-scatter");
}
diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp
index adb550d9c5da..47ec36b3a8ff 100644
--- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp
@@ -56,6 +56,7 @@
#include "llvm/Support/YAMLParser.h"
#include "llvm/TargetParser/ARMTargetParserCommon.h"
#include "llvm/TargetParser/Host.h"
+#include "llvm/TargetParser/LoongArchTargetParser.h"
#include "llvm/TargetParser/RISCVTargetParser.h"
#include <cctype>
@@ -1853,10 +1854,20 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args,
void Clang::AddLoongArchTargetArgs(const ArgList &Args,
ArgStringList &CmdArgs) const {
+ const llvm::Triple &Triple = getToolChain().getTriple();
+
CmdArgs.push_back("-target-abi");
- CmdArgs.push_back(loongarch::getLoongArchABI(getToolChain().getDriver(), Args,
- getToolChain().getTriple())
- .data());
+ CmdArgs.push_back(
+ loongarch::getLoongArchABI(getToolChain().getDriver(), Args, Triple)
+ .data());
+
+ // Handle -mtune.
+ if (const Arg *A = Args.getLastArg(options::OPT_mtune_EQ)) {
+ std::string TuneCPU = A->getValue();
+ TuneCPU = loongarch::postProcessTargetCPUString(TuneCPU, Triple);
+ CmdArgs.push_back("-tune-cpu");
+ CmdArgs.push_back(Args.MakeArgString(TuneCPU));
+ }
}
void Clang::AddMIPSTargetArgs(const ArgList &Args,
@@ -2052,6 +2063,12 @@ void Clang::AddPPCTargetArgs(const ArgList &Args,
} else if (V == "vec-extabi") {
VecExtabi = true;
A->claim();
+ } else if (V == "elfv1") {
+ ABIName = "elfv1";
+ A->claim();
+ } else if (V == "elfv2") {
+ ABIName = "elfv2";
+ A->claim();
} else if (V != "altivec")
// The ppc64 linux abis are all "altivec" abis by default. Accept and ignore
// the option if given as we don't have backend support for any targets
@@ -7359,22 +7376,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (SplitLTOUnit)
CmdArgs.push_back("-fsplit-lto-unit");
- if (Arg *A = Args.getLastArg(options::OPT_ffat_lto_objects,
- options::OPT_fno_fat_lto_objects)) {
- if (IsUsingLTO && A->getOption().matches(options::OPT_ffat_lto_objects)) {
- assert(LTOMode == LTOK_Full || LTOMode == LTOK_Thin);
- if (!Triple.isOSBinFormatELF()) {
- D.Diag(diag::err_drv_unsupported_opt_for_target)
- << A->getAsString(Args) << TC.getTripleString();
- }
- CmdArgs.push_back(Args.MakeArgString(
- Twine("-flto=") + (LTOMode == LTOK_Thin ? "thin" : "full")));
- CmdArgs.push_back("-flto-unit");
- CmdArgs.push_back("-ffat-lto-objects");
- A->render(Args, CmdArgs);
- }
- }
-
if (Arg *A = Args.getLastArg(options::OPT_fglobal_isel,
options::OPT_fno_global_isel)) {
CmdArgs.push_back("-mllvm");
diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 358d7565f47c..0d6907b8e5c7 100644
--- a/contrib/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -474,6 +474,10 @@ std::string tools::getCPUName(const Driver &D, const ArgList &Args,
case llvm::Triple::wasm32:
case llvm::Triple::wasm64:
return std::string(getWebAssemblyTargetCPU(Args));
+
+ case llvm::Triple::loongarch32:
+ case llvm::Triple::loongarch64:
+ return loongarch::getLoongArchTargetCPU(Args, T);
}
}
@@ -617,11 +621,6 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args,
PluginName + Suffix,
Plugin);
CmdArgs.push_back(Args.MakeArgString(Twine(PluginPrefix) + Plugin));
- } else {
- // Tell LLD to find and use .llvm.lto section in regular relocatable object
- // files
- if (Args.hasArg(options::OPT_ffat_lto_objects))
- CmdArgs.push_back("--fat-lto-objects");
}
const char *PluginOptPrefix = IsOSAIX ? "-bplugin_opt:" : "-plugin-opt=";
diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Gnu.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Gnu.cpp
index b64fff8b14be..40038dce47d8 100644
--- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -1874,6 +1874,12 @@ static bool findBiarchMultilibs(const Driver &D,
.flag("-m64", /*Disallow=*/true)
.flag("-mx32")
.makeMultilib();
+ Multilib Alt32sparc = MultilibBuilder()
+ .gccSuffix("/sparcv8plus")
+ .includeSuffix("/sparcv8plus")
+ .flag("-m32")
+ .flag("-m64", /*Disallow=*/true)
+ .makeMultilib();
// GCC toolchain for IAMCU doesn't have crtbegin.o, so look for libgcc.a.
FilterNonExistent NonExistent(
@@ -1885,10 +1891,14 @@ static bool findBiarchMultilibs(const Driver &D,
const bool IsX32 = TargetTriple.isX32();
if (TargetTriple.isArch32Bit() && !NonExistent(Alt32))
Want = WANT64;
+ if (TargetTriple.isArch32Bit() && !NonExistent(Alt32sparc))
+ Want = WANT64;
else if (TargetTriple.isArch64Bit() && IsX32 && !NonExistent(Altx32))
Want = WANT64;
else if (TargetTriple.isArch64Bit() && !IsX32 && !NonExistent(Alt64))
Want = WANT32;
+ else if (TargetTriple.isArch64Bit() && !NonExistent(Alt32sparc))
+ Want = WANT64;
else {
if (TargetTriple.isArch32Bit())
Want = NeedsBiarchSuffix ? WANT64 : WANT32;
@@ -1919,6 +1929,7 @@ static bool findBiarchMultilibs(const Driver &D,
Result.Multilibs.push_back(Alt64);
Result.Multilibs.push_back(Alt32);
Result.Multilibs.push_back(Altx32);
+ Result.Multilibs.push_back(Alt32sparc);
Result.Multilibs.FilterOut(NonExistent);
@@ -1932,7 +1943,8 @@ static bool findBiarchMultilibs(const Driver &D,
if (Result.SelectedMultilibs.back() == Alt64 ||
Result.SelectedMultilibs.back() == Alt32 ||
- Result.SelectedMultilibs.back() == Altx32)
+ Result.SelectedMultilibs.back() == Altx32 ||
+ Result.SelectedMultilibs.back() == Alt32sparc)
Result.BiarchSibling = Default;
return true;
@@ -2215,6 +2227,7 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes(
// so we need to find those /usr/gcc/*/lib/gcc libdirs and go with
// /usr/gcc/<version> as a prefix.
+ SmallVector<std::pair<GCCVersion, std::string>, 8> SolarisPrefixes;
std::string PrefixDir = concat(SysRoot, "/usr/gcc");
std::error_code EC;
for (llvm::vfs::directory_iterator LI = D.getVFS().dir_begin(PrefixDir, EC),
@@ -2232,8 +2245,13 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes(
if (!D.getVFS().exists(CandidateLibPath))
continue;
- Prefixes.push_back(CandidatePrefix);
+ SolarisPrefixes.emplace_back(
+ std::make_pair(CandidateVersion, CandidatePrefix));
}
+ // Sort in reverse order so GCCInstallationDetector::init picks the latest.
+ std::sort(SolarisPrefixes.rbegin(), SolarisPrefixes.rend());
+ for (auto p : SolarisPrefixes)
+ Prefixes.emplace_back(p.second);
return;
}
diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Hexagon.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Hexagon.cpp
index 7acc600a6aa4..aed4ab1955b4 100644
--- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Hexagon.cpp
+++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Hexagon.cpp
@@ -383,6 +383,10 @@ constructHexagonLinkArgs(Compilation &C, const JobAction &JA,
if (HTC.ShouldLinkCXXStdlib(Args))
HTC.AddCXXStdlibLibArgs(Args, CmdArgs);
}
+ const ToolChain::path_list &LibPaths = HTC.getFilePaths();
+ for (const auto &LibPath : LibPaths)
+ CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + LibPath));
+ Args.ClaimAllArgs(options::OPT_L);
return;
}
@@ -441,6 +445,7 @@ constructHexagonLinkArgs(Compilation &C, const JobAction &JA,
const ToolChain::path_list &LibPaths = HTC.getFilePaths();
for (const auto &LibPath : LibPaths)
CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + LibPath));
+ Args.ClaimAllArgs(options::OPT_L);
//----------------------------------------------------------------------------
//
diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Solaris.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Solaris.cpp
index 335a5a88cdfa..de5a69e4ca3f 100644
--- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Solaris.cpp
+++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Solaris.cpp
@@ -47,11 +47,24 @@ void solaris::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
Exec, CmdArgs, Inputs, Output));
}
+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))
+ return false;
+
+ Arg *A = Args.getLastArg(options::OPT_pie, options::OPT_no_pie,
+ options::OPT_nopie);
+ if (!A)
+ return TC.isPIEDefault(Args);
+ return A->getOption().matches(options::OPT_pie);
+}
+
void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
const ArgList &Args,
const char *LinkingOutput) const {
+ const bool IsPIE = getPIE(Args, getToolChain());
ArgStringList CmdArgs;
// Demangle C++ names in errors
@@ -62,6 +75,11 @@ void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("_start");
}
+ if (IsPIE) {
+ CmdArgs.push_back("-z");
+ CmdArgs.push_back("type=pie");
+ }
+
if (Args.hasArg(options::OPT_static)) {
CmdArgs.push_back("-Bstatic");
CmdArgs.push_back("-dn");
@@ -113,8 +131,13 @@ void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA,
values_xpg = "values-xpg4.o";
CmdArgs.push_back(
Args.MakeArgString(getToolChain().GetFilePath(values_xpg)));
- CmdArgs.push_back(
- Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
+
+ const char *crtbegin = nullptr;
+ if (Args.hasArg(options::OPT_shared) || IsPIE)
+ crtbegin = "crtbeginS.o";
+ else
+ crtbegin = "crtbegin.o";
+ CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(crtbegin)));
// Add crtfastmath.o if available and fast math is enabled.
getToolChain().addFastMathRuntimeIfAvailable(Args, CmdArgs);
}
@@ -151,24 +174,32 @@ void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-lgcc");
CmdArgs.push_back("-lm");
}
+ const SanitizerArgs &SA = getToolChain().getSanitizerArgs(Args);
if (NeedsSanitizerDeps) {
linkSanitizerRuntimeDeps(getToolChain(), CmdArgs);
// Work around Solaris/amd64 ld bug when calling __tls_get_addr directly.
// However, ld -z relax=transtls is available since Solaris 11.2, but not
// in Illumos.
- const SanitizerArgs &SA = getToolChain().getSanitizerArgs(Args);
if (getToolChain().getTriple().getArch() == llvm::Triple::x86_64 &&
(SA.needsAsanRt() || SA.needsStatsRt() ||
(SA.needsUbsanRt() && !SA.requiresMinimalRuntime())))
CmdArgs.push_back("-zrelax=transtls");
}
+ // Avoid AsanInitInternal cycle, Issue #64126.
+ if (getToolChain().getTriple().isX86() && SA.needsSharedRt() &&
+ SA.needsAsanRt())
+ CmdArgs.push_back("-znow");
}
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles,
options::OPT_r)) {
- CmdArgs.push_back(
- Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
+ if (Args.hasArg(options::OPT_shared) || IsPIE)
+ CmdArgs.push_back(
+ Args.MakeArgString(getToolChain().GetFilePath("crtendS.o")));
+ else
+ CmdArgs.push_back(
+ Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
CmdArgs.push_back(
Args.MakeArgString(getToolChain().GetFilePath("crtn.o")));
}
diff --git a/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp b/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp
index 32619bc56f7a..852437b9390f 100644
--- a/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp
@@ -581,7 +581,8 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {
ProbablyBracedList =
ProbablyBracedList ||
(NextTok->is(tok::l_brace) && LBraceStack.back().PrevTok &&
- LBraceStack.back().PrevTok->is(tok::identifier));
+ LBraceStack.back().PrevTok->isOneOf(tok::identifier,
+ tok::greater));
ProbablyBracedList =
ProbablyBracedList ||
@@ -2464,7 +2465,7 @@ bool UnwrappedLineParser::parseParens(TokenType AmpAmpTokenType) {
const auto *PrevPrev = Prev ? Prev->getPreviousNonComment() : nullptr;
const bool Blacklisted =
PrevPrev &&
- (PrevPrev->is(tok::kw___attribute) ||
+ (PrevPrev->isOneOf(tok::kw___attribute, tok::kw_decltype) ||
(SeenEqual &&
(PrevPrev->isOneOf(tok::kw_if, tok::kw_while) ||
PrevPrev->endsSequence(tok::kw_constexpr, tok::kw_if))));
diff --git a/contrib/llvm-project/clang/lib/Frontend/FrontendAction.cpp b/contrib/llvm-project/clang/lib/Frontend/FrontendAction.cpp
index c6f958a6077b..0bd4b01ff79d 100644
--- a/contrib/llvm-project/clang/lib/Frontend/FrontendAction.cpp
+++ b/contrib/llvm-project/clang/lib/Frontend/FrontendAction.cpp
@@ -15,6 +15,7 @@
#include "clang/Basic/FileEntry.h"
#include "clang/Basic/LangStandard.h"
#include "clang/Basic/Sarif.h"
+#include "clang/Basic/Stack.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendDiagnostic.h"
@@ -1150,6 +1151,10 @@ void ASTFrontendAction::ExecuteAction() {
CompilerInstance &CI = getCompilerInstance();
if (!CI.hasPreprocessor())
return;
+ // This is a fallback: If the client forgets to invoke this, we mark the
+ // current stack as the bottom. Though not optimal, this could help prevent
+ // stack overflow during deep recursion.
+ clang::noteBottomOfStack();
// FIXME: Move the truncation aspect of this into Sema, we delayed this till
// here so the source manager would be initialized.
diff --git a/contrib/llvm-project/clang/lib/Headers/__clang_cuda_math.h b/contrib/llvm-project/clang/lib/Headers/__clang_cuda_math.h
index e447590393ec..6166317f8f9d 100644
--- a/contrib/llvm-project/clang/lib/Headers/__clang_cuda_math.h
+++ b/contrib/llvm-project/clang/lib/Headers/__clang_cuda_math.h
@@ -36,7 +36,7 @@
// because the OpenMP overlay requires constexpr functions here but prior to
// c++14 void return functions could not be constexpr.
#pragma push_macro("__DEVICE_VOID__")
-#ifdef __OPENMP_NVPTX__ && defined(__cplusplus) && __cplusplus < 201402L
+#if defined(__OPENMP_NVPTX__) && defined(__cplusplus) && __cplusplus < 201402L
#define __DEVICE_VOID__ static __attribute__((always_inline, nothrow))
#else
#define __DEVICE_VOID__ __DEVICE__
diff --git a/contrib/llvm-project/clang/lib/Headers/__clang_hip_libdevice_declares.h b/contrib/llvm-project/clang/lib/Headers/__clang_hip_libdevice_declares.h
index ed576027cb5e..f15198b3d9f9 100644
--- a/contrib/llvm-project/clang/lib/Headers/__clang_hip_libdevice_declares.h
+++ b/contrib/llvm-project/clang/lib/Headers/__clang_hip_libdevice_declares.h
@@ -317,7 +317,7 @@ __device__ __attribute__((pure)) __2f16 __ocml_log_2f16(__2f16);
__device__ __attribute__((pure)) __2f16 __ocml_log10_2f16(__2f16);
__device__ __attribute__((pure)) __2f16 __ocml_log2_2f16(__2f16);
-#if HIP_VERSION_MAJOR * 100 + HIP_VERSION_MINOR >= 560 || 1
+#if HIP_VERSION_MAJOR * 100 + HIP_VERSION_MINOR >= 560
#define __DEPRECATED_SINCE_HIP_560(X) __attribute__((deprecated(X)))
#else
#define __DEPRECATED_SINCE_HIP_560(X)
diff --git a/contrib/llvm-project/clang/lib/Headers/cpuid.h b/contrib/llvm-project/clang/lib/Headers/cpuid.h
index 454f74e92f85..1ad6853a97c9 100644
--- a/contrib/llvm-project/clang/lib/Headers/cpuid.h
+++ b/contrib/llvm-project/clang/lib/Headers/cpuid.h
@@ -328,14 +328,4 @@ static __inline int __get_cpuid_count (unsigned int __leaf,
return 1;
}
-// If MS extensions are enabled, __cpuidex is defined as a builtin which will
-// conflict with the __cpuidex definition below.
-#ifndef _MSC_EXTENSIONS
-static __inline void __cpuidex (int __cpu_info[4], int __leaf, int __subleaf)
-{
- __cpuid_count(__leaf, __subleaf, __cpu_info[0], __cpu_info[1], __cpu_info[2],
- __cpu_info[3]);
-}
-#endif
-
#endif /* __CPUID_H */
diff --git a/contrib/llvm-project/clang/lib/Interpreter/IncrementalExecutor.cpp b/contrib/llvm-project/clang/lib/Interpreter/IncrementalExecutor.cpp
index 3f8d60630de4..2c4dfc9a611e 100644
--- a/contrib/llvm-project/clang/lib/Interpreter/IncrementalExecutor.cpp
+++ b/contrib/llvm-project/clang/lib/Interpreter/IncrementalExecutor.cpp
@@ -92,12 +92,19 @@ llvm::Error IncrementalExecutor::runCtors() const {
llvm::Expected<llvm::orc::ExecutorAddr>
IncrementalExecutor::getSymbolAddress(llvm::StringRef Name,
SymbolNameKind NameKind) const {
- auto Sym = (NameKind == LinkerName) ? Jit->lookupLinkerMangled(Name)
- : Jit->lookup(Name);
-
- if (!Sym)
- return Sym.takeError();
- return Sym;
+ using namespace llvm::orc;
+ auto SO = makeJITDylibSearchOrder({&Jit->getMainJITDylib(),
+ Jit->getPlatformJITDylib().get(),
+ Jit->getProcessSymbolsJITDylib().get()});
+
+ ExecutionSession &ES = Jit->getExecutionSession();
+
+ auto SymOrErr =
+ ES.lookup(SO, (NameKind == LinkerName) ? ES.intern(Name)
+ : Jit->mangleAndIntern(Name));
+ if (auto Err = SymOrErr.takeError())
+ return std::move(Err);
+ return SymOrErr->getAddress();
}
} // end namespace clang
diff --git a/contrib/llvm-project/clang/lib/Lex/LiteralSupport.cpp b/contrib/llvm-project/clang/lib/Lex/LiteralSupport.cpp
index 3b9913ac8ba4..a6f50832950c 100644
--- a/contrib/llvm-project/clang/lib/Lex/LiteralSupport.cpp
+++ b/contrib/llvm-project/clang/lib/Lex/LiteralSupport.cpp
@@ -57,6 +57,26 @@ static unsigned getCharWidth(tok::TokenKind kind, const TargetInfo &Target) {
}
}
+static unsigned getEncodingPrefixLen(tok::TokenKind kind) {
+ switch (kind) {
+ default:
+ llvm_unreachable("Unknown token type!");
+ case tok::char_constant:
+ case tok::string_literal:
+ return 0;
+ case tok::utf8_char_constant:
+ case tok::utf8_string_literal:
+ return 2;
+ case tok::wide_char_constant:
+ case tok::wide_string_literal:
+ case tok::utf16_char_constant:
+ case tok::utf16_string_literal:
+ case tok::utf32_char_constant:
+ case tok::utf32_string_literal:
+ return 1;
+ }
+}
+
static CharSourceRange MakeCharSourceRange(const LangOptions &Features,
FullSourceLoc TokLoc,
const char *TokBegin,
@@ -343,7 +363,9 @@ static unsigned ProcessCharEscape(const char *ThisTokBegin,
Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
diag::err_unevaluated_string_invalid_escape_sequence)
<< StringRef(EscapeBegin, ThisTokBuf - EscapeBegin);
+ HadError = true;
}
+
return ResultChar;
}
@@ -1917,9 +1939,22 @@ void StringLiteralParser::init(ArrayRef<Token> StringToks){
// Remember if we see any wide or utf-8/16/32 strings.
// Also check for illegal concatenations.
if (isUnevaluated() && Tok.getKind() != tok::string_literal) {
- if (Diags)
- Diags->Report(Tok.getLocation(), diag::err_unevaluated_string_prefix);
- hadError = true;
+ if (Diags) {
+ SourceLocation PrefixEndLoc = Lexer::AdvanceToTokenCharacter(
+ Tok.getLocation(), getEncodingPrefixLen(Tok.getKind()), SM,
+ Features);
+ CharSourceRange Range =
+ CharSourceRange::getCharRange({Tok.getLocation(), PrefixEndLoc});
+ StringRef Prefix(SM.getCharacterData(Tok.getLocation()),
+ getEncodingPrefixLen(Tok.getKind()));
+ Diags->Report(Tok.getLocation(),
+ Features.CPlusPlus26
+ ? diag::err_unevaluated_string_prefix
+ : diag::warn_unevaluated_string_prefix)
+ << Prefix << Features.CPlusPlus << FixItHint::CreateRemoval(Range);
+ }
+ if (Features.CPlusPlus26)
+ hadError = true;
} else if (Tok.isNot(Kind) && Tok.isNot(tok::string_literal)) {
if (isOrdinary()) {
Kind = Tok.getKind();
diff --git a/contrib/llvm-project/clang/lib/Parse/ParseDeclCXX.cpp b/contrib/llvm-project/clang/lib/Parse/ParseDeclCXX.cpp
index c1e09db2b3ee..d9ff6c42c502 100644
--- a/contrib/llvm-project/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/contrib/llvm-project/clang/lib/Parse/ParseDeclCXX.cpp
@@ -1016,10 +1016,23 @@ Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd) {
return nullptr;
}
- if (isTokenStringLiteral())
- AssertMessage = ParseUnevaluatedStringLiteralExpression();
- else if (getLangOpts().CPlusPlus26)
+ bool ParseAsExpression = false;
+ if (getLangOpts().CPlusPlus26) {
+ for (unsigned I = 0;; ++I) {
+ const Token &T = GetLookAheadToken(I);
+ if (T.is(tok::r_paren))
+ break;
+ if (!tok::isStringLiteral(Tok.getKind())) {
+ ParseAsExpression = true;
+ break;
+ }
+ }
+ }
+
+ if (ParseAsExpression)
AssertMessage = ParseConstantExpressionInExprEvalContext();
+ else if (tok::isStringLiteral(Tok.getKind()))
+ AssertMessage = ParseUnevaluatedStringLiteralExpression();
else {
Diag(Tok, diag::err_expected_string_literal)
<< /*Source='static_assert'*/ 1;
diff --git a/contrib/llvm-project/clang/lib/Parse/ParseTentative.cpp b/contrib/llvm-project/clang/lib/Parse/ParseTentative.cpp
index b7c83bbeb82e..664337052500 100644
--- a/contrib/llvm-project/clang/lib/Parse/ParseTentative.cpp
+++ b/contrib/llvm-project/clang/lib/Parse/ParseTentative.cpp
@@ -62,6 +62,7 @@ bool Parser::isCXXDeclarationStatement(
case tok::kw_static_assert:
case tok::kw__Static_assert:
return true;
+ case tok::coloncolon:
case tok::identifier: {
if (DisambiguatingWithExpression) {
RevertingTentativeParsingAction TPA(*this);
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaAvailability.cpp b/contrib/llvm-project/clang/lib/Sema/SemaAvailability.cpp
index 05ad42780e50..84c06566387c 100644
--- a/contrib/llvm-project/clang/lib/Sema/SemaAvailability.cpp
+++ b/contrib/llvm-project/clang/lib/Sema/SemaAvailability.cpp
@@ -123,6 +123,18 @@ ShouldDiagnoseAvailabilityInContext(Sema &S, AvailabilityResult K,
const NamedDecl *OffendingDecl) {
assert(K != AR_Available && "Expected an unavailable declaration here!");
+ // If this was defined using CF_OPTIONS, etc. then ignore the diagnostic.
+ auto DeclLoc = Ctx->getBeginLoc();
+ // This is only a problem in Foundation's C++ implementation for CF_OPTIONS.
+ if (DeclLoc.isMacroID() && S.getLangOpts().CPlusPlus &&
+ isa<TypedefDecl>(OffendingDecl)) {
+ StringRef MacroName = S.getPreprocessor().getImmediateMacroName(DeclLoc);
+ if (MacroName == "CF_OPTIONS" || MacroName == "OBJC_OPTIONS" ||
+ MacroName == "SWIFT_OPTIONS" || MacroName == "NS_OPTIONS") {
+ return false;
+ }
+ }
+
// Checks if we should emit the availability diagnostic in the context of C.
auto CheckContext = [&](const Decl *C) {
if (K == AR_NotYetIntroduced) {
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaCast.cpp b/contrib/llvm-project/clang/lib/Sema/SemaCast.cpp
index d65ecf52c523..b338d601db73 100644
--- a/contrib/llvm-project/clang/lib/Sema/SemaCast.cpp
+++ b/contrib/llvm-project/clang/lib/Sema/SemaCast.cpp
@@ -935,6 +935,14 @@ void CastOperation::CheckDynamicCast() {
<< isClangCL;
}
+ // For a dynamic_cast to a final type, IR generation might emit a reference
+ // to the vtable.
+ if (DestRecord) {
+ auto *DestDecl = DestRecord->getAsCXXRecordDecl();
+ if (DestDecl->isEffectivelyFinal())
+ Self.MarkVTableUsed(OpRange.getBegin(), DestDecl);
+ }
+
// Done. Everything else is run-time checks.
Kind = CK_Dynamic;
}
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaDecl.cpp b/contrib/llvm-project/clang/lib/Sema/SemaDecl.cpp
index a4bf57928470..21b5781a71cd 100644
--- a/contrib/llvm-project/clang/lib/Sema/SemaDecl.cpp
+++ b/contrib/llvm-project/clang/lib/Sema/SemaDecl.cpp
@@ -9154,7 +9154,8 @@ static FunctionDecl *CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,
bool HasPrototype =
(D.isFunctionDeclarator() && D.getFunctionTypeInfo().hasPrototype) ||
(D.getDeclSpec().isTypeRep() &&
- D.getDeclSpec().getRepAsType().get()->isFunctionProtoType()) ||
+ SemaRef.GetTypeFromParser(D.getDeclSpec().getRepAsType(), nullptr)
+ ->isFunctionProtoType()) ||
(!R->getAsAdjusted<FunctionType>() && R->isFunctionProtoType());
assert(
(HasPrototype || !SemaRef.getLangOpts().requiresStrictPrototypes()) &&
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaExpr.cpp b/contrib/llvm-project/clang/lib/Sema/SemaExpr.cpp
index 2716b6677105..3a5e302cc03a 100644
--- a/contrib/llvm-project/clang/lib/Sema/SemaExpr.cpp
+++ b/contrib/llvm-project/clang/lib/Sema/SemaExpr.cpp
@@ -13880,56 +13880,6 @@ inline QualType Sema::CheckBitwiseOperands(ExprResult &LHS, ExprResult &RHS,
return InvalidOperands(Loc, LHS, RHS);
}
-// Diagnose cases where the user write a logical and/or but probably meant a
-// bitwise one. We do this when one of the operands is a non-bool integer and
-// the other is a constant.
-void Sema::diagnoseLogicalInsteadOfBitwise(Expr *Op1, Expr *Op2,
- SourceLocation Loc,
- BinaryOperatorKind Opc) {
- if (Op1->getType()->isIntegerType() && !Op1->getType()->isBooleanType() &&
- Op2->getType()->isIntegerType() && !Op2->isValueDependent() &&
- // Don't warn in macros or template instantiations.
- !Loc.isMacroID() && !inTemplateInstantiation() &&
- !Op2->getExprLoc().isMacroID() &&
- !Op1->getExprLoc().isMacroID()) {
- bool IsOp1InMacro = Op1->getExprLoc().isMacroID();
- bool IsOp2InMacro = Op2->getExprLoc().isMacroID();
-
- // Exclude the specific expression from triggering the warning.
- if (!(IsOp1InMacro && IsOp2InMacro && Op1->getSourceRange() == Op2->getSourceRange())) {
- // If the RHS can be constant folded, and if it constant folds to something
- // that isn't 0 or 1 (which indicate a potential logical operation that
- // happened to fold to true/false) then warn.
- // Parens on the RHS are ignored.
- // If the RHS can be constant folded, and if it constant folds to something
- // that isn't 0 or 1 (which indicate a potential logical operation that
- // happened to fold to true/false) then warn.
- // Parens on the RHS are ignored.
- Expr::EvalResult EVResult;
- if (Op2->EvaluateAsInt(EVResult, Context)) {
- llvm::APSInt Result = EVResult.Val.getInt();
- if ((getLangOpts().Bool && !Op2->getType()->isBooleanType() &&
- !Op2->getExprLoc().isMacroID()) ||
- (Result != 0 && Result != 1)) {
- Diag(Loc, diag::warn_logical_instead_of_bitwise)
- << Op2->getSourceRange() << (Opc == BO_LAnd ? "&&" : "||");
- // Suggest replacing the logical operator with the bitwise version
- Diag(Loc, diag::note_logical_instead_of_bitwise_change_operator)
- << (Opc == BO_LAnd ? "&" : "|")
- << FixItHint::CreateReplacement(
- SourceRange(Loc, getLocForEndOfToken(Loc)),
- Opc == BO_LAnd ? "&" : "|");
- if (Opc == BO_LAnd)
- // Suggest replacing "Foo() && kNonZero" with "Foo()"
- Diag(Loc, diag::note_logical_instead_of_bitwise_remove_constant)
- << FixItHint::CreateRemoval(SourceRange(
- getLocForEndOfToken(Op1->getEndLoc()), Op2->getEndLoc()));
- }
- }
- }
- }
-}
-
// C99 6.5.[13,14]
inline QualType Sema::CheckLogicalOperands(ExprResult &LHS, ExprResult &RHS,
SourceLocation Loc,
@@ -13948,6 +13898,9 @@ inline QualType Sema::CheckLogicalOperands(ExprResult &LHS, ExprResult &RHS,
}
}
+ if (EnumConstantInBoolContext)
+ Diag(Loc, diag::warn_enum_constant_in_bool_context);
+
// WebAssembly tables can't be used with logical operators.
QualType LHSTy = LHS.get()->getType();
QualType RHSTy = RHS.get()->getType();
@@ -13958,14 +13911,40 @@ inline QualType Sema::CheckLogicalOperands(ExprResult &LHS, ExprResult &RHS,
return InvalidOperands(Loc, LHS, RHS);
}
- if (EnumConstantInBoolContext) {
- // Warn when converting the enum constant to a boolean
- Diag(Loc, diag::warn_enum_constant_in_bool_context);
- } else {
- // Diagnose cases where the user write a logical and/or but probably meant a
- // bitwise one.
- diagnoseLogicalInsteadOfBitwise(LHS.get(), RHS.get(), Loc, Opc);
- diagnoseLogicalInsteadOfBitwise(RHS.get(), LHS.get(), Loc, Opc);
+ // Diagnose cases where the user write a logical and/or but probably meant a
+ // bitwise one. We do this when the LHS is a non-bool integer and the RHS
+ // is a constant.
+ if (!EnumConstantInBoolContext && LHS.get()->getType()->isIntegerType() &&
+ !LHS.get()->getType()->isBooleanType() &&
+ RHS.get()->getType()->isIntegerType() && !RHS.get()->isValueDependent() &&
+ // Don't warn in macros or template instantiations.
+ !Loc.isMacroID() && !inTemplateInstantiation()) {
+ // If the RHS can be constant folded, and if it constant folds to something
+ // that isn't 0 or 1 (which indicate a potential logical operation that
+ // happened to fold to true/false) then warn.
+ // Parens on the RHS are ignored.
+ Expr::EvalResult EVResult;
+ if (RHS.get()->EvaluateAsInt(EVResult, Context)) {
+ llvm::APSInt Result = EVResult.Val.getInt();
+ if ((getLangOpts().Bool && !RHS.get()->getType()->isBooleanType() &&
+ !RHS.get()->getExprLoc().isMacroID()) ||
+ (Result != 0 && Result != 1)) {
+ Diag(Loc, diag::warn_logical_instead_of_bitwise)
+ << RHS.get()->getSourceRange() << (Opc == BO_LAnd ? "&&" : "||");
+ // Suggest replacing the logical operator with the bitwise version
+ Diag(Loc, diag::note_logical_instead_of_bitwise_change_operator)
+ << (Opc == BO_LAnd ? "&" : "|")
+ << FixItHint::CreateReplacement(
+ SourceRange(Loc, getLocForEndOfToken(Loc)),
+ Opc == BO_LAnd ? "&" : "|");
+ if (Opc == BO_LAnd)
+ // Suggest replacing "Foo() && kNonZero" with "Foo()"
+ Diag(Loc, diag::note_logical_instead_of_bitwise_remove_constant)
+ << FixItHint::CreateRemoval(
+ SourceRange(getLocForEndOfToken(LHS.get()->getEndLoc()),
+ RHS.get()->getEndLoc()));
+ }
+ }
}
if (!Context.getLangOpts().CPlusPlus) {
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp b/contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp
index 423d5372a6f6..1cff4a75790e 100644
--- a/contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp
+++ b/contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp
@@ -19,6 +19,7 @@
#include "clang/AST/CharUnits.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprConcepts.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/Type.h"
@@ -9072,16 +9073,24 @@ Sema::BuildExprRequirement(
MultiLevelTemplateArgumentList MLTAL(Param, TAL.asArray(),
/*Final=*/false);
MLTAL.addOuterRetainedLevels(TPL->getDepth());
- Expr *IDC = Param->getTypeConstraint()->getImmediatelyDeclaredConstraint();
+ const TypeConstraint *TC = Param->getTypeConstraint();
+ assert(TC && "Type Constraint cannot be null here");
+ auto *IDC = TC->getImmediatelyDeclaredConstraint();
+ assert(IDC && "ImmediatelyDeclaredConstraint can't be null here.");
ExprResult Constraint = SubstExpr(IDC, MLTAL);
if (Constraint.isInvalid()) {
- Status = concepts::ExprRequirement::SS_ExprSubstitutionFailure;
- } else {
- SubstitutedConstraintExpr =
- cast<ConceptSpecializationExpr>(Constraint.get());
- if (!SubstitutedConstraintExpr->isSatisfied())
- Status = concepts::ExprRequirement::SS_ConstraintsNotSatisfied;
- }
+ return new (Context) concepts::ExprRequirement(
+ concepts::createSubstDiagAt(*this, IDC->getExprLoc(),
+ [&](llvm::raw_ostream &OS) {
+ IDC->printPretty(OS, /*Helper=*/nullptr,
+ getPrintingPolicy());
+ }),
+ IsSimple, NoexceptLoc, ReturnTypeRequirement);
+ }
+ SubstitutedConstraintExpr =
+ cast<ConceptSpecializationExpr>(Constraint.get());
+ if (!SubstitutedConstraintExpr->isSatisfied())
+ Status = concepts::ExprRequirement::SS_ConstraintsNotSatisfied;
}
return new (Context) concepts::ExprRequirement(E, IsSimple, NoexceptLoc,
ReturnTypeRequirement, Status,
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaLookup.cpp b/contrib/llvm-project/clang/lib/Sema/SemaLookup.cpp
index c4f4edb6666c..d1ff688c2a21 100644
--- a/contrib/llvm-project/clang/lib/Sema/SemaLookup.cpp
+++ b/contrib/llvm-project/clang/lib/Sema/SemaLookup.cpp
@@ -513,42 +513,21 @@ void LookupResult::resolveKind() {
const NamedDecl *HasNonFunction = nullptr;
llvm::SmallVector<const NamedDecl *, 4> EquivalentNonFunctions;
- llvm::BitVector RemovedDecls(N);
- for (unsigned I = 0; I < N; I++) {
+ unsigned UniqueTagIndex = 0;
+
+ unsigned I = 0;
+ while (I < N) {
const NamedDecl *D = Decls[I]->getUnderlyingDecl();
D = cast<NamedDecl>(D->getCanonicalDecl());
// Ignore an invalid declaration unless it's the only one left.
// Also ignore HLSLBufferDecl which not have name conflict with other Decls.
- if ((D->isInvalidDecl() || isa<HLSLBufferDecl>(D)) &&
- N - RemovedDecls.count() > 1) {
- RemovedDecls.set(I);
+ if ((D->isInvalidDecl() || isa<HLSLBufferDecl>(D)) && !(I == 0 && N == 1)) {
+ Decls[I] = Decls[--N];
continue;
}
- // C++ [basic.scope.hiding]p2:
- // A class name or enumeration name can be hidden by the name of
- // an object, function, or enumerator declared in the same
- // scope. If a class or enumeration name and an object, function,
- // or enumerator are declared in the same scope (in any order)
- // with the same name, the class or enumeration name is hidden
- // wherever the object, function, or enumerator name is visible.
- if (HideTags && isa<TagDecl>(D)) {
- bool Hidden = false;
- for (auto *OtherDecl : Decls) {
- if (canHideTag(OtherDecl) &&
- getContextForScopeMatching(OtherDecl)->Equals(
- getContextForScopeMatching(Decls[I]))) {
- RemovedDecls.set(I);
- Hidden = true;
- break;
- }
- }
- if (Hidden)
- continue;
- }
-
std::optional<unsigned> ExistingI;
// Redeclarations of types via typedef can occur both within a scope
@@ -581,7 +560,7 @@ void LookupResult::resolveKind() {
if (isPreferredLookupResult(getSema(), getLookupKind(), Decls[I],
Decls[*ExistingI]))
Decls[*ExistingI] = Decls[I];
- RemovedDecls.set(I);
+ Decls[I] = Decls[--N];
continue;
}
@@ -592,6 +571,7 @@ void LookupResult::resolveKind() {
} else if (isa<TagDecl>(D)) {
if (HasTag)
Ambiguous = true;
+ UniqueTagIndex = I;
HasTag = true;
} else if (isa<FunctionTemplateDecl>(D)) {
HasFunction = true;
@@ -607,7 +587,7 @@ void LookupResult::resolveKind() {
if (getSema().isEquivalentInternalLinkageDeclaration(HasNonFunction,
D)) {
EquivalentNonFunctions.push_back(D);
- RemovedDecls.set(I);
+ Decls[I] = Decls[--N];
continue;
}
@@ -615,6 +595,28 @@ void LookupResult::resolveKind() {
}
HasNonFunction = D;
}
+ I++;
+ }
+
+ // C++ [basic.scope.hiding]p2:
+ // A class name or enumeration name can be hidden by the name of
+ // an object, function, or enumerator declared in the same
+ // scope. If a class or enumeration name and an object, function,
+ // or enumerator are declared in the same scope (in any order)
+ // with the same name, the class or enumeration name is hidden
+ // wherever the object, function, or enumerator name is visible.
+ // But it's still an error if there are distinct tag types found,
+ // even if they're not visible. (ref?)
+ if (N > 1 && HideTags && HasTag && !Ambiguous &&
+ (HasFunction || HasNonFunction || HasUnresolved)) {
+ const NamedDecl *OtherDecl = Decls[UniqueTagIndex ? 0 : N - 1];
+ if (isa<TagDecl>(Decls[UniqueTagIndex]->getUnderlyingDecl()) &&
+ getContextForScopeMatching(Decls[UniqueTagIndex])->Equals(
+ getContextForScopeMatching(OtherDecl)) &&
+ canHideTag(OtherDecl))
+ Decls[UniqueTagIndex] = Decls[--N];
+ else
+ Ambiguous = true;
}
// FIXME: This diagnostic should really be delayed until we're done with
@@ -623,15 +625,9 @@ void LookupResult::resolveKind() {
getSema().diagnoseEquivalentInternalLinkageDeclarations(
getNameLoc(), HasNonFunction, EquivalentNonFunctions);
- // Remove decls by replacing them with decls from the end (which
- // means that we need to iterate from the end) and then truncating
- // to the new size.
- for (int I = RemovedDecls.find_last(); I >= 0; I = RemovedDecls.find_prev(I))
- Decls[I] = Decls[--N];
Decls.truncate(N);
- if ((HasNonFunction && (HasFunction || HasUnresolved)) ||
- (HideTags && HasTag && (HasFunction || HasNonFunction || HasUnresolved)))
+ if (HasNonFunction && (HasFunction || HasUnresolved))
Ambiguous = true;
if (Ambiguous)
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaTemplateInstantiate.cpp b/contrib/llvm-project/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 8702e2ca3a1b..394006a57747 100644
--- a/contrib/llvm-project/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/contrib/llvm-project/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -2276,9 +2276,9 @@ QualType TemplateInstantiator::TransformSubstTemplateTypeParmPackType(
getPackIndex(Pack), Arg, TL.getNameLoc());
}
-template<typename EntityPrinter>
static concepts::Requirement::SubstitutionDiagnostic *
-createSubstDiag(Sema &S, TemplateDeductionInfo &Info, EntityPrinter Printer) {
+createSubstDiag(Sema &S, TemplateDeductionInfo &Info,
+ concepts::EntityPrinter Printer) {
SmallString<128> Message;
SourceLocation ErrorLoc;
if (Info.hasSFINAEDiagnostic()) {
@@ -2302,6 +2302,19 @@ createSubstDiag(Sema &S, TemplateDeductionInfo &Info, EntityPrinter Printer) {
StringRef(MessageBuf, Message.size())};
}
+concepts::Requirement::SubstitutionDiagnostic *
+concepts::createSubstDiagAt(Sema &S, SourceLocation Location,
+ EntityPrinter Printer) {
+ SmallString<128> Entity;
+ llvm::raw_svector_ostream OS(Entity);
+ Printer(OS);
+ char *EntityBuf = new (S.Context) char[Entity.size()];
+ llvm::copy(Entity, EntityBuf);
+ return new (S.Context) concepts::Requirement::SubstitutionDiagnostic{
+ /*SubstitutedEntity=*/StringRef(EntityBuf, Entity.size()),
+ /*DiagLoc=*/Location, /*DiagMessage=*/StringRef()};
+}
+
ExprResult TemplateInstantiator::TransformRequiresTypeParams(
SourceLocation KWLoc, SourceLocation RBraceLoc, const RequiresExpr *RE,
RequiresExprBodyDecl *Body, ArrayRef<ParmVarDecl *> Params,
diff --git a/contrib/llvm-project/clang/lib/Sema/TreeTransform.h b/contrib/llvm-project/clang/lib/Sema/TreeTransform.h
index 10b3587885e3..097e81ea7d45 100644
--- a/contrib/llvm-project/clang/lib/Sema/TreeTransform.h
+++ b/contrib/llvm-project/clang/lib/Sema/TreeTransform.h
@@ -7478,6 +7478,10 @@ StmtResult
TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
bool IsStmtExpr) {
Sema::CompoundScopeRAII CompoundScope(getSema());
+ Sema::FPFeaturesStateRAII FPSave(getSema());
+ if (S->hasStoredFPFeatures())
+ getSema().resetFPOptions(
+ S->getStoredFPFeatures().applyOverrides(getSema().getLangOpts()));
const Stmt *ExprResult = S->getStmtExprResult();
bool SubStmtInvalid = false;
diff --git a/contrib/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp b/contrib/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp
index 10c92f8d2149..c8cbee14be4f 100644
--- a/contrib/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/contrib/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -181,6 +181,13 @@ namespace clang {
static void setAnonymousDeclForMerging(ASTReader &Reader, DeclContext *DC,
unsigned Index, NamedDecl *D);
+ /// Commit to a primary definition of the class RD, which is known to be
+ /// a definition of the class. We might not have read the definition data
+ /// for it yet. If we haven't then allocate placeholder definition data
+ /// now too.
+ static CXXRecordDecl *getOrFakePrimaryClassDefinition(ASTReader &Reader,
+ CXXRecordDecl *RD);
+
/// Results from loading a RedeclarableDecl.
class RedeclarableResult {
Decl *MergeWith;
@@ -598,7 +605,13 @@ void ASTDeclReader::VisitDecl(Decl *D) {
auto *LexicalDC = readDeclAs<DeclContext>();
if (!LexicalDC)
LexicalDC = SemaDC;
- DeclContext *MergedSemaDC = Reader.MergedDeclContexts.lookup(SemaDC);
+ // If the context is a class, we might not have actually merged it yet, in
+ // the case where the definition comes from an update record.
+ DeclContext *MergedSemaDC;
+ if (auto *RD = dyn_cast<CXXRecordDecl>(SemaDC))
+ MergedSemaDC = getOrFakePrimaryClassDefinition(Reader, RD);
+ else
+ MergedSemaDC = Reader.MergedDeclContexts.lookup(SemaDC);
// Avoid calling setLexicalDeclContext() directly because it uses
// Decl::getASTContext() internally which is unsafe during derialization.
D->setDeclContextsImpl(MergedSemaDC ? MergedSemaDC : SemaDC, LexicalDC,
@@ -3198,6 +3211,32 @@ uint64_t ASTReader::getGlobalBitOffset(ModuleFile &M, uint64_t LocalOffset) {
return LocalOffset + M.GlobalBitOffset;
}
+CXXRecordDecl *
+ASTDeclReader::getOrFakePrimaryClassDefinition(ASTReader &Reader,
+ CXXRecordDecl *RD) {
+ // Try to dig out the definition.
+ auto *DD = RD->DefinitionData;
+ if (!DD)
+ DD = RD->getCanonicalDecl()->DefinitionData;
+
+ // If there's no definition yet, then DC's definition is added by an update
+ // record, but we've not yet loaded that update record. In this case, we
+ // commit to DC being the canonical definition now, and will fix this when
+ // we load the update record.
+ if (!DD) {
+ DD = new (Reader.getContext()) struct CXXRecordDecl::DefinitionData(RD);
+ RD->setCompleteDefinition(true);
+ RD->DefinitionData = DD;
+ RD->getCanonicalDecl()->DefinitionData = DD;
+
+ // Track that we did this horrible thing so that we can fix it later.
+ Reader.PendingFakeDefinitionData.insert(
+ std::make_pair(DD, ASTReader::PendingFakeDefinitionKind::Fake));
+ }
+
+ return DD->Definition;
+}
+
/// Find the context in which we should search for previous declarations when
/// looking for declarations to merge.
DeclContext *ASTDeclReader::getPrimaryContextForMerging(ASTReader &Reader,
@@ -3205,29 +3244,8 @@ DeclContext *ASTDeclReader::getPrimaryContextForMerging(ASTReader &Reader,
if (auto *ND = dyn_cast<NamespaceDecl>(DC))
return ND->getOriginalNamespace();
- if (auto *RD = dyn_cast<CXXRecordDecl>(DC)) {
- // Try to dig out the definition.
- auto *DD = RD->DefinitionData;
- if (!DD)
- DD = RD->getCanonicalDecl()->DefinitionData;
-
- // If there's no definition yet, then DC's definition is added by an update
- // record, but we've not yet loaded that update record. In this case, we
- // commit to DC being the canonical definition now, and will fix this when
- // we load the update record.
- if (!DD) {
- DD = new (Reader.getContext()) struct CXXRecordDecl::DefinitionData(RD);
- RD->setCompleteDefinition(true);
- RD->DefinitionData = DD;
- RD->getCanonicalDecl()->DefinitionData = DD;
-
- // Track that we did this horrible thing so that we can fix it later.
- Reader.PendingFakeDefinitionData.insert(
- std::make_pair(DD, ASTReader::PendingFakeDefinitionKind::Fake));
- }
-
- return DD->Definition;
- }
+ if (auto *RD = dyn_cast<CXXRecordDecl>(DC))
+ return getOrFakePrimaryClassDefinition(Reader, RD);
if (auto *RD = dyn_cast<RecordDecl>(DC))
return RD->getDefinition();
diff --git a/contrib/llvm-project/clang/lib/Serialization/ASTWriterDecl.cpp b/contrib/llvm-project/clang/lib/Serialization/ASTWriterDecl.cpp
index 59dbc36d24e8..8dd78152bd68 100644
--- a/contrib/llvm-project/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/contrib/llvm-project/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -580,7 +580,7 @@ void ASTDeclWriter::VisitDeclaratorDecl(DeclaratorDecl *D) {
}
void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
- static_assert(DeclContext::NumFunctionDeclBits == 30,
+ static_assert(DeclContext::NumFunctionDeclBits == 31,
"You need to update the serializer after you change the "
"FunctionDeclBits");
@@ -1495,7 +1495,7 @@ void ASTDeclWriter::VisitCXXMethodDecl(CXXMethodDecl *D) {
}
void ASTDeclWriter::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
- static_assert(DeclContext::NumCXXConstructorDeclBits == 21,
+ static_assert(DeclContext::NumCXXConstructorDeclBits == 20,
"You need to update the serializer after you change the "
"CXXConstructorDeclBits");
diff --git a/contrib/llvm-project/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc b/contrib/llvm-project/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc
index a08ec11e77a4..b46bd2e4d7a4 100644
--- a/contrib/llvm-project/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc
+++ b/contrib/llvm-project/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc
@@ -3773,6 +3773,33 @@ SYMBOL(viewable_range, std::ranges::, <ranges>)
SYMBOL(wistream_view, std::ranges::, <ranges>)
SYMBOL(zip_transform_view, std::ranges::, <ranges>)
SYMBOL(zip_view, std::ranges::, <ranges>)
+SYMBOL(all, std::ranges::views::, <ranges>)
+SYMBOL(all_t, std::ranges::views::, <ranges>)
+SYMBOL(as_const, std::ranges::views::, <ranges>)
+SYMBOL(as_rvalue, std::ranges::views::, <ranges>)
+SYMBOL(common, std::ranges::views::, <ranges>)
+SYMBOL(counted, std::ranges::views::, <ranges>)
+SYMBOL(drop, std::ranges::views::, <ranges>)
+SYMBOL(drop_while, std::ranges::views::, <ranges>)
+SYMBOL(elements, std::ranges::views::, <ranges>)
+SYMBOL(empty, std::ranges::views::, <ranges>)
+SYMBOL(filter, std::ranges::views::, <ranges>)
+SYMBOL(iota, std::ranges::views::, <ranges>)
+SYMBOL(istream, std::ranges::views::, <ranges>)
+SYMBOL(istream, std::ranges::views::, <iosfwd>)
+SYMBOL(join, std::ranges::views::, <ranges>)
+SYMBOL(join_with, std::ranges::views::, <ranges>)
+SYMBOL(keys, std::ranges::views::, <ranges>)
+SYMBOL(lazy_split, std::ranges::views::, <ranges>)
+SYMBOL(reverse, std::ranges::views::, <ranges>)
+SYMBOL(single, std::ranges::views::, <ranges>)
+SYMBOL(split, std::ranges::views::, <ranges>)
+SYMBOL(take, std::ranges::views::, <ranges>)
+SYMBOL(take_while, std::ranges::views::, <ranges>)
+SYMBOL(transform, std::ranges::views::, <ranges>)
+SYMBOL(values, std::ranges::views::, <ranges>)
+SYMBOL(zip, std::ranges::views::, <ranges>)
+SYMBOL(zip_transform, std::ranges::views::, <ranges>)
SYMBOL(ECMAScript, std::regex_constants::, <regex>)
SYMBOL(awk, std::regex_constants::, <regex>)
SYMBOL(basic, std::regex_constants::, <regex>)
@@ -3817,3 +3844,30 @@ SYMBOL(get_id, std::this_thread::, <thread>)
SYMBOL(sleep_for, std::this_thread::, <thread>)
SYMBOL(sleep_until, std::this_thread::, <thread>)
SYMBOL(yield, std::this_thread::, <thread>)
+SYMBOL(all, std::views::, <ranges>)
+SYMBOL(all_t, std::views::, <ranges>)
+SYMBOL(as_const, std::views::, <ranges>)
+SYMBOL(as_rvalue, std::views::, <ranges>)
+SYMBOL(common, std::views::, <ranges>)
+SYMBOL(counted, std::views::, <ranges>)
+SYMBOL(drop, std::views::, <ranges>)
+SYMBOL(drop_while, std::views::, <ranges>)
+SYMBOL(elements, std::views::, <ranges>)
+SYMBOL(empty, std::views::, <ranges>)
+SYMBOL(filter, std::views::, <ranges>)
+SYMBOL(iota, std::views::, <ranges>)
+SYMBOL(istream, std::views::, <ranges>)
+SYMBOL(istream, std::views::, <iosfwd>)
+SYMBOL(join, std::views::, <ranges>)
+SYMBOL(join_with, std::views::, <ranges>)
+SYMBOL(keys, std::views::, <ranges>)
+SYMBOL(lazy_split, std::views::, <ranges>)
+SYMBOL(reverse, std::views::, <ranges>)
+SYMBOL(single, std::views::, <ranges>)
+SYMBOL(split, std::views::, <ranges>)
+SYMBOL(take, std::views::, <ranges>)
+SYMBOL(take_while, std::views::, <ranges>)
+SYMBOL(transform, std::views::, <ranges>)
+SYMBOL(values, std::views::, <ranges>)
+SYMBOL(zip, std::views::, <ranges>)
+SYMBOL(zip_transform, std::views::, <ranges>)