Date: Sun, 1 Dec 2024 12:54:23 GMT From: Dimitry Andric <dim@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: d7185d58b3d2 - stable/13 - Merge llvm-project release/19.x llvmorg-19.1.0-rc2-0-gd033ae172d1c Message-ID: <202412011254.4B1CsN7d094167@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by dim: URL: https://cgit.FreeBSD.org/src/commit/?id=d7185d58b3d221543483a7faed1a984ba08fc3b6 commit d7185d58b3d221543483a7faed1a984ba08fc3b6 Author: Dimitry Andric <dim@FreeBSD.org> AuthorDate: 2024-08-06 13:37:26 +0000 Commit: Dimitry Andric <dim@FreeBSD.org> CommitDate: 2024-12-01 12:32:42 +0000 Merge llvm-project release/19.x llvmorg-19.1.0-rc2-0-gd033ae172d1c This updates llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp to llvm-project release/19.x llvmorg-19.1.0-rc2-0-gd033ae172d1c. PR: 280562 MFC after: 1 month (cherry picked from commit 52418fc2be8efa5172b90a3a9e617017173612c4) --- .../llvm-project/clang/include/clang/AST/DeclCXX.h | 7 + .../llvm-project/clang/include/clang/Basic/Attr.td | 9 + .../clang/include/clang/Basic/AttrDocs.td | 10 + .../include/clang/Basic/DiagnosticFrontendKinds.td | 3 + .../include/clang/Basic/DiagnosticSemaKinds.td | 5 +- contrib/llvm-project/clang/lib/AST/DeclCXX.cpp | 36 +++ .../clang/lib/CodeGen/CodeGenFunction.cpp | 3 + .../clang/lib/CodeGen/Targets/AArch64.cpp | 6 +- .../clang/lib/Driver/ToolChains/Clang.cpp | 3 + .../clang/lib/Format/TokenAnnotator.cpp | 61 ++--- .../clang/lib/Sema/CheckExprLifetime.cpp | 9 + .../llvm-project/clang/lib/Sema/SemaChecking.cpp | 74 ++--- contrib/llvm-project/clang/lib/Sema/SemaDecl.cpp | 29 +- .../llvm-project/clang/lib/Sema/SemaDeclAttr.cpp | 10 +- .../Checkers/BlockInCriticalSectionChecker.cpp | 16 +- .../clang/lib/StaticAnalyzer/Core/Store.cpp | 12 +- .../compiler-rt/lib/builtins/riscv/feature_bits.c | 298 --------------------- .../lib/interception/interception_linux.h | 16 +- .../compiler-rt/lib/nsan/nsan_interceptors.cpp | 10 - .../compiler-rt/lib/rtsan/rtsan_interceptors.cpp | 12 + .../lib/sanitizer_common/sanitizer_linux.cpp | 2 +- .../sanitizer_stacktrace_sparc.cpp | 11 +- .../libcxx/include/__atomic/atomic_ref.h | 32 ++- contrib/llvm-project/libcxx/include/typeinfo | 9 +- contrib/llvm-project/libcxx/include/version | 4 +- .../libcxx/src/include/overridable_function.h | 6 +- .../llvm-project/libunwind/src/UnwindCursor.hpp | 3 +- contrib/llvm-project/lld/ELF/Arch/LoongArch.cpp | 10 + contrib/llvm-project/lld/ELF/DWARF.cpp | 3 +- contrib/llvm-project/lld/ELF/ICF.cpp | 26 +- contrib/llvm-project/lld/ELF/InputFiles.cpp | 1 + contrib/llvm-project/lld/ELF/InputFiles.h | 1 + contrib/llvm-project/lld/ELF/InputSection.cpp | 75 ++++-- contrib/llvm-project/lld/ELF/InputSection.h | 27 +- contrib/llvm-project/lld/ELF/LinkerScript.cpp | 2 + contrib/llvm-project/lld/ELF/MarkLive.cpp | 12 +- contrib/llvm-project/lld/ELF/OutputSections.cpp | 132 ++++++++- contrib/llvm-project/lld/ELF/OutputSections.h | 6 + contrib/llvm-project/lld/ELF/Relocations.cpp | 57 ++-- contrib/llvm-project/lld/ELF/Relocations.h | 102 ++++++- contrib/llvm-project/lld/ELF/ScriptLexer.cpp | 5 - contrib/llvm-project/lld/ELF/SyntheticSections.cpp | 18 +- contrib/llvm-project/lld/ELF/SyntheticSections.h | 5 +- contrib/llvm-project/lld/ELF/Writer.cpp | 13 +- contrib/llvm-project/lld/docs/ReleaseNotes.rst | 8 +- .../llvm-project/llvm/include/llvm/ADT/STLExtras.h | 6 + .../include/llvm/CodeGen/TargetFrameLowering.h | 7 + .../llvm/include/llvm/IR/IntrinsicInst.h | 4 + .../llvm/include/llvm/IR/VectorBuilder.h | 5 +- .../llvm/include/llvm/MC/MCAsmBackend.h | 5 +- .../llvm/include/llvm/MC/MCAssembler.h | 4 +- .../llvm-project/llvm/include/llvm/MC/MCSection.h | 5 + .../llvm/include/llvm/Transforms/Utils/LoopUtils.h | 4 + .../llvm/lib/CodeGen/RegisterCoalescer.cpp | 7 + .../lib/CodeGen/StackFrameLayoutAnalysisPass.cpp | 72 +++-- .../llvm/lib/CodeGen/TargetFrameLoweringImpl.cpp | 14 + contrib/llvm-project/llvm/lib/IR/IntrinsicInst.cpp | 19 ++ contrib/llvm-project/llvm/lib/IR/Metadata.cpp | 5 +- contrib/llvm-project/llvm/lib/IR/VectorBuilder.cpp | 57 +--- contrib/llvm-project/llvm/lib/MC/MCAssembler.cpp | 77 +++--- contrib/llvm-project/llvm/lib/MC/MCSection.cpp | 4 +- .../llvm/lib/Support/Windows/Process.inc | 3 +- .../llvm/lib/Support/Windows/Signals.inc | 38 +-- .../Target/AArch64/AArch64Arm64ECCallLowering.cpp | 5 + .../lib/Target/AArch64/AArch64FrameLowering.cpp | 35 +++ .../llvm/lib/Target/AArch64/AArch64FrameLowering.h | 2 + .../AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.h | 1 + .../llvm/lib/Target/ARM/ARMAsmPrinter.cpp | 6 +- .../Hexagon/MCTargetDesc/HexagonAsmBackend.cpp | 4 +- .../LoongArch/AsmParser/LoongArchAsmParser.cpp | 24 ++ .../lib/Target/LoongArch/LoongArchInstrInfo.td | 6 +- .../LoongArch/MCTargetDesc/LoongArchFixupKinds.h | 8 + .../MCTargetDesc/LoongArchMCCodeEmitter.cpp | 12 + .../LoongArch/MCTargetDesc/LoongArchMCExpr.cpp | 15 ++ .../LoongArch/MCTargetDesc/LoongArchMCExpr.h | 4 + .../llvm/lib/Target/NVPTX/NVPTXFrameLowering.cpp | 5 +- .../llvm/lib/Target/PowerPC/PPCRegisterInfo.td | 35 ++- .../llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 4 + .../llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp | 10 +- .../lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp | 26 +- .../lib/Transforms/Scalar/InferAddressSpaces.cpp | 2 +- .../llvm/lib/Transforms/Utils/LoopUtils.cpp | 44 ++- lib/clang/include/VCSVersion.inc | 6 +- lib/clang/include/clang/Basic/Version.inc | 4 +- lib/clang/include/lld/Common/Version.inc | 2 +- lib/clang/include/lldb/Version/Version.inc | 4 +- lib/clang/include/llvm/Config/config.h | 4 +- lib/clang/include/llvm/Config/llvm-config.h | 2 +- lib/clang/include/llvm/Support/VCSRevision.h | 2 +- 89 files changed, 1106 insertions(+), 701 deletions(-) diff --git a/contrib/llvm-project/clang/include/clang/AST/DeclCXX.h b/contrib/llvm-project/clang/include/clang/AST/DeclCXX.h index fb52ac804849..0923736a95f9 100644 --- a/contrib/llvm-project/clang/include/clang/AST/DeclCXX.h +++ b/contrib/llvm-project/clang/include/clang/AST/DeclCXX.h @@ -1210,6 +1210,13 @@ public: return D.HasPublicFields || D.HasProtectedFields || D.HasPrivateFields; } + /// If this is a standard-layout class or union, any and all data members will + /// be declared in the same type. + /// + /// This retrieves the type where any fields are declared, + /// or the current class if there is no class with fields. + const CXXRecordDecl *getStandardLayoutBaseWithFields() const; + /// Whether this class is polymorphic (C++ [class.virtual]), /// which means that the class contains or inherits a virtual function. bool isPolymorphic() const { return data().Polymorphic; } diff --git a/contrib/llvm-project/clang/include/clang/Basic/Attr.td b/contrib/llvm-project/clang/include/clang/Basic/Attr.td index 4825979a974d..46d0a66d59c3 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/Attr.td +++ b/contrib/llvm-project/clang/include/clang/Basic/Attr.td @@ -477,6 +477,9 @@ def TargetELF : TargetSpec { def TargetELFOrMachO : TargetSpec { let ObjectFormats = ["ELF", "MachO"]; } +def TargetWindowsArm64EC : TargetSpec { + let CustomCode = [{ Target.getTriple().isWindowsArm64EC() }]; +} def TargetSupportsInitPriority : TargetSpec { let CustomCode = [{ !Target.getTriple().isOSzOS() }]; @@ -4027,6 +4030,12 @@ def SelectAny : InheritableAttr { let SimpleHandler = 1; } +def HybridPatchable : InheritableAttr, TargetSpecificAttr<TargetWindowsArm64EC> { + let Spellings = [Declspec<"hybrid_patchable">, Clang<"hybrid_patchable">]; + let Subjects = SubjectList<[Function]>; + let Documentation = [HybridPatchableDocs]; +} + def Thread : Attr { let Spellings = [Declspec<"thread">]; let LangOpts = [MicrosoftExt]; diff --git a/contrib/llvm-project/clang/include/clang/Basic/AttrDocs.td b/contrib/llvm-project/clang/include/clang/Basic/AttrDocs.td index 99738812c815..b5d468eb5ec9 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/AttrDocs.td +++ b/contrib/llvm-project/clang/include/clang/Basic/AttrDocs.td @@ -5985,6 +5985,16 @@ For more information see or `msvc documentation <https://docs.microsoft.com/pl-pl/cpp/cpp/selectany>`_. }]; } +def HybridPatchableDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +The ``hybrid_patchable`` attribute declares an ARM64EC function with an additional +x86-64 thunk, which may be patched at runtime. + +For more information see +`ARM64EC ABI documentation <https://learn.microsoft.com/en-us/windows/arm/arm64ec-abi>`_. +}]; } + def WebAssemblyExportNameDocs : Documentation { let Category = DocCatFunction; let Content = [{ diff --git a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticFrontendKinds.td index 12a4617c64d8..8a1462c670d6 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -288,6 +288,9 @@ def err_function_needs_feature : Error< let CategoryName = "Codegen ABI Check" in { def err_function_always_inline_attribute_mismatch : Error< "always_inline function %1 and its caller %0 have mismatching %2 attributes">; +def warn_function_always_inline_attribute_mismatch : Warning< + "always_inline function %1 and its caller %0 have mismatching %2 attributes, " + "inlining may change runtime behaviour">, InGroup<AArch64SMEAttributes>; def err_function_always_inline_new_za : Error< "always_inline function %0 has new za state">; diff --git a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticSemaKinds.td b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticSemaKinds.td index 3669b8b48e53..5490a38afa53 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3677,6 +3677,9 @@ def err_attribute_weak_static : Error< "weak declaration cannot have internal linkage">; def err_attribute_selectany_non_extern_data : Error< "'selectany' can only be applied to data items with external linkage">; +def warn_attribute_hybrid_patchable_non_extern : Warning< + "'hybrid_patchable' is ignored on functions without external linkage">, + InGroup<IgnoredAttributes>; def err_declspec_thread_on_thread_variable : Error< "'__declspec(thread)' applied to variable that already has a " "thread-local storage specifier">; @@ -3808,8 +3811,6 @@ def warn_sme_locally_streaming_has_vl_args_returns : Warning< InGroup<AArch64SMEAttributes>, DefaultIgnore; def err_conflicting_attributes_arm_state : Error< "conflicting attributes for state '%0'">; -def err_sme_streaming_cannot_be_multiversioned : Error< - "streaming function cannot be multi-versioned">; def err_unknown_arm_state : Error< "unknown state '%0'">; def err_missing_arm_state : Error< diff --git a/contrib/llvm-project/clang/lib/AST/DeclCXX.cpp b/contrib/llvm-project/clang/lib/AST/DeclCXX.cpp index b573c2713a3a..9a3ede426e91 100644 --- a/contrib/llvm-project/clang/lib/AST/DeclCXX.cpp +++ b/contrib/llvm-project/clang/lib/AST/DeclCXX.cpp @@ -561,6 +561,42 @@ void CXXRecordDecl::addedClassSubobject(CXXRecordDecl *Subobj) { data().StructuralIfLiteral = false; } +const CXXRecordDecl *CXXRecordDecl::getStandardLayoutBaseWithFields() const { + assert( + isStandardLayout() && + "getStandardLayoutBaseWithFields called on a non-standard-layout type"); +#ifdef EXPENSIVE_CHECKS + { + unsigned NumberOfBasesWithFields = 0; + if (!field_empty()) + ++NumberOfBasesWithFields; + llvm::SmallPtrSet<const CXXRecordDecl *, 8> UniqueBases; + forallBases([&](const CXXRecordDecl *Base) -> bool { + if (!Base->field_empty()) + ++NumberOfBasesWithFields; + assert( + UniqueBases.insert(Base->getCanonicalDecl()).second && + "Standard layout struct has multiple base classes of the same type"); + return true; + }); + assert(NumberOfBasesWithFields <= 1 && + "Standard layout struct has fields declared in more than one class"); + } +#endif + if (!field_empty()) + return this; + const CXXRecordDecl *Result = this; + forallBases([&](const CXXRecordDecl *Base) -> bool { + if (!Base->field_empty()) { + // This is the base where the fields are declared; return early + Result = Base; + return false; + } + return true; + }); + return Result; +} + bool CXXRecordDecl::hasConstexprDestructor() const { auto *Dtor = getDestructor(); return Dtor ? Dtor->isConstexpr() : defaultedDestructorIsConstexpr(); diff --git a/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp b/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp index d6078696a7d9..af201554898f 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp @@ -991,6 +991,9 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, if (D && D->hasAttr<NoProfileFunctionAttr>()) Fn->addFnAttr(llvm::Attribute::NoProfile); + if (D && D->hasAttr<HybridPatchableAttr>()) + Fn->addFnAttr(llvm::Attribute::HybridPatchable); + if (D) { // Function attributes take precedence over command line flags. if (auto *A = D->getAttr<FunctionReturnThunksAttr>()) { diff --git a/contrib/llvm-project/clang/lib/CodeGen/Targets/AArch64.cpp b/contrib/llvm-project/clang/lib/CodeGen/Targets/AArch64.cpp index b9df54b0c67c..1dec3cd40ebd 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/Targets/AArch64.cpp +++ b/contrib/llvm-project/clang/lib/CodeGen/Targets/AArch64.cpp @@ -883,8 +883,10 @@ void AArch64TargetCodeGenInfo::checkFunctionCallABIStreaming( if (!CalleeIsStreamingCompatible && (CallerIsStreaming != CalleeIsStreaming || CallerIsStreamingCompatible)) - CGM.getDiags().Report(CallLoc, - diag::err_function_always_inline_attribute_mismatch) + CGM.getDiags().Report( + CallLoc, CalleeIsStreaming + ? diag::err_function_always_inline_attribute_mismatch + : diag::warn_function_always_inline_attribute_mismatch) << Caller->getDeclName() << Callee->getDeclName() << "streaming"; if (auto *NewAttr = Callee->getAttr<ArmNewAttr>()) if (NewAttr->isNewZA()) diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp index 5de29f1eca61..366b147a052b 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp @@ -1847,6 +1847,9 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args, Args.addOptInFlag( CmdArgs, options::OPT_fptrauth_vtable_pointer_type_discrimination, options::OPT_fno_ptrauth_vtable_pointer_type_discrimination); + Args.addOptInFlag( + CmdArgs, options::OPT_fptrauth_type_info_vtable_pointer_discrimination, + options::OPT_fno_ptrauth_type_info_vtable_pointer_discrimination); Args.addOptInFlag(CmdArgs, options::OPT_fptrauth_init_fini, options::OPT_fno_ptrauth_init_fini); Args.addOptInFlag( diff --git a/contrib/llvm-project/clang/lib/Format/TokenAnnotator.cpp b/contrib/llvm-project/clang/lib/Format/TokenAnnotator.cpp index 21924a8fe17d..63c8699fd62d 100644 --- a/contrib/llvm-project/clang/lib/Format/TokenAnnotator.cpp +++ b/contrib/llvm-project/clang/lib/Format/TokenAnnotator.cpp @@ -154,8 +154,8 @@ private: if (NonTemplateLess.count(CurrentToken->Previous) > 0) return false; - const FormatToken &Previous = *CurrentToken->Previous; // The '<'. - if (Previous.Previous) { + if (const auto &Previous = *CurrentToken->Previous; // The '<'. + Previous.Previous) { if (Previous.Previous->Tok.isLiteral()) return false; if (Previous.Previous->is(tok::r_brace)) @@ -175,11 +175,13 @@ private: FormatToken *Left = CurrentToken->Previous; Left->ParentBracket = Contexts.back().ContextKind; ScopedContextCreator ContextCreator(*this, tok::less, 12); - Contexts.back().IsExpression = false; + + const auto *BeforeLess = Left->Previous; + // If there's a template keyword before the opening angle bracket, this is a // template parameter, not an argument. - if (Left->Previous && Left->Previous->isNot(tok::kw_template)) + if (BeforeLess && BeforeLess->isNot(tok::kw_template)) Contexts.back().ContextType = Context::TemplateArgument; if (Style.Language == FormatStyle::LK_Java && @@ -187,19 +189,24 @@ private: next(); } - while (CurrentToken) { + for (bool SeenTernaryOperator = false; CurrentToken;) { + const bool InExpr = Contexts[Contexts.size() - 2].IsExpression; if (CurrentToken->is(tok::greater)) { + const auto *Next = CurrentToken->Next; // Try to do a better job at looking for ">>" within the condition of // a statement. Conservatively insert spaces between consecutive ">" // tokens to prevent splitting right bitshift operators and potentially // altering program semantics. This check is overly conservative and // will prevent spaces from being inserted in select nested template // parameter cases, but should not alter program semantics. - if (CurrentToken->Next && CurrentToken->Next->is(tok::greater) && + if (Next && Next->is(tok::greater) && Left->ParentBracket != tok::less && CurrentToken->getStartOfNonWhitespace() == - CurrentToken->Next->getStartOfNonWhitespace().getLocWithOffset( - -1)) { + Next->getStartOfNonWhitespace().getLocWithOffset(-1)) { + return false; + } + if (InExpr && SeenTernaryOperator && + (!Next || !Next->isOneOf(tok::l_paren, tok::l_brace))) { return false; } Left->MatchingParen = CurrentToken; @@ -210,14 +217,14 @@ private: // msg: < item: data > // In TT_TextProto, map<key, value> does not occur. if (Style.Language == FormatStyle::LK_TextProto || - (Style.Language == FormatStyle::LK_Proto && Left->Previous && - Left->Previous->isOneOf(TT_SelectorName, TT_DictLiteral))) { + (Style.Language == FormatStyle::LK_Proto && BeforeLess && + BeforeLess->isOneOf(TT_SelectorName, TT_DictLiteral))) { CurrentToken->setType(TT_DictLiteral); } else { CurrentToken->setType(TT_TemplateCloser); CurrentToken->Tok.setLength(1); } - if (CurrentToken->Next && CurrentToken->Next->Tok.isLiteral()) + if (Next && Next->Tok.isLiteral()) return false; next(); return true; @@ -229,18 +236,21 @@ private: } if (CurrentToken->isOneOf(tok::r_paren, tok::r_square, tok::r_brace)) return false; + const auto &Prev = *CurrentToken->Previous; // If a && or || is found and interpreted as a binary operator, this set // of angles is likely part of something like "a < b && c > d". If the // angles are inside an expression, the ||/&& might also be a binary // operator that was misinterpreted because we are parsing template // parameters. // FIXME: This is getting out of hand, write a decent parser. - if (CurrentToken->Previous->isOneOf(tok::pipepipe, tok::ampamp) && - CurrentToken->Previous->is(TT_BinaryOperator) && - Contexts[Contexts.size() - 2].IsExpression && - !Line.startsWith(tok::kw_template)) { - return false; + if (InExpr && !Line.startsWith(tok::kw_template) && + Prev.is(TT_BinaryOperator)) { + const auto Precedence = Prev.getPrecedence(); + if (Precedence > prec::Conditional && Precedence < prec::Relational) + return false; } + if (Prev.is(TT_ConditionalExpr)) + SeenTernaryOperator = true; updateParameterCount(Left, CurrentToken); if (Style.Language == FormatStyle::LK_Proto) { if (FormatToken *Previous = CurrentToken->getPreviousNonComment()) { @@ -372,6 +382,10 @@ private: OpeningParen.Previous->is(tok::kw__Generic)) { Contexts.back().ContextType = Context::C11GenericSelection; Contexts.back().IsExpression = true; + } else if (Line.InPPDirective && + (!OpeningParen.Previous || + OpeningParen.Previous->isNot(tok::identifier))) { + Contexts.back().IsExpression = true; } else if (Contexts[Contexts.size() - 2].CaretFound) { // This is the parameter list of an ObjC block. Contexts.back().IsExpression = false; @@ -384,20 +398,7 @@ private: OpeningParen.Previous->MatchingParen->isOneOf( TT_ObjCBlockLParen, TT_FunctionTypeLParen)) { Contexts.back().IsExpression = false; - } else if (Line.InPPDirective) { - auto IsExpr = [&OpeningParen] { - const auto *Tok = OpeningParen.Previous; - if (!Tok || Tok->isNot(tok::identifier)) - return true; - Tok = Tok->Previous; - while (Tok && Tok->endsSequence(tok::coloncolon, tok::identifier)) { - assert(Tok->Previous); - Tok = Tok->Previous->Previous; - } - return !Tok || !Tok->Tok.getIdentifierInfo(); - }; - Contexts.back().IsExpression = IsExpr(); - } else if (!Line.MustBeDeclaration) { + } else if (!Line.MustBeDeclaration && !Line.InPPDirective) { bool IsForOrCatch = OpeningParen.Previous && OpeningParen.Previous->isOneOf(tok::kw_for, tok::kw_catch); diff --git a/contrib/llvm-project/clang/lib/Sema/CheckExprLifetime.cpp b/contrib/llvm-project/clang/lib/Sema/CheckExprLifetime.cpp index 5c8ef564f30a..112cf3d08182 100644 --- a/contrib/llvm-project/clang/lib/Sema/CheckExprLifetime.cpp +++ b/contrib/llvm-project/clang/lib/Sema/CheckExprLifetime.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "CheckExprLifetime.h" +#include "clang/AST/Decl.h" #include "clang/AST/Expr.h" #include "clang/Basic/DiagnosticSema.h" #include "clang/Sema/Initialization.h" @@ -548,6 +549,14 @@ static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path, EnableLifetimeWarnings); } + if (auto *M = dyn_cast<MemberExpr>(Init)) { + // Lifetime of a non-reference type field is same as base object. + if (auto *F = dyn_cast<FieldDecl>(M->getMemberDecl()); + F && !F->getType()->isReferenceType()) + visitLocalsRetainedByInitializer(Path, M->getBase(), Visit, true, + EnableLifetimeWarnings); + } + if (isa<CallExpr>(Init)) { if (EnableLifetimeWarnings) handleGslAnnotatedTypes(Path, Init, Visit); diff --git a/contrib/llvm-project/clang/lib/Sema/SemaChecking.cpp b/contrib/llvm-project/clang/lib/Sema/SemaChecking.cpp index cf1196ad23c2..9088b5e285bf 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaChecking.cpp +++ b/contrib/llvm-project/clang/lib/Sema/SemaChecking.cpp @@ -13664,10 +13664,11 @@ void Sema::DiagnoseSelfMove(const Expr *LHSExpr, const Expr *RHSExpr, //===--- Layout compatibility ----------------------------------------------// -static bool isLayoutCompatible(ASTContext &C, QualType T1, QualType T2); +static bool isLayoutCompatible(const ASTContext &C, QualType T1, QualType T2); /// Check if two enumeration types are layout-compatible. -static bool isLayoutCompatible(ASTContext &C, EnumDecl *ED1, EnumDecl *ED2) { +static bool isLayoutCompatible(const ASTContext &C, const EnumDecl *ED1, + const EnumDecl *ED2) { // C++11 [dcl.enum] p8: // Two enumeration types are layout-compatible if they have the same // underlying type. @@ -13678,8 +13679,8 @@ static bool isLayoutCompatible(ASTContext &C, EnumDecl *ED1, EnumDecl *ED2) { /// Check if two fields are layout-compatible. /// Can be used on union members, which are exempt from alignment requirement /// of common initial sequence. -static bool isLayoutCompatible(ASTContext &C, FieldDecl *Field1, - FieldDecl *Field2, +static bool isLayoutCompatible(const ASTContext &C, const FieldDecl *Field1, + const FieldDecl *Field2, bool AreUnionMembers = false) { [[maybe_unused]] const Type *Field1Parent = Field1->getParent()->getTypeForDecl(); @@ -13722,60 +13723,33 @@ static bool isLayoutCompatible(ASTContext &C, FieldDecl *Field1, /// Check if two standard-layout structs are layout-compatible. /// (C++11 [class.mem] p17) -static bool isLayoutCompatibleStruct(ASTContext &C, RecordDecl *RD1, - RecordDecl *RD2) { - // If both records are C++ classes, check that base classes match. - if (const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1)) { - // If one of records is a CXXRecordDecl we are in C++ mode, - // thus the other one is a CXXRecordDecl, too. - const CXXRecordDecl *D2CXX = cast<CXXRecordDecl>(RD2); - // Check number of base classes. - if (D1CXX->getNumBases() != D2CXX->getNumBases()) - return false; +static bool isLayoutCompatibleStruct(const ASTContext &C, const RecordDecl *RD1, + const RecordDecl *RD2) { + // Get to the class where the fields are declared + if (const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1)) + RD1 = D1CXX->getStandardLayoutBaseWithFields(); - // Check the base classes. - for (CXXRecordDecl::base_class_const_iterator - Base1 = D1CXX->bases_begin(), - BaseEnd1 = D1CXX->bases_end(), - Base2 = D2CXX->bases_begin(); - Base1 != BaseEnd1; - ++Base1, ++Base2) { - if (!isLayoutCompatible(C, Base1->getType(), Base2->getType())) - return false; - } - } else if (const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2)) { - // If only RD2 is a C++ class, it should have zero base classes. - if (D2CXX->getNumBases() > 0) - return false; - } + if (const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2)) + RD2 = D2CXX->getStandardLayoutBaseWithFields(); // Check the fields. - RecordDecl::field_iterator Field2 = RD2->field_begin(), - Field2End = RD2->field_end(), - Field1 = RD1->field_begin(), - Field1End = RD1->field_end(); - for ( ; Field1 != Field1End && Field2 != Field2End; ++Field1, ++Field2) { - if (!isLayoutCompatible(C, *Field1, *Field2)) - return false; - } - if (Field1 != Field1End || Field2 != Field2End) - return false; - - return true; + return llvm::equal(RD1->fields(), RD2->fields(), + [&C](const FieldDecl *F1, const FieldDecl *F2) -> bool { + return isLayoutCompatible(C, F1, F2); + }); } /// Check if two standard-layout unions are layout-compatible. /// (C++11 [class.mem] p18) -static bool isLayoutCompatibleUnion(ASTContext &C, RecordDecl *RD1, - RecordDecl *RD2) { - llvm::SmallPtrSet<FieldDecl *, 8> UnmatchedFields; +static bool isLayoutCompatibleUnion(const ASTContext &C, const RecordDecl *RD1, + const RecordDecl *RD2) { + llvm::SmallPtrSet<const FieldDecl *, 8> UnmatchedFields; for (auto *Field2 : RD2->fields()) UnmatchedFields.insert(Field2); for (auto *Field1 : RD1->fields()) { - llvm::SmallPtrSet<FieldDecl *, 8>::iterator - I = UnmatchedFields.begin(), - E = UnmatchedFields.end(); + auto I = UnmatchedFields.begin(); + auto E = UnmatchedFields.end(); for ( ; I != E; ++I) { if (isLayoutCompatible(C, Field1, *I, /*IsUnionMember=*/true)) { @@ -13792,8 +13766,8 @@ static bool isLayoutCompatibleUnion(ASTContext &C, RecordDecl *RD1, return UnmatchedFields.empty(); } -static bool isLayoutCompatible(ASTContext &C, RecordDecl *RD1, - RecordDecl *RD2) { +static bool isLayoutCompatible(const ASTContext &C, const RecordDecl *RD1, + const RecordDecl *RD2) { if (RD1->isUnion() != RD2->isUnion()) return false; @@ -13804,7 +13778,7 @@ static bool isLayoutCompatible(ASTContext &C, RecordDecl *RD1, } /// Check if two types are layout-compatible in C++11 sense. -static bool isLayoutCompatible(ASTContext &C, QualType T1, QualType T2) { +static bool isLayoutCompatible(const ASTContext &C, QualType T1, QualType T2) { if (T1.isNull() || T2.isNull()) return false; diff --git a/contrib/llvm-project/clang/lib/Sema/SemaDecl.cpp b/contrib/llvm-project/clang/lib/Sema/SemaDecl.cpp index bb25a0b3a45a..01231f8e385e 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaDecl.cpp +++ b/contrib/llvm-project/clang/lib/Sema/SemaDecl.cpp @@ -6890,6 +6890,11 @@ static void checkAttributesAfterMerging(Sema &S, NamedDecl &ND) { } } + if (HybridPatchableAttr *Attr = ND.getAttr<HybridPatchableAttr>()) { + if (!ND.isExternallyVisible()) + S.Diag(Attr->getLocation(), + diag::warn_attribute_hybrid_patchable_non_extern); + } if (const InheritableAttr *Attr = getDLLAttr(&ND)) { auto *VD = dyn_cast<VarDecl>(&ND); bool IsAnonymousNS = false; @@ -11009,6 +11014,9 @@ static bool AttrCompatibleWithMultiVersion(attr::Kind Kind, switch (Kind) { default: return false; + case attr::ArmLocallyStreaming: + return MVKind == MultiVersionKind::TargetVersion || + MVKind == MultiVersionKind::TargetClones; case attr::Used: return MVKind == MultiVersionKind::Target; case attr::NonNull: @@ -11145,7 +11153,21 @@ bool Sema::areMultiversionVariantFunctionsCompatible( FunctionType::ExtInfo OldTypeInfo = OldType->getExtInfo(); FunctionType::ExtInfo NewTypeInfo = NewType->getExtInfo(); - if (OldTypeInfo.getCC() != NewTypeInfo.getCC()) + const auto *OldFPT = OldFD->getType()->getAs<FunctionProtoType>(); + const auto *NewFPT = NewFD->getType()->getAs<FunctionProtoType>(); + + bool ArmStreamingCCMismatched = false; + if (OldFPT && NewFPT) { + unsigned Diff = + OldFPT->getAArch64SMEAttributes() ^ NewFPT->getAArch64SMEAttributes(); + // Arm-streaming, arm-streaming-compatible and non-streaming versions + // cannot be mixed. + if (Diff & (FunctionType::SME_PStateSMEnabledMask | + FunctionType::SME_PStateSMCompatibleMask)) + ArmStreamingCCMismatched = true; + } + + if (OldTypeInfo.getCC() != NewTypeInfo.getCC() || ArmStreamingCCMismatched) return Diag(DiffDiagIDAt.first, DiffDiagIDAt.second) << CallingConv; QualType OldReturnType = OldType->getReturnType(); @@ -11165,9 +11187,8 @@ bool Sema::areMultiversionVariantFunctionsCompatible( if (!CLinkageMayDiffer && OldFD->isExternC() != NewFD->isExternC()) return Diag(DiffDiagIDAt.first, DiffDiagIDAt.second) << LanguageLinkage; - if (CheckEquivalentExceptionSpec( - OldFD->getType()->getAs<FunctionProtoType>(), OldFD->getLocation(), - NewFD->getType()->getAs<FunctionProtoType>(), NewFD->getLocation())) + if (CheckEquivalentExceptionSpec(OldFPT, OldFD->getLocation(), NewFPT, + NewFD->getLocation())) return true; } return false; diff --git a/contrib/llvm-project/clang/lib/Sema/SemaDeclAttr.cpp b/contrib/llvm-project/clang/lib/Sema/SemaDeclAttr.cpp index 5fd8622c90dd..e2eada24f9fc 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaDeclAttr.cpp +++ b/contrib/llvm-project/clang/lib/Sema/SemaDeclAttr.cpp @@ -3024,9 +3024,6 @@ bool Sema::checkTargetVersionAttr(SourceLocation LiteralLoc, Decl *D, return Diag(LiteralLoc, diag::warn_unsupported_target_attribute) << Unsupported << None << CurFeature << TargetVersion; } - if (IsArmStreamingFunction(cast<FunctionDecl>(D), - /*IncludeLocallyStreaming=*/false)) - return Diag(LiteralLoc, diag::err_sme_streaming_cannot_be_multiversioned); return false; } @@ -3123,10 +3120,6 @@ bool Sema::checkTargetClonesAttrString( HasNotDefault = true; } } - if (IsArmStreamingFunction(cast<FunctionDecl>(D), - /*IncludeLocallyStreaming=*/false)) - return Diag(LiteralLoc, - diag::err_sme_streaming_cannot_be_multiversioned); } else { // Other targets ( currently X86 ) if (Cur.starts_with("arch=")) { @@ -6868,6 +6861,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, case ParsedAttr::AT_MSConstexpr: handleMSConstexprAttr(S, D, AL); break; + case ParsedAttr::AT_HybridPatchable: + handleSimpleAttribute<HybridPatchableAttr>(S, D, AL); + break; // HLSL attributes: case ParsedAttr::AT_HLSLNumThreads: diff --git a/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp b/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp index 40f7e9cede1f..4cd2f2802f30 100644 --- a/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp +++ b/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp @@ -147,10 +147,18 @@ using MutexDescriptor = class BlockInCriticalSectionChecker : public Checker<check::PostCall> { private: const std::array<MutexDescriptor, 8> MutexDescriptors{ - MemberMutexDescriptor({/*MatchAs=*/CDM::CXXMethod, - /*QualifiedName=*/{"std", "mutex", "lock"}, - /*RequiredArgs=*/0}, - {CDM::CXXMethod, {"std", "mutex", "unlock"}, 0}), + // NOTE: There are standard library implementations where some methods + // of `std::mutex` are inherited from an implementation detail base + // class, and those aren't matched by the name specification {"std", + // "mutex", "lock"}. + // As a workaround here we omit the class name and only require the + // presence of the name parts "std" and "lock"/"unlock". + // TODO: Ensure that CallDescription understands inherited methods. + MemberMutexDescriptor( + {/*MatchAs=*/CDM::CXXMethod, + /*QualifiedName=*/{"std", /*"mutex",*/ "lock"}, + /*RequiredArgs=*/0}, + {CDM::CXXMethod, {"std", /*"mutex",*/ "unlock"}, 0}), FirstArgMutexDescriptor({CDM::CLibrary, {"pthread_mutex_lock"}, 1}, {CDM::CLibrary, {"pthread_mutex_unlock"}, 1}), FirstArgMutexDescriptor({CDM::CLibrary, {"mtx_lock"}, 1}, diff --git a/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/Store.cpp b/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/Store.cpp index 67ca61bb56ba..b436dd746d21 100644 --- a/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/Store.cpp +++ b/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/Store.cpp @@ -472,7 +472,17 @@ SVal StoreManager::getLValueElement(QualType elementType, NonLoc Offset, const auto *ElemR = dyn_cast<ElementRegion>(BaseRegion); // Convert the offset to the appropriate size and signedness. - Offset = svalBuilder.convertToArrayIndex(Offset).castAs<NonLoc>(); + auto Off = svalBuilder.convertToArrayIndex(Offset).getAs<NonLoc>(); + if (!Off) { + // Handle cases when LazyCompoundVal is used for an array index. + // Such case is possible if code does: + // char b[4]; + // a[__builtin_bitcast(int, b)]; + // Return UnknownVal, since we cannot model it. + return UnknownVal(); + } + + Offset = Off.value(); if (!ElemR) { // If the base region is not an ElementRegion, create one. diff --git a/contrib/llvm-project/compiler-rt/lib/builtins/riscv/feature_bits.c b/contrib/llvm-project/compiler-rt/lib/builtins/riscv/feature_bits.c deleted file mode 100644 index 77422935bd2d..000000000000 --- a/contrib/llvm-project/compiler-rt/lib/builtins/riscv/feature_bits.c +++ /dev/null @@ -1,298 +0,0 @@ -//=== feature_bits.c - Update RISC-V Feature Bits Structure -*- C -*-=========// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#define RISCV_FEATURE_BITS_LENGTH 1 -struct { - unsigned length; - unsigned long long features[RISCV_FEATURE_BITS_LENGTH]; -} __riscv_feature_bits __attribute__((visibility("hidden"), nocommon)); - -#define RISCV_VENDOR_FEATURE_BITS_LENGTH 1 -struct { - unsigned vendorID; - unsigned length; - unsigned long long features[RISCV_VENDOR_FEATURE_BITS_LENGTH]; -} __riscv_vendor_feature_bits __attribute__((visibility("hidden"), nocommon)); - -// NOTE: Should sync-up with RISCVFeatures.td -// TODO: Maybe generate a header from tablegen then include it. -#define A_GROUPID 0 -#define A_BITMASK (1ULL << 0) -#define C_GROUPID 0 -#define C_BITMASK (1ULL << 2) -#define D_GROUPID 0 -#define D_BITMASK (1ULL << 3) -#define F_GROUPID 0 -#define F_BITMASK (1ULL << 5) -#define I_GROUPID 0 -#define I_BITMASK (1ULL << 8) -#define M_GROUPID 0 -#define M_BITMASK (1ULL << 12) -#define V_GROUPID 0 -#define V_BITMASK (1ULL << 21) -#define ZACAS_GROUPID 0 -#define ZACAS_BITMASK (1ULL << 26) -#define ZBA_GROUPID 0 -#define ZBA_BITMASK (1ULL << 27) -#define ZBB_GROUPID 0 -#define ZBB_BITMASK (1ULL << 28) -#define ZBC_GROUPID 0 -#define ZBC_BITMASK (1ULL << 29) -#define ZBKB_GROUPID 0 -#define ZBKB_BITMASK (1ULL << 30) -#define ZBKC_GROUPID 0 -#define ZBKC_BITMASK (1ULL << 31) -#define ZBKX_GROUPID 0 -#define ZBKX_BITMASK (1ULL << 32) -#define ZBS_GROUPID 0 -#define ZBS_BITMASK (1ULL << 33) -#define ZFA_GROUPID 0 -#define ZFA_BITMASK (1ULL << 34) -#define ZFH_GROUPID 0 -#define ZFH_BITMASK (1ULL << 35) -#define ZFHMIN_GROUPID 0 -#define ZFHMIN_BITMASK (1ULL << 36) -#define ZICBOZ_GROUPID 0 -#define ZICBOZ_BITMASK (1ULL << 37) -#define ZICOND_GROUPID 0 -#define ZICOND_BITMASK (1ULL << 38) -#define ZIHINTNTL_GROUPID 0 -#define ZIHINTNTL_BITMASK (1ULL << 39) -#define ZIHINTPAUSE_GROUPID 0 -#define ZIHINTPAUSE_BITMASK (1ULL << 40) -#define ZKND_GROUPID 0 -#define ZKND_BITMASK (1ULL << 41) -#define ZKNE_GROUPID 0 -#define ZKNE_BITMASK (1ULL << 42) -#define ZKNH_GROUPID 0 -#define ZKNH_BITMASK (1ULL << 43) -#define ZKSED_GROUPID 0 -#define ZKSED_BITMASK (1ULL << 44) -#define ZKSH_GROUPID 0 -#define ZKSH_BITMASK (1ULL << 45) -#define ZKT_GROUPID 0 -#define ZKT_BITMASK (1ULL << 46) -#define ZTSO_GROUPID 0 -#define ZTSO_BITMASK (1ULL << 47) -#define ZVBB_GROUPID 0 -#define ZVBB_BITMASK (1ULL << 48) -#define ZVBC_GROUPID 0 -#define ZVBC_BITMASK (1ULL << 49) -#define ZVFH_GROUPID 0 -#define ZVFH_BITMASK (1ULL << 50) -#define ZVFHMIN_GROUPID 0 -#define ZVFHMIN_BITMASK (1ULL << 51) -#define ZVKB_GROUPID 0 -#define ZVKB_BITMASK (1ULL << 52) -#define ZVKG_GROUPID 0 -#define ZVKG_BITMASK (1ULL << 53) -#define ZVKNED_GROUPID 0 -#define ZVKNED_BITMASK (1ULL << 54) -#define ZVKNHA_GROUPID 0 -#define ZVKNHA_BITMASK (1ULL << 55) -#define ZVKNHB_GROUPID 0 -#define ZVKNHB_BITMASK (1ULL << 56) -#define ZVKSED_GROUPID 0 -#define ZVKSED_BITMASK (1ULL << 57) -#define ZVKSH_GROUPID 0 -#define ZVKSH_BITMASK (1ULL << 58) -#define ZVKT_GROUPID 0 -#define ZVKT_BITMASK (1ULL << 59) - -#if defined(__linux__) - -static long syscall_impl_5_args(long number, long arg1, long arg2, long arg3, - long arg4, long arg5) { - register long a7 __asm__("a7") = number; - register long a0 __asm__("a0") = arg1; - register long a1 __asm__("a1") = arg2; - register long a2 __asm__("a2") = arg3; - register long a3 __asm__("a3") = arg4; - register long a4 __asm__("a4") = arg5; - __asm__ __volatile__("ecall\n\t" - : "=r"(a0) - : "r"(a7), "r"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a4) - : "memory"); - return a0; -} - -#define RISCV_HWPROBE_KEY_MVENDORID 0 -#define RISCV_HWPROBE_KEY_MARCHID 1 -#define RISCV_HWPROBE_KEY_MIMPID 2 -#define RISCV_HWPROBE_KEY_BASE_BEHAVIOR 3 -#define RISCV_HWPROBE_BASE_BEHAVIOR_IMA (1ULL << 0) -#define RISCV_HWPROBE_KEY_IMA_EXT_0 4 -#define RISCV_HWPROBE_IMA_FD (1ULL << 0) -#define RISCV_HWPROBE_IMA_C (1ULL << 1) -#define RISCV_HWPROBE_IMA_V (1ULL << 2) -#define RISCV_HWPROBE_EXT_ZBA (1ULL << 3) -#define RISCV_HWPROBE_EXT_ZBB (1ULL << 4) -#define RISCV_HWPROBE_EXT_ZBS (1ULL << 5) -#define RISCV_HWPROBE_EXT_ZICBOZ (1ULL << 6) -#define RISCV_HWPROBE_EXT_ZBC (1ULL << 7) -#define RISCV_HWPROBE_EXT_ZBKB (1ULL << 8) -#define RISCV_HWPROBE_EXT_ZBKC (1ULL << 9) -#define RISCV_HWPROBE_EXT_ZBKX (1ULL << 10) -#define RISCV_HWPROBE_EXT_ZKND (1ULL << 11) -#define RISCV_HWPROBE_EXT_ZKNE (1ULL << 12) -#define RISCV_HWPROBE_EXT_ZKNH (1ULL << 13) -#define RISCV_HWPROBE_EXT_ZKSED (1ULL << 14) -#define RISCV_HWPROBE_EXT_ZKSH (1ULL << 15) -#define RISCV_HWPROBE_EXT_ZKT (1ULL << 16) -#define RISCV_HWPROBE_EXT_ZVBB (1ULL << 17) -#define RISCV_HWPROBE_EXT_ZVBC (1ULL << 18) -#define RISCV_HWPROBE_EXT_ZVKB (1ULL << 19) -#define RISCV_HWPROBE_EXT_ZVKG (1ULL << 20) -#define RISCV_HWPROBE_EXT_ZVKNED (1ULL << 21) -#define RISCV_HWPROBE_EXT_ZVKNHA (1ULL << 22) -#define RISCV_HWPROBE_EXT_ZVKNHB (1ULL << 23) -#define RISCV_HWPROBE_EXT_ZVKSED (1ULL << 24) -#define RISCV_HWPROBE_EXT_ZVKSH (1ULL << 25) -#define RISCV_HWPROBE_EXT_ZVKT (1ULL << 26) -#define RISCV_HWPROBE_EXT_ZFH (1ULL << 27) -#define RISCV_HWPROBE_EXT_ZFHMIN (1ULL << 28) -#define RISCV_HWPROBE_EXT_ZIHINTNTL (1ULL << 29) -#define RISCV_HWPROBE_EXT_ZVFH (1ULL << 30) -#define RISCV_HWPROBE_EXT_ZVFHMIN (1ULL << 31) -#define RISCV_HWPROBE_EXT_ZFA (1ULL << 32) -#define RISCV_HWPROBE_EXT_ZTSO (1ULL << 33) -#define RISCV_HWPROBE_EXT_ZACAS (1ULL << 34) -#define RISCV_HWPROBE_EXT_ZICOND (1ULL << 35) -#define RISCV_HWPROBE_EXT_ZIHINTPAUSE (1ULL << 36) -#define RISCV_HWPROBE_KEY_CPUPERF_0 5 -#define RISCV_HWPROBE_MISALIGNED_UNKNOWN (0 << 0) -#define RISCV_HWPROBE_MISALIGNED_EMULATED (1ULL << 0) -#define RISCV_HWPROBE_MISALIGNED_SLOW (2 << 0) -#define RISCV_HWPROBE_MISALIGNED_FAST (3 << 0) -#define RISCV_HWPROBE_MISALIGNED_UNSUPPORTED (4 << 0) -#define RISCV_HWPROBE_MISALIGNED_MASK (7 << 0) -#define RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE 6 -/* Increase RISCV_HWPROBE_MAX_KEY when adding items. */ - -struct riscv_hwprobe { - long long key; - unsigned long long value; -}; - -#define __NR_riscv_hwprobe 258 -static long initHwProbe(struct riscv_hwprobe *Hwprobes, int len) { - return syscall_impl_5_args(__NR_riscv_hwprobe, (long)Hwprobes, len, 0, 0, 0); -} - -#define SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(EXTNAME) \ - SET_SINGLE_IMAEXT_RISCV_FEATURE(RISCV_HWPROBE_EXT_##EXTNAME, EXTNAME) - -#define SET_SINGLE_IMAEXT_RISCV_FEATURE(HWPROBE_BITMASK, EXT) \ - SET_SINGLE_RISCV_FEATURE(IMAEXT0Value &HWPROBE_BITMASK, EXT) - -#define SET_SINGLE_RISCV_FEATURE(COND, EXT) \ - if (COND) { \ - SET_RISCV_FEATURE(EXT); \ - } - -#define SET_RISCV_FEATURE(EXT) features[EXT##_GROUPID] |= EXT##_BITMASK - -static void initRISCVFeature(struct riscv_hwprobe Hwprobes[]) { - - // Note: If a hwprobe key is unknown to the kernel, its key field - // will be cleared to -1, and its value set to 0. - // This unsets all extension bitmask bits. - - // Init vendor extension - __riscv_vendor_feature_bits.length = 0; - __riscv_vendor_feature_bits.vendorID = Hwprobes[2].value; - - // Init standard extension - // TODO: Maybe Extension implied generate from tablegen? - __riscv_feature_bits.length = RISCV_FEATURE_BITS_LENGTH; - - unsigned long long features[RISCV_FEATURE_BITS_LENGTH]; - int i; - - for (i = 0; i < RISCV_FEATURE_BITS_LENGTH; i++) - features[i] = 0; - - // Check RISCV_HWPROBE_KEY_BASE_BEHAVIOR - unsigned long long BaseValue = Hwprobes[0].value; - if (BaseValue & RISCV_HWPROBE_BASE_BEHAVIOR_IMA) { - SET_RISCV_FEATURE(I); - SET_RISCV_FEATURE(M); - SET_RISCV_FEATURE(A); - } - - // Check RISCV_HWPROBE_KEY_IMA_EXT_0 - unsigned long long IMAEXT0Value = Hwprobes[1].value; - if (IMAEXT0Value & RISCV_HWPROBE_IMA_FD) { - SET_RISCV_FEATURE(F); - SET_RISCV_FEATURE(D); - } - - SET_SINGLE_IMAEXT_RISCV_FEATURE(RISCV_HWPROBE_IMA_C, C); - SET_SINGLE_IMAEXT_RISCV_FEATURE(RISCV_HWPROBE_IMA_V, V); - SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZBA); *** 2681 LINES SKIPPED ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202412011254.4B1CsN7d094167>