[llvm-branch-commits] [llvm] release/18.x: [Codegen][X86] Fix /HOTPATCH with clang-cl and inline asm (#87639) (PR #88388)
https://github.com/aganea approved this pull request. It think this should be good to go, but ideally I'd like someone else to sign off please. @phoebewang @KanRobert @sylvain-audi https://github.com/llvm/llvm-project/pull/88388 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] release/19.x: Win release packaging: Don't try to use rpmalloc for 32-bit x86 (#106969) (PR #106985)
https://github.com/aganea approved this pull request. https://github.com/llvm/llvm-project/pull/106985 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [lld] e7a371f - [LLD][COFF] Avoid std::vector resizes during type merging
Author: Alexandre Ganea Date: 2021-01-13T14:35:03-05:00 New Revision: e7a371f9fd0076c187f4cd1a9c7546867faeb19b URL: https://github.com/llvm/llvm-project/commit/e7a371f9fd0076c187f4cd1a9c7546867faeb19b DIFF: https://github.com/llvm/llvm-project/commit/e7a371f9fd0076c187f4cd1a9c7546867faeb19b.diff LOG: [LLD][COFF] Avoid std::vector resizes during type merging Consistently saves approx. 0.6 sec (out of 18 sec) on a large output (400 MB EXE, 2 GB PDB). Differential Revision: https://reviews.llvm.org/D94555 Added: Modified: lld/COFF/DebugTypes.cpp Removed: diff --git a/lld/COFF/DebugTypes.cpp b/lld/COFF/DebugTypes.cpp index 52c24aaf214f..fedcb054540f 100644 --- a/lld/COFF/DebugTypes.cpp +++ b/lld/COFF/DebugTypes.cpp @@ -679,6 +679,26 @@ void TpiSource::mergeUniqueTypeRecords(ArrayRef typeRecords, auto nextUniqueIndex = uniqueTypes.begin(); assert(mergedTpi.recs.empty()); assert(mergedIpi.recs.empty()); + + // Pre-compute the number of elements in advance to avoid std::vector resizes. + unsigned nbTpiRecs = 0; + unsigned nbIpiRecs = 0; + forEachTypeChecked(typeRecords, [&](const CVType &ty) { +if (nextUniqueIndex != uniqueTypes.end() && +*nextUniqueIndex == ghashIndex) { + assert(ty.length() <= codeview::MaxRecordLength); + size_t newSize = alignTo(ty.length(), 4); + (isIdRecord(ty.kind()) ? nbIpiRecs : nbTpiRecs) += newSize; + ++nextUniqueIndex; +} +++ghashIndex; + }); + mergedTpi.recs.reserve(nbTpiRecs); + mergedIpi.recs.reserve(nbIpiRecs); + + // Do the actual type merge. + ghashIndex = 0; + nextUniqueIndex = uniqueTypes.begin(); forEachTypeChecked(typeRecords, [&](const CVType &ty) { if (nextUniqueIndex != uniqueTypes.end() && *nextUniqueIndex == ghashIndex) { ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] 336ab2d - [Support] On Windows, take the affinity mask into account
Author: Alexandre Ganea Date: 2021-01-13T21:00:09-05:00 New Revision: 336ab2d51dfdd5ca09c2a9c506453db4fe653584 URL: https://github.com/llvm/llvm-project/commit/336ab2d51dfdd5ca09c2a9c506453db4fe653584 DIFF: https://github.com/llvm/llvm-project/commit/336ab2d51dfdd5ca09c2a9c506453db4fe653584.diff LOG: [Support] On Windows, take the affinity mask into account The number of hardware threads available to a ThreadPool can be limited if setting an affinity mask. For example: > start /B /AFFINITY 0xF lld-link.exe ... Would let LLD only use 4 hyper-threads. Previously, there was an outstanding issue on Windows Server 2019 on dual-CPU machines, which was preventing from using both CPU sockets. In normal conditions, when no affinity mask was set, ProcessorGroup::AllThreads was different from ProcessorGroup::UsableThreads. The previous code in llvm/lib/Support/Windows/Threading.inc L201 was improperly assuming those two values to be equal, and consequently was limiting the execution to only one CPU socket. Differential Revision: https://reviews.llvm.org/D92419 Added: Modified: llvm/include/llvm/Support/Program.h llvm/lib/Support/Program.cpp llvm/lib/Support/Unix/Program.inc llvm/lib/Support/Windows/Program.inc llvm/lib/Support/Windows/Threading.inc llvm/unittests/Support/ThreadPool.cpp Removed: diff --git a/llvm/include/llvm/Support/Program.h b/llvm/include/llvm/Support/Program.h index b32de47adb57..bfd271958788 100644 --- a/llvm/include/llvm/Support/Program.h +++ b/llvm/include/llvm/Support/Program.h @@ -14,6 +14,7 @@ #define LLVM_SUPPORT_PROGRAM_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/BitVector.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/StringRef.h" #include "llvm/Config/llvm-config.h" @@ -125,9 +126,11 @@ namespace sys { ///< string is non-empty upon return an error occurred while invoking the ///< program. bool *ExecutionFailed = nullptr, - Optional *ProcStat = nullptr ///< If non-zero, provides - /// a pointer to a structure in which process execution statistics will be - /// stored. + Optional *ProcStat = nullptr, ///< If non-zero, + /// provides a pointer to a structure in which process execution + /// statistics will be stored. + BitVector *AffinityMask = nullptr ///< CPUs or processors the new +/// program shall run on. ); /// Similar to ExecuteAndWait, but returns immediately. @@ -140,7 +143,8 @@ namespace sys { ArrayRef> Redirects = {}, unsigned MemoryLimit = 0, std::string *ErrMsg = nullptr, -bool *ExecutionFailed = nullptr); +bool *ExecutionFailed = nullptr, +BitVector *AffinityMask = nullptr); /// Return true if the given arguments fit within system-specific /// argument length limits. diff --git a/llvm/lib/Support/Program.cpp b/llvm/lib/Support/Program.cpp index 5294f65bd5a5..c7a59642b27e 100644 --- a/llvm/lib/Support/Program.cpp +++ b/llvm/lib/Support/Program.cpp @@ -26,17 +26,20 @@ using namespace sys; static bool Execute(ProcessInfo &PI, StringRef Program, ArrayRef Args, Optional> Env, ArrayRef> Redirects, -unsigned MemoryLimit, std::string *ErrMsg); +unsigned MemoryLimit, std::string *ErrMsg, +BitVector *AffinityMask); int sys::ExecuteAndWait(StringRef Program, ArrayRef Args, Optional> Env, ArrayRef> Redirects, unsigned SecondsToWait, unsigned MemoryLimit, std::string *ErrMsg, bool *ExecutionFailed, -Optional *ProcStat) { +Optional *ProcStat, +BitVector *AffinityMask) { assert(Redirects.empty() || Redirects.size() == 3); ProcessInfo PI; - if (Execute(PI, Program, Args, Env, Redirects, MemoryLimit, ErrMsg)) { + if (Execute(PI, Program, Args, Env, Redirects, MemoryLimit, ErrMsg, + AffinityMask)) { if (ExecutionFailed) *ExecutionFailed = false; ProcessInfo Result = @@ -55,12 +58,13 @@ ProcessInfo sys::ExecuteNoWait(StringRef Program, ArrayRef Args, Optional> Env, ArrayRef> Redirects, unsigned MemoryLimit, std::string *ErrMsg, - bool *ExecutionFailed) { + bool *ExecutionFailed, BitVector *AffinityMask) { assert(Redirects.empty() || Redirects.size() == 3); ProcessInfo PI; if (ExecutionFailed) *ExecutionFailed = false; - if (!Execute(PI, Program, Args, Env, Redirects, Memor
[llvm-branch-commits] [llvm] eec8568 - Revert "[Support] On Windows, take the affinity mask into account"
Author: Alexandre Ganea Date: 2021-01-13T21:34:54-05:00 New Revision: eec856848ccc481b2704ebf64d725e635a3d7dca URL: https://github.com/llvm/llvm-project/commit/eec856848ccc481b2704ebf64d725e635a3d7dca DIFF: https://github.com/llvm/llvm-project/commit/eec856848ccc481b2704ebf64d725e635a3d7dca.diff LOG: Revert "[Support] On Windows, take the affinity mask into account" This reverts commit 336ab2d51dfdd5ca09c2a9c506453db4fe653584. Added: Modified: llvm/include/llvm/Support/Program.h llvm/lib/Support/Program.cpp llvm/lib/Support/Unix/Program.inc llvm/lib/Support/Windows/Program.inc llvm/lib/Support/Windows/Threading.inc llvm/unittests/Support/ThreadPool.cpp Removed: diff --git a/llvm/include/llvm/Support/Program.h b/llvm/include/llvm/Support/Program.h index bfd271958788..b32de47adb57 100644 --- a/llvm/include/llvm/Support/Program.h +++ b/llvm/include/llvm/Support/Program.h @@ -14,7 +14,6 @@ #define LLVM_SUPPORT_PROGRAM_H #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/BitVector.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/StringRef.h" #include "llvm/Config/llvm-config.h" @@ -126,11 +125,9 @@ namespace sys { ///< string is non-empty upon return an error occurred while invoking the ///< program. bool *ExecutionFailed = nullptr, - Optional *ProcStat = nullptr, ///< If non-zero, - /// provides a pointer to a structure in which process execution - /// statistics will be stored. - BitVector *AffinityMask = nullptr ///< CPUs or processors the new -/// program shall run on. + Optional *ProcStat = nullptr ///< If non-zero, provides + /// a pointer to a structure in which process execution statistics will be + /// stored. ); /// Similar to ExecuteAndWait, but returns immediately. @@ -143,8 +140,7 @@ namespace sys { ArrayRef> Redirects = {}, unsigned MemoryLimit = 0, std::string *ErrMsg = nullptr, -bool *ExecutionFailed = nullptr, -BitVector *AffinityMask = nullptr); +bool *ExecutionFailed = nullptr); /// Return true if the given arguments fit within system-specific /// argument length limits. diff --git a/llvm/lib/Support/Program.cpp b/llvm/lib/Support/Program.cpp index c7a59642b27e..5294f65bd5a5 100644 --- a/llvm/lib/Support/Program.cpp +++ b/llvm/lib/Support/Program.cpp @@ -26,20 +26,17 @@ using namespace sys; static bool Execute(ProcessInfo &PI, StringRef Program, ArrayRef Args, Optional> Env, ArrayRef> Redirects, -unsigned MemoryLimit, std::string *ErrMsg, -BitVector *AffinityMask); +unsigned MemoryLimit, std::string *ErrMsg); int sys::ExecuteAndWait(StringRef Program, ArrayRef Args, Optional> Env, ArrayRef> Redirects, unsigned SecondsToWait, unsigned MemoryLimit, std::string *ErrMsg, bool *ExecutionFailed, -Optional *ProcStat, -BitVector *AffinityMask) { +Optional *ProcStat) { assert(Redirects.empty() || Redirects.size() == 3); ProcessInfo PI; - if (Execute(PI, Program, Args, Env, Redirects, MemoryLimit, ErrMsg, - AffinityMask)) { + if (Execute(PI, Program, Args, Env, Redirects, MemoryLimit, ErrMsg)) { if (ExecutionFailed) *ExecutionFailed = false; ProcessInfo Result = @@ -58,13 +55,12 @@ ProcessInfo sys::ExecuteNoWait(StringRef Program, ArrayRef Args, Optional> Env, ArrayRef> Redirects, unsigned MemoryLimit, std::string *ErrMsg, - bool *ExecutionFailed, BitVector *AffinityMask) { + bool *ExecutionFailed) { assert(Redirects.empty() || Redirects.size() == 3); ProcessInfo PI; if (ExecutionFailed) *ExecutionFailed = false; - if (!Execute(PI, Program, Args, Env, Redirects, MemoryLimit, ErrMsg, - AffinityMask)) + if (!Execute(PI, Program, Args, Env, Redirects, MemoryLimit, ErrMsg)) if (ExecutionFailed) *ExecutionFailed = true; diff --git a/llvm/lib/Support/Unix/Program.inc b/llvm/lib/Support/Unix/Program.inc index fb56fa4b0d1d..8f41fc015163 100644 --- a/llvm/lib/Support/Unix/Program.inc +++ b/llvm/lib/Support/Unix/Program.inc @@ -174,8 +174,7 @@ toNullTerminatedCStringArray(ArrayRef Strings, StringSaver &Saver) { static bool Execute(ProcessInfo &PI, StringRef Program, ArrayRef Args, Optional> Env, ArrayRef> Redirects, -
[llvm-branch-commits] [llvm] 6abbba3 - Revert "Fix llvm::Optional build breaks in MSVC using std::is_trivially_copyable"
Author: Alexandre Ganea Date: 2021-01-14T08:35:38-05:00 New Revision: 6abbba3fca9fdf8d31f74800a7ddb40b103ae6e3 URL: https://github.com/llvm/llvm-project/commit/6abbba3fca9fdf8d31f74800a7ddb40b103ae6e3 DIFF: https://github.com/llvm/llvm-project/commit/6abbba3fca9fdf8d31f74800a7ddb40b103ae6e3.diff LOG: Revert "Fix llvm::Optional build breaks in MSVC using std::is_trivially_copyable" This reverts commit 854f0984f0b7ab9a9a541a4bcda7ea173e4113d3. This breaks compilation with clang-cl on Windows, while in a MSVC 16.8 cmd.exe. This also breaks PPC: http://lab.llvm.org:8011/#/builders/93/builds/1435 And: https://reviews.llvm.org/D93510#2497737 Added: Modified: llvm/include/llvm/ADT/Optional.h llvm/unittests/ADT/OptionalTest.cpp Removed: diff --git a/llvm/include/llvm/ADT/Optional.h b/llvm/include/llvm/ADT/Optional.h index 820e586ff7dd..daa9ee627fa9 100644 --- a/llvm/include/llvm/ADT/Optional.h +++ b/llvm/include/llvm/ADT/Optional.h @@ -33,12 +33,7 @@ namespace optional_detail { struct in_place_t {}; /// Storage for any type. -template ::value && - std::is_trivially_copy_assignable::value && - (std::is_trivially_move_constructible::value || - !std::is_move_constructible::value) && - (std::is_trivially_move_assignable::value || - !std::is_move_assignable::value))> +template ::value> class OptionalStorage { union { char empty; diff --git a/llvm/unittests/ADT/OptionalTest.cpp b/llvm/unittests/ADT/OptionalTest.cpp index 235b834887d1..c7fa796a2d7f 100644 --- a/llvm/unittests/ADT/OptionalTest.cpp +++ b/llvm/unittests/ADT/OptionalTest.cpp @@ -390,127 +390,6 @@ TEST(OptionalTest, ImmovableEmplace) { EXPECT_EQ(0u, Immovable::Destructions); } -// Craft a class which is_trivially_copyable, but not -// is_trivially_copy_constructible. -struct NonTCopy { - NonTCopy() = default; - - // Delete the volatile copy constructor to engage the "rule of 3" and delete - // any unspecified copy assignment or constructor. - NonTCopy(volatile NonTCopy const &) = delete; - - // Leave the non-volatile default copy constructor unspecified (deleted by - // rule of 3) - - // This template can serve as the copy constructor, but isn't chosen - // by =default in a class with a 'NonTCopy' member. - template - NonTCopy(Self const &Other) : Val(Other.Val) {} - - NonTCopy &operator=(NonTCopy const &) = default; - - int Val{0}; -}; - -#if defined(_MSC_VER) && _MSC_VER >= 1927 -// Currently only true on recent MSVC releases. -static_assert(std::is_trivially_copyable::value, - "Expect NonTCopy to be trivially copyable"); - -static_assert(!std::is_trivially_copy_constructible::value, - "Expect NonTCopy not to be trivially copy constructible."); -#endif // defined(_MSC_VER) && _MSC_VER >= 1927 - -TEST(OptionalTest, DeletedCopyConstructor) { - - // Expect compile to fail if 'trivial' version of - // optional_detail::OptionalStorage is chosen. - using NonTCopyOptT = Optional; - NonTCopyOptT NonTCopy1; - - // Check that the Optional can be copy constructed. - NonTCopyOptT NonTCopy2{NonTCopy1}; - - // Check that the Optional can be copy assigned. - NonTCopy1 = NonTCopy2; -} - -// Craft a class which is_trivially_copyable, but not -// is_trivially_copy_assignable. -class NonTAssign { -public: - NonTAssign() = default; - NonTAssign(NonTAssign const &) = default; - - // Delete the volatile copy assignment to engage the "rule of 3" and delete - // any unspecified copy assignment or constructor. - NonTAssign &operator=(volatile NonTAssign const &) = delete; - - // Leave the non-volatile default copy assignment unspecified (deleted by rule - // of 3). - - // This template can serve as the copy assignment, but isn't chosen - // by =default in a class with a 'NonTAssign' member. - template - NonTAssign &operator=(Self const &Other) { -A = Other.A; -return *this; - } - - int A{0}; -}; - -#if defined(_MSC_VER) && _MSC_VER >= 1927 -// Currently only true on recent MSVC releases. -static_assert(std::is_trivially_copyable::value, - "Expect NonTAssign to be trivially copyable"); - -static_assert(!std::is_trivially_copy_assignable::value, - "Expect NonTAssign not to be trivially assignable."); -#endif // defined(_MSC_VER) && _MSC_VER >= 1927 - -TEST(OptionalTest, DeletedCopyAssignment) { - - // Expect compile to fail if 'trivial' version of - // optional_detail::OptionalStorage is chosen. - using NonTAssignOptT = Optional; - NonTAssignOptT NonTAssign1; - - // Check that the Optional can be copy constructed. - NonTAssignOptT NonTAssign2{NonTAssign1}; - - // Check that the Optional can be copy assigned. - NonTAssign1 = NonTAssign2; -} - -struct NoTMove { - NoTMove() = default; - NoTMove(NoTMov
[llvm-branch-commits] [llvm] 4fcb255 - Re-land [Support] On Windows, take the affinity mask into account
Author: Alexandre Ganea Date: 2021-01-14T17:03:22-05:00 New Revision: 4fcb25583c3ccbe10c4367d02086269e5fa0bb87 URL: https://github.com/llvm/llvm-project/commit/4fcb25583c3ccbe10c4367d02086269e5fa0bb87 DIFF: https://github.com/llvm/llvm-project/commit/4fcb25583c3ccbe10c4367d02086269e5fa0bb87.diff LOG: Re-land [Support] On Windows, take the affinity mask into account The number of hardware threads available to a ThreadPool can be limited if setting an affinity mask. For example: > start /B /AFFINITY 0xF lld-link.exe ... Would let LLD only use 4 hyper-threads. Previously, there was an outstanding issue on Windows Server 2019 on dual-CPU machines, which was preventing from using both CPU sockets. In normal conditions, when no affinity mask was set, ProcessorGroup::AllThreads was different from ProcessorGroup::UsableThreads. The previous code in llvm/lib/Support/Windows/Threading.inc L201 was improperly assuming those two values to be equal, and consequently was limiting the execution to only one CPU socket. Differential Revision: https://reviews.llvm.org/D92419 Added: Modified: llvm/include/llvm/Support/Program.h llvm/lib/Support/Program.cpp llvm/lib/Support/Unix/Program.inc llvm/lib/Support/Windows/Program.inc llvm/lib/Support/Windows/Threading.inc llvm/unittests/Support/ThreadPool.cpp Removed: diff --git a/llvm/include/llvm/Support/Program.h b/llvm/include/llvm/Support/Program.h index b32de47adb57..bfd271958788 100644 --- a/llvm/include/llvm/Support/Program.h +++ b/llvm/include/llvm/Support/Program.h @@ -14,6 +14,7 @@ #define LLVM_SUPPORT_PROGRAM_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/BitVector.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/StringRef.h" #include "llvm/Config/llvm-config.h" @@ -125,9 +126,11 @@ namespace sys { ///< string is non-empty upon return an error occurred while invoking the ///< program. bool *ExecutionFailed = nullptr, - Optional *ProcStat = nullptr ///< If non-zero, provides - /// a pointer to a structure in which process execution statistics will be - /// stored. + Optional *ProcStat = nullptr, ///< If non-zero, + /// provides a pointer to a structure in which process execution + /// statistics will be stored. + BitVector *AffinityMask = nullptr ///< CPUs or processors the new +/// program shall run on. ); /// Similar to ExecuteAndWait, but returns immediately. @@ -140,7 +143,8 @@ namespace sys { ArrayRef> Redirects = {}, unsigned MemoryLimit = 0, std::string *ErrMsg = nullptr, -bool *ExecutionFailed = nullptr); +bool *ExecutionFailed = nullptr, +BitVector *AffinityMask = nullptr); /// Return true if the given arguments fit within system-specific /// argument length limits. diff --git a/llvm/lib/Support/Program.cpp b/llvm/lib/Support/Program.cpp index 5294f65bd5a5..c7a59642b27e 100644 --- a/llvm/lib/Support/Program.cpp +++ b/llvm/lib/Support/Program.cpp @@ -26,17 +26,20 @@ using namespace sys; static bool Execute(ProcessInfo &PI, StringRef Program, ArrayRef Args, Optional> Env, ArrayRef> Redirects, -unsigned MemoryLimit, std::string *ErrMsg); +unsigned MemoryLimit, std::string *ErrMsg, +BitVector *AffinityMask); int sys::ExecuteAndWait(StringRef Program, ArrayRef Args, Optional> Env, ArrayRef> Redirects, unsigned SecondsToWait, unsigned MemoryLimit, std::string *ErrMsg, bool *ExecutionFailed, -Optional *ProcStat) { +Optional *ProcStat, +BitVector *AffinityMask) { assert(Redirects.empty() || Redirects.size() == 3); ProcessInfo PI; - if (Execute(PI, Program, Args, Env, Redirects, MemoryLimit, ErrMsg)) { + if (Execute(PI, Program, Args, Env, Redirects, MemoryLimit, ErrMsg, + AffinityMask)) { if (ExecutionFailed) *ExecutionFailed = false; ProcessInfo Result = @@ -55,12 +58,13 @@ ProcessInfo sys::ExecuteNoWait(StringRef Program, ArrayRef Args, Optional> Env, ArrayRef> Redirects, unsigned MemoryLimit, std::string *ErrMsg, - bool *ExecutionFailed) { + bool *ExecutionFailed, BitVector *AffinityMask) { assert(Redirects.empty() || Redirects.size() == 3); ProcessInfo PI; if (ExecutionFailed) *ExecutionFailed = false; - if (!Execute(PI, Program, Args, Env, Redi
[llvm-branch-commits] [llvm] 25c1578 - Fix llvm::Optional build breaks in MSVC using std::is_trivially_copyable
Author: James Player Date: 2021-01-16T09:37:04-05:00 New Revision: 25c1578a46ff93f920b7ad4e3057465902ced8f5 URL: https://github.com/llvm/llvm-project/commit/25c1578a46ff93f920b7ad4e3057465902ced8f5 DIFF: https://github.com/llvm/llvm-project/commit/25c1578a46ff93f920b7ad4e3057465902ced8f5.diff LOG: Fix llvm::Optional build breaks in MSVC using std::is_trivially_copyable Current code breaks this version of MSVC due to a mismatch between `std::is_trivially_copyable` and `llvm::is_trivially_copyable` for `std::pair` instantiations. Hence I was attempting to use `std::is_trivially_copyable` to set `llvm::is_trivially_copyable::value`. I spent some time root causing an `llvm::Optional` build error on MSVC 16.8.3 related to the change described above: ``` 62>C:\src\ocg_llvm\llvm-project\llvm\include\llvm/ADT/BreadthFirstIterator.h(96,12): error C2280: 'llvm::Optional::NodeSubset> *,llvm::Optional::ChildIterator>>> &llvm::Optional::NodeSubset> *,llvm::Optional::ChildIterator>>>::operator =(const llvm::Optional::NodeSubset> *,llvm::Optional::ChildIterator>>> &)': attempting to reference a deleted function (compiling source file C:\src\ocg_llvm\llvm-project\llvm\unittests\ADT\BreadthFirstIteratorTest.cpp) ... ``` The "trivial" specialization of `optional_detail::OptionalStorage` assumes that the value type is trivially copy constructible and trivially copy assignable. The specialization is invoked based on a check of `is_trivially_copyable` alone, which does not imply both `is_trivially_copy_assignable` and `is_trivially_copy_constructible` are true. [[ https://en.cppreference.com/w/cpp/named_req/TriviallyCopyable | According to the spec ]], a deleted assignment operator does not make `is_trivially_copyable` false. So I think all these properties need to be checked explicitly in order to specialize `OptionalStorage` to the "trivial" version: ``` /// Storage for any type. template ::value && std::is_trivially_copy_assignable::value> class OptionalStorage { ``` Above fixed my build break in MSVC, but I think we need to explicitly check `is_trivially_copy_constructible` too since it might be possible the copy constructor is deleted. Also would be ideal to move over to `std::is_trivially_copyable` instead of the `llvm` namespace verson. Reviewed By: dblaikie Differential Revision: https://reviews.llvm.org/D93510 Added: Modified: llvm/include/llvm/ADT/Optional.h llvm/unittests/ADT/OptionalTest.cpp Removed: diff --git a/llvm/include/llvm/ADT/Optional.h b/llvm/include/llvm/ADT/Optional.h index daa9ee627fa9..a285c81d1be8 100644 --- a/llvm/include/llvm/ADT/Optional.h +++ b/llvm/include/llvm/ADT/Optional.h @@ -33,7 +33,30 @@ namespace optional_detail { struct in_place_t {}; /// Storage for any type. -template ::value> +// +// The specialization condition intentionally uses +// llvm::is_trivially_copy_constructible instead of +// std::is_trivially_copy_constructible. GCC versions prior to 7.4 may +// instantiate the copy constructor of `T` when +// std::is_trivially_copy_constructible is instantiated. This causes +// compilation to fail if we query the trivially copy constructible property of +// a class which is not copy constructible. +// +// The current implementation of OptionalStorage insists that in order to use +// the trivial specialization, the value_type must be trivially copy +// constructible and trivially copy assignable due to =default implementations +// of the copy/move constructor/assignment. It does not follow that this is +// necessarily the case std::is_trivially_copyable is true (hence the expanded +// specialization condition). +// +// The move constructible / assignable conditions emulate the remaining behavior +// of std::is_trivially_copyable. +template ::value && + std::is_trivially_copy_assignable::value && + (std::is_trivially_move_constructible::value || + !std::is_move_constructible::value) && + (std::is_trivially_move_assignable::value || + !std::is_move_assignable::value))> class OptionalStorage { union { char empty; diff --git a/llvm/unittests/ADT/OptionalTest.cpp b/llvm/unittests/ADT/OptionalTest.cpp index c7fa796a2d7f..d40e21255f80 100644 --- a/llvm/unittests/ADT/OptionalTest.cpp +++ b/llvm/unittests/ADT/OptionalTest.cpp @@ -8,6 +8,7 @@ #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringMap.h" #include "llvm/Support/raw_ostream.h" #include "gtest/gtest-spi.h" #include "gtest/gtest.h" @@ -390,6 +391,143 @@ TEST(OptionalTest, ImmovableEmplace) { EXPECT_EQ(0u, Immovable::Destructions); } +// Craft a class which is_trivially_copyable, but not +// is_trivially_copy_constructible. +struct NonTCopy { + NonTCopy()
[llvm-branch-commits] [clang] d015445 - Silence warning: comparison of integers of different signs: 'const unsigned int' and 'const long' [-Wsign-compare]
Author: Alexandre Ganea Date: 2021-01-07T13:01:06-05:00 New Revision: d0154456e61c5ab79e25fc9b8bb684ebdca3a7c2 URL: https://github.com/llvm/llvm-project/commit/d0154456e61c5ab79e25fc9b8bb684ebdca3a7c2 DIFF: https://github.com/llvm/llvm-project/commit/d0154456e61c5ab79e25fc9b8bb684ebdca3a7c2.diff LOG: Silence warning: comparison of integers of different signs: 'const unsigned int' and 'const long' [-Wsign-compare] (off_t being a signed type) Added: Modified: clang/unittests/Basic/FileEntryTest.cpp Removed: diff --git a/clang/unittests/Basic/FileEntryTest.cpp b/clang/unittests/Basic/FileEntryTest.cpp index a3e03e6c7c29..16c8e57d9a17 100644 --- a/clang/unittests/Basic/FileEntryTest.cpp +++ b/clang/unittests/Basic/FileEntryTest.cpp @@ -57,7 +57,7 @@ struct RefMaps { TEST(FileEntryTest, Constructor) { FileEntry FE; - EXPECT_EQ(0U, FE.getSize()); + EXPECT_EQ(0, FE.getSize()); EXPECT_EQ(0, FE.getModificationTime()); EXPECT_EQ(nullptr, FE.getDir()); EXPECT_EQ(0U, FE.getUniqueID().getDevice()); ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] 3854b81 - [Clang][Driver] Fix read-after-free when using /clang:
Author: Alexandre Ganea Date: 2021-01-07T15:15:13-05:00 New Revision: 3854b81b0fd23adc9bab91bf68918d102dc31f51 URL: https://github.com/llvm/llvm-project/commit/3854b81b0fd23adc9bab91bf68918d102dc31f51 DIFF: https://github.com/llvm/llvm-project/commit/3854b81b0fd23adc9bab91bf68918d102dc31f51.diff LOG: [Clang][Driver] Fix read-after-free when using /clang: Fixes PR42501. Differential Revision: https://reviews.llvm.org/D93772 Added: Modified: clang/lib/Driver/Driver.cpp clang/test/Driver/cl-options.c Removed: diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 5c3ce478053a..418e1d3e8ec9 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -1009,13 +1009,15 @@ Compilation *Driver::BuildCompilation(ArrayRef ArgList) { // objects than Args. This copies an Arg from one of those other InputArgLists // to the ownership of Args. auto appendOneArg = [&Args](const Arg *Opt, const Arg *BaseArg) { - unsigned Index = Args.MakeIndex(Opt->getSpelling()); - Arg *Copy = new llvm::opt::Arg(Opt->getOption(), Opt->getSpelling(), - Index, BaseArg); - Copy->getValues() = Opt->getValues(); - if (Opt->isClaimed()) -Copy->claim(); - Args.append(Copy); +unsigned Index = Args.MakeIndex(Opt->getSpelling()); +Arg *Copy = new llvm::opt::Arg(Opt->getOption(), Args.getArgString(Index), + Index, BaseArg); +Copy->getValues() = Opt->getValues(); +if (Opt->isClaimed()) + Copy->claim(); +Copy->setOwnsValues(Opt->getOwnsValues()); +Opt->setOwnsValues(false); +Args.append(Copy); }; if (HasConfigFile) diff --git a/clang/test/Driver/cl-options.c b/clang/test/Driver/cl-options.c index db70fca5222c..4b6d71ed7b6d 100644 --- a/clang/test/Driver/cl-options.c +++ b/clang/test/Driver/cl-options.c @@ -686,6 +686,11 @@ // CLANG-NOT: "--dependent-lib=libcmt" // CLANG-NOT: "-vectorize-slp" +// Cover PR42501: clang-cl /clang: pass-through causes read-after-free with aliased options. +// RUN: %clang_cl /clang:-save-temps /clang:-Wl,test1,test2 -### -- %s 2>&1 | FileCheck -check-prefix=SAVETEMPS %s +// SAVETEMPS: "-save-temps=cwd" +// SAVETEMPS: "test1" "test2" + // Validate that the default triple is used when run an empty tools dir is specified // RUN: %clang_cl -vctoolsdir "" -### -- %s 2>&1 | FileCheck %s --check-prefix VCTOOLSDIR // VCTOOLSDIR: "-triple" "{{[a-zA-Z0-9_-]*}}-pc-windows-msvc19.11.0" ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] ce7f30b - [llvm-pdbutil] Don't crash when printing unknown CodeView type records
Author: Alexandre Ganea Date: 2021-01-07T15:44:55-05:00 New Revision: ce7f30b2a874386a0ce089c98327acb65e87b04d URL: https://github.com/llvm/llvm-project/commit/ce7f30b2a874386a0ce089c98327acb65e87b04d DIFF: https://github.com/llvm/llvm-project/commit/ce7f30b2a874386a0ce089c98327acb65e87b04d.diff LOG: [llvm-pdbutil] Don't crash when printing unknown CodeView type records Differential Revision: https://reviews.llvm.org/D93720 Added: llvm/test/tools/llvm-pdbutil/Inputs/unknown-record.obj llvm/test/tools/llvm-pdbutil/unknown-records.test Modified: llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp llvm/tools/llvm-pdbutil/FormatUtil.cpp llvm/tools/llvm-pdbutil/FormatUtil.h Removed: diff --git a/llvm/test/tools/llvm-pdbutil/Inputs/unknown-record.obj b/llvm/test/tools/llvm-pdbutil/Inputs/unknown-record.obj new file mode 100644 index ..0be00ffdd922 Binary files /dev/null and b/llvm/test/tools/llvm-pdbutil/Inputs/unknown-record.obj diff er diff --git a/llvm/test/tools/llvm-pdbutil/unknown-records.test b/llvm/test/tools/llvm-pdbutil/unknown-records.test new file mode 100644 index ..9773b85a0cd7 --- /dev/null +++ b/llvm/test/tools/llvm-pdbutil/unknown-records.test @@ -0,0 +1,3 @@ +; REQUIRES: diasdk +; RUN: llvm-pdbutil dump -all %p/Inputs/unknown-record.obj | FileCheck %s +; CHECK: UNKNOWN RECORD (0x1609) diff --git a/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp b/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp index aa185e8a2f22..3d8a86f34922 100644 --- a/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp +++ b/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp @@ -738,21 +738,17 @@ namespace { constexpr uint32_t kNoneUdtKind = 0; constexpr uint32_t kSimpleUdtKind = 1; constexpr uint32_t kUnknownUdtKind = 2; -const StringRef NoneLabel(""); -const StringRef SimpleLabel(""); -const StringRef UnknownLabel(""); - } // namespace -static StringRef getUdtStatLabel(uint32_t Kind) { +static std::string getUdtStatLabel(uint32_t Kind) { if (Kind == kNoneUdtKind) -return NoneLabel; +return ""; if (Kind == kSimpleUdtKind) -return SimpleLabel; +return ""; if (Kind == kUnknownUdtKind) -return UnknownLabel; +return ""; return formatTypeLeafKind(static_cast(Kind)); } @@ -760,7 +756,7 @@ static StringRef getUdtStatLabel(uint32_t Kind) { static uint32_t getLongestTypeLeafName(const StatCollection &Stats) { size_t L = 0; for (const auto &Stat : Stats.Individual) { -StringRef Label = getUdtStatLabel(Stat.first); +std::string Label = getUdtStatLabel(Stat.first); L = std::max(L, Label.size()); } return static_cast(L); @@ -869,7 +865,7 @@ Error DumpOutputStyle::dumpUdtStats() { P.formatLine("{0}", fmt_repeat('-', TableWidth)); for (const auto &Stat : UdtTargetStats.getStatsSortedBySize()) { -StringRef Label = getUdtStatLabel(Stat.first); +std::string Label = getUdtStatLabel(Stat.first); P.formatLine("{0} | {1:N} {2:N}", fmt_align(Label, AlignStyle::Right, FieldWidth), fmt_align(Stat.second.Count, AlignStyle::Right, CD), diff --git a/llvm/tools/llvm-pdbutil/FormatUtil.cpp b/llvm/tools/llvm-pdbutil/FormatUtil.cpp index c9ef19609496..b4837398f1d0 100644 --- a/llvm/tools/llvm-pdbutil/FormatUtil.cpp +++ b/llvm/tools/llvm-pdbutil/FormatUtil.cpp @@ -156,16 +156,17 @@ std::string llvm::pdb::formatSymbolKind(SymbolKind K) { return formatUnknownEnum(K); } -StringRef llvm::pdb::formatTypeLeafKind(TypeLeafKind K) { +std::string llvm::pdb::formatTypeLeafKind(TypeLeafKind K) { switch (K) { #define TYPE_RECORD(EnumName, value, name) \ case EnumName: \ return #EnumName; #include "llvm/DebugInfo/CodeView/CodeViewTypes.def" default: -llvm_unreachable("Unknown type leaf kind!"); +return formatv("UNKNOWN RECORD ({0:X})", + static_cast>(K)) +.str(); } - return ""; } std::string llvm::pdb::formatSegmentOffset(uint16_t Segment, uint32_t Offset) { diff --git a/llvm/tools/llvm-pdbutil/FormatUtil.h b/llvm/tools/llvm-pdbutil/FormatUtil.h index 133a0eb40e12..b99ccec215b5 100644 --- a/llvm/tools/llvm-pdbutil/FormatUtil.h +++ b/llvm/tools/llvm-pdbutil/FormatUtil.h @@ -66,7 +66,7 @@ std::string typesetStringList(uint32_t IndentLevel, std::string formatChunkKind(codeview::DebugSubsectionKind Kind, bool Friendly = true); std::string formatSymbolKind(codeview::SymbolKind K); -StringRef formatTypeLeafKind(codeview::TypeLeafKind K); +std::string formatTypeLeafKind(codeview::TypeLeafKind K); /// Returns the number of digits in the given integer. inline int NumDigits(uint64_t N) { ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists
[llvm-branch-commits] [lld] eaadb41 - [LLD][COFF] When using PCH.OBJ, ensure func_id records indices are remapped under /DEBUG:GHASH
Author: Alexandre Ganea Date: 2021-01-07T17:27:13-05:00 New Revision: eaadb41db6233cf1c9e882d74a31c1f9d6e211ff URL: https://github.com/llvm/llvm-project/commit/eaadb41db6233cf1c9e882d74a31c1f9d6e211ff DIFF: https://github.com/llvm/llvm-project/commit/eaadb41db6233cf1c9e882d74a31c1f9d6e211ff.diff LOG: [LLD][COFF] When using PCH.OBJ, ensure func_id records indices are remapped under /DEBUG:GHASH Before this patch, when using LLD with /DEBUG:GHASH and MSVC precomp.OBJ files, we had a bunch of: lld-link: warning: S_[GL]PROC32ID record in blabla.obj refers to PDB item index 0x206ED1 which is not a LF[M]FUNC_ID record This was caused by LF_FUNC_ID and LF_MFUNC_ID which didn't have correct mapping to the corresponding TPI records. The root issue was that the indexMapStorage was improperly re-assembled in UsePrecompSource::remapTpiWithGHashes. After this patch, /DEBUG and /DEBUG:GHASH produce exactly the same debug infos in the PDB. Differential Revision: https://reviews.llvm.org/D93732 Added: lld/test/COFF/Inputs/precomp-ghash-obj1.obj lld/test/COFF/Inputs/precomp-ghash-obj2.obj lld/test/COFF/Inputs/precomp-ghash-precomp.obj lld/test/COFF/precomp-ghash.test Modified: lld/COFF/DebugTypes.cpp Removed: diff --git a/lld/COFF/DebugTypes.cpp b/lld/COFF/DebugTypes.cpp index 0c8bfd8ae5b8..d3996eabca7d 100644 --- a/lld/COFF/DebugTypes.cpp +++ b/lld/COFF/DebugTypes.cpp @@ -532,7 +532,7 @@ Error UsePrecompSource::mergeInPrecompHeaderObj() { TypeIndex::FirstNonSimpleIndex); assert(precompDependency.getTypesCount() <= precompSrc->tpiMap.size()); // Use the previously remapped index map from the precompiled headers. - indexMapStorage.append(precompSrc->tpiMap.begin(), + indexMapStorage.insert(indexMapStorage.begin(), precompSrc->tpiMap.begin(), precompSrc->tpiMap.begin() + precompDependency.getTypesCount()); @@ -842,6 +842,7 @@ void UsePrecompSource::loadGHashes() { } void UsePrecompSource::remapTpiWithGHashes(GHashState *g) { + fillMapFromGHashes(g, indexMapStorage); // This object was compiled with /Yu, so process the corresponding // precompiled headers object (/Yc) first. Some type indices in the current // object are referencing data in the precompiled headers object, so we need @@ -851,7 +852,6 @@ void UsePrecompSource::remapTpiWithGHashes(GHashState *g) { return; } - fillMapFromGHashes(g, indexMapStorage); tpiMap = indexMapStorage; ipiMap = indexMapStorage; mergeUniqueTypeRecords(file->debugTypes, diff --git a/lld/test/COFF/Inputs/precomp-ghash-obj1.obj b/lld/test/COFF/Inputs/precomp-ghash-obj1.obj new file mode 100644 index ..078593e05f66 Binary files /dev/null and b/lld/test/COFF/Inputs/precomp-ghash-obj1.obj diff er diff --git a/lld/test/COFF/Inputs/precomp-ghash-obj2.obj b/lld/test/COFF/Inputs/precomp-ghash-obj2.obj new file mode 100644 index ..f9cff3b9dfad Binary files /dev/null and b/lld/test/COFF/Inputs/precomp-ghash-obj2.obj diff er diff --git a/lld/test/COFF/Inputs/precomp-ghash-precomp.obj b/lld/test/COFF/Inputs/precomp-ghash-precomp.obj new file mode 100644 index ..b28ff77f19aa Binary files /dev/null and b/lld/test/COFF/Inputs/precomp-ghash-precomp.obj diff er diff --git a/lld/test/COFF/precomp-ghash.test b/lld/test/COFF/precomp-ghash.test new file mode 100644 index ..e9d1984ac40d --- /dev/null +++ b/lld/test/COFF/precomp-ghash.test @@ -0,0 +1,53 @@ + +# This test ensures that under /DEBUG:GHASH, IPI records LF_FUNC_ID/LF_MFUNC_ID +# have properly remapped indices to corresponding TPI records. + +RUN: lld-link %p/Inputs/precomp-ghash-precomp.obj \ +RUN:%p/Inputs/precomp-ghash-obj1.obj\ +RUN:%p/Inputs/precomp-ghash-obj2.obj /debug:ghash /out:%t.exe /pdb:%t.pdb +RUN: llvm-pdbutil dump -types -ids %t.pdb | FileCheck %s + +; These object files were generated via the following inputs and commands: +; -- +; // precomp-ghash-obj.h +; namespace NS { +; struct Foo { +; explicit Foo(int x) : X(x) {} +; int X; +; }; +; +; int func(const Foo &f); +; } +; -- +; // precomp-ghash-obj1.cpp +; #include "precomp-ghash-obj.h" +; +; int main(int argc, char **argv) { +; NS::Foo f(argc); +; return NS::func(f); +; } +; -- +; // precomp-ghash-obj2.cpp +; #include "precomp-ghash-obj.h" +; +; int NS::func(const Foo &f) { +; return 2 * f.X; +; } +; -- +; // precomp-ghash-precomp.cpp +; #include "precomp-ghash-obj.h" +; -- +; $ cl /c /Z7 /GS- precomp-ghash-precomp.cpp /Ycprecomp-ghash-obj.h +; $ cl /c /Z7 /GS- precomp-ghash-obj1.cpp /Yuprecomp-ghash-obj.h +; $ cl /c /Z7 /GS- precomp-ghash-obj2.c
[llvm-branch-commits] [lld] 6acfc3a - Fix build after eaadb41db6233cf1c9e882d74a31c1f9d6e211ff when the MSVC libs are not in PATH.
Author: Alexandre Ganea Date: 2021-01-07T18:52:00-05:00 New Revision: 6acfc3a78210639367ab8345a9af04e97692a661 URL: https://github.com/llvm/llvm-project/commit/6acfc3a78210639367ab8345a9af04e97692a661 DIFF: https://github.com/llvm/llvm-project/commit/6acfc3a78210639367ab8345a9af04e97692a661.diff LOG: Fix build after eaadb41db6233cf1c9e882d74a31c1f9d6e211ff when the MSVC libs are not in PATH. Added: Modified: lld/test/COFF/precomp-ghash.test Removed: diff --git a/lld/test/COFF/precomp-ghash.test b/lld/test/COFF/precomp-ghash.test index e9d1984ac40d..6dcd8a35002e 100644 --- a/lld/test/COFF/precomp-ghash.test +++ b/lld/test/COFF/precomp-ghash.test @@ -4,7 +4,7 @@ RUN: lld-link %p/Inputs/precomp-ghash-precomp.obj \ RUN:%p/Inputs/precomp-ghash-obj1.obj\ -RUN:%p/Inputs/precomp-ghash-obj2.obj /debug:ghash /out:%t.exe /pdb:%t.pdb +RUN:%p/Inputs/precomp-ghash-obj2.obj /debug:ghash /out:%t.exe /pdb:%t.pdb /nodefaultlib /force RUN: llvm-pdbutil dump -types -ids %t.pdb | FileCheck %s ; These object files were generated via the following inputs and commands: @@ -44,10 +44,10 @@ RUN: llvm-pdbutil dump -types -ids %t.pdb | FileCheck %s CHECK: Types (TPI Stream) CHECK-NEXT: CHECK: 0x1003 | LF_MFUNCTION -CHECK: 0x274F | LF_PROCEDURE +CHECK: 0x1377 | LF_PROCEDURE CHECK: Types (IPI Stream) CHECK-NEXT: -CHECK: 0x189D | LF_FUNC_ID [size = 20] -CHECK-NEXT: name = main, type = 0x274F, parent scope = -CHECK-NEXT: 0x189E | LF_MFUNC_ID [size = 20] +CHECK: 0x10A5 | LF_FUNC_ID [size = 20] +CHECK-NEXT: name = main, type = 0x1377, parent scope = +CHECK-NEXT: 0x10A6 | LF_MFUNC_ID [size = 20] CHECK-NEXT: name = {ctor}, type = 0x1003, class type = 0x1000 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [lld] b14ad90 - [LLD][COFF] Simplify function. NFC.
Author: Alexandre Ganea Date: 2021-01-07T22:37:11-05:00 New Revision: b14ad90b137980125170b64fdf6be270811e5fc7 URL: https://github.com/llvm/llvm-project/commit/b14ad90b137980125170b64fdf6be270811e5fc7 DIFF: https://github.com/llvm/llvm-project/commit/b14ad90b137980125170b64fdf6be270811e5fc7.diff LOG: [LLD][COFF] Simplify function. NFC. Added: Modified: lld/COFF/DebugTypes.cpp lld/COFF/DebugTypes.h Removed: diff --git a/lld/COFF/DebugTypes.cpp b/lld/COFF/DebugTypes.cpp index d3996eabca7d..52c24aaf214f 100644 --- a/lld/COFF/DebugTypes.cpp +++ b/lld/COFF/DebugTypes.cpp @@ -696,7 +696,7 @@ void TpiSource::mergeUniqueTypeRecords(ArrayRef typeRecords, void TpiSource::remapTpiWithGHashes(GHashState *g) { assert(config->debugGHashes && "ghashes must be enabled"); - fillMapFromGHashes(g, indexMapStorage); + fillMapFromGHashes(g); tpiMap = indexMapStorage; ipiMap = indexMapStorage; mergeUniqueTypeRecords(file->debugTypes); @@ -761,13 +761,13 @@ void TypeServerSource::remapTpiWithGHashes(GHashState *g) { // propagate errors, those should've been handled during ghash loading. pdb::PDBFile &pdbFile = pdbInputFile->session->getPDBFile(); pdb::TpiStream &tpi = check(pdbFile.getPDBTpiStream()); - fillMapFromGHashes(g, indexMapStorage); + fillMapFromGHashes(g); tpiMap = indexMapStorage; mergeUniqueTypeRecords(typeArrayToBytes(tpi.typeArray())); if (pdbFile.hasPDBIpiStream()) { pdb::TpiStream &ipi = check(pdbFile.getPDBIpiStream()); ipiSrc->indexMapStorage.resize(ipiSrc->ghashes.size()); -ipiSrc->fillMapFromGHashes(g, ipiSrc->indexMapStorage); +ipiSrc->fillMapFromGHashes(g); ipiMap = ipiSrc->indexMapStorage; ipiSrc->tpiMap = tpiMap; ipiSrc->ipiMap = ipiMap; @@ -842,7 +842,7 @@ void UsePrecompSource::loadGHashes() { } void UsePrecompSource::remapTpiWithGHashes(GHashState *g) { - fillMapFromGHashes(g, indexMapStorage); + fillMapFromGHashes(g); // This object was compiled with /Yu, so process the corresponding // precompiled headers object (/Yc) first. Some type indices in the current // object are referencing data in the precompiled headers object, so we need @@ -1149,14 +1149,14 @@ static TypeIndex loadPdbTypeIndexFromCell(GHashState *g, // Fill in a TPI or IPI index map using ghashes. For each source type, use its // ghash to lookup its final type index in the PDB, and store that in the map. -void TpiSource::fillMapFromGHashes(GHashState *g, - SmallVectorImpl &mapToFill) { +void TpiSource::fillMapFromGHashes(GHashState *g) { for (size_t i = 0, e = ghashes.size(); i < e; ++i) { TypeIndex fakeCellIndex = indexMapStorage[i]; if (fakeCellIndex.isSimple()) - mapToFill[i] = fakeCellIndex; + indexMapStorage[i] = fakeCellIndex; else - mapToFill[i] = loadPdbTypeIndexFromCell(g, fakeCellIndex.toArrayIndex()); + indexMapStorage[i] = + loadPdbTypeIndexFromCell(g, fakeCellIndex.toArrayIndex()); } } diff --git a/lld/COFF/DebugTypes.h b/lld/COFF/DebugTypes.h index 42485df06f87..faad30b141e9 100644 --- a/lld/COFF/DebugTypes.h +++ b/lld/COFF/DebugTypes.h @@ -83,8 +83,7 @@ class TpiSource { // Use the ghash table to construct a map from source type index to // destination PDB type index. Usable for either TPI or IPI. - void fillMapFromGHashes(GHashState *m, - llvm::SmallVectorImpl &indexMap); + void fillMapFromGHashes(GHashState *m); // Copies ghashes from a vector into an array. These are long lived, so it's // worth the time to copy these into an appropriately sized vector to reduce ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] 69132d1 - [Clang] Reverse test to save on indentation. NFC.
Author: Alexandre Ganea Date: 2020-12-23T19:24:53-05:00 New Revision: 69132d12deae749a8e4c9def5498ffa354ce1fa6 URL: https://github.com/llvm/llvm-project/commit/69132d12deae749a8e4c9def5498ffa354ce1fa6 DIFF: https://github.com/llvm/llvm-project/commit/69132d12deae749a8e4c9def5498ffa354ce1fa6.diff LOG: [Clang] Reverse test to save on indentation. NFC. Added: Modified: clang/lib/CodeGen/CodeGenAction.cpp Removed: diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp index 5b23b6d2b7f5..778d4df3c2e9 100644 --- a/clang/lib/CodeGen/CodeGenAction.cpp +++ b/clang/lib/CodeGen/CodeGenAction.cpp @@ -1078,78 +1078,74 @@ CodeGenAction::loadModule(MemoryBufferRef MBRef) { } void CodeGenAction::ExecuteAction() { - // If this is an IR file, we have to treat it specially. - if (getCurrentFileKind().getLanguage() == Language::LLVM_IR) { -BackendAction BA = static_cast(Act); -CompilerInstance &CI = getCompilerInstance(); -auto &CodeGenOpts = CI.getCodeGenOpts(); -auto &Diagnostics = CI.getDiagnostics(); -std::unique_ptr OS = -GetOutputStream(CI, getCurrentFile(), BA); -if (BA != Backend_EmitNothing && !OS) - return; - -SourceManager &SM = CI.getSourceManager(); -FileID FID = SM.getMainFileID(); -Optional MainFile = SM.getBufferOrNone(FID); -if (!MainFile) - return; + if (getCurrentFileKind().getLanguage() != Language::LLVM_IR) { +this->ASTFrontendAction::ExecuteAction(); +return; + } -TheModule = loadModule(*MainFile); -if (!TheModule) - return; + // If this is an IR file, we have to treat it specially. + BackendAction BA = static_cast(Act); + CompilerInstance &CI = getCompilerInstance(); + auto &CodeGenOpts = CI.getCodeGenOpts(); + auto &Diagnostics = CI.getDiagnostics(); + std::unique_ptr OS = + GetOutputStream(CI, getCurrentFile(), BA); + if (BA != Backend_EmitNothing && !OS) +return; -const TargetOptions &TargetOpts = CI.getTargetOpts(); -if (TheModule->getTargetTriple() != TargetOpts.Triple) { - Diagnostics.Report(SourceLocation(), - diag::warn_fe_override_module) - << TargetOpts.Triple; - TheModule->setTargetTriple(TargetOpts.Triple); -} + SourceManager &SM = CI.getSourceManager(); + FileID FID = SM.getMainFileID(); + Optional MainFile = SM.getBufferOrNone(FID); + if (!MainFile) +return; -EmbedBitcode(TheModule.get(), CodeGenOpts, *MainFile); - -LLVMContext &Ctx = TheModule->getContext(); -Ctx.setInlineAsmDiagnosticHandler(BitcodeInlineAsmDiagHandler, - &Diagnostics); - -// Set clang diagnostic handler. To do this we need to create a fake -// BackendConsumer. -BackendConsumer Result(BA, CI.getDiagnostics(), CI.getHeaderSearchOpts(), - CI.getPreprocessorOpts(), CI.getCodeGenOpts(), - CI.getTargetOpts(), CI.getLangOpts(), - std::move(LinkModules), *VMContext, nullptr); -// PR44896: Force DiscardValueNames as false. DiscardValueNames cannot be -// true here because the valued names are needed for reading textual IR. -Ctx.setDiscardValueNames(false); -Ctx.setDiagnosticHandler( -std::make_unique(CodeGenOpts, &Result)); - -Expected> OptRecordFileOrErr = -setupLLVMOptimizationRemarks( -Ctx, CodeGenOpts.OptRecordFile, CodeGenOpts.OptRecordPasses, -CodeGenOpts.OptRecordFormat, CodeGenOpts.DiagnosticsWithHotness, -CodeGenOpts.DiagnosticsHotnessThreshold); - -if (Error E = OptRecordFileOrErr.takeError()) { - reportOptRecordError(std::move(E), Diagnostics, CodeGenOpts); - return; -} -std::unique_ptr OptRecordFile = -std::move(*OptRecordFileOrErr); + TheModule = loadModule(*MainFile); + if (!TheModule) +return; -EmitBackendOutput(Diagnostics, CI.getHeaderSearchOpts(), CodeGenOpts, - TargetOpts, CI.getLangOpts(), - CI.getTarget().getDataLayout(), TheModule.get(), BA, - std::move(OS)); + const TargetOptions &TargetOpts = CI.getTargetOpts(); + if (TheModule->getTargetTriple() != TargetOpts.Triple) { +Diagnostics.Report(SourceLocation(), diag::warn_fe_override_module) +<< TargetOpts.Triple; +TheModule->setTargetTriple(TargetOpts.Triple); + } -if (OptRecordFile) - OptRecordFile->keep(); + EmbedBitcode(TheModule.get(), CodeGenOpts, *MainFile); + + LLVMContext &Ctx = TheModule->getContext(); + Ctx.setInlineAsmDiagnosticHandler(BitcodeInlineAsmDiagHandler, &Diagnostics); + + // Set clang diagnostic handler. To do this we need to create a fake + // BackendConsumer. + BackendConsumer Result(BA, CI.getDiagnostics(), CI.getHeaderSearchOpts(), + CI.getPreprocessorOpt
[llvm-branch-commits] [llvm] 0f1f13f - Re-land: [lit] Support running tests on Windows without GnuWin32
Author: Alexandre Ganea Date: 2020-12-10T21:41:54-05:00 New Revision: 0f1f13fcb17fbc8c93d505da989a04ab5cbd9ed3 URL: https://github.com/llvm/llvm-project/commit/0f1f13fcb17fbc8c93d505da989a04ab5cbd9ed3 DIFF: https://github.com/llvm/llvm-project/commit/0f1f13fcb17fbc8c93d505da989a04ab5cbd9ed3.diff LOG: Re-land: [lit] Support running tests on Windows without GnuWin32 Historically, we have told contributors that GnuWin32 is a pre-requisite because our tests depend on utilities such as sed, grep, diff, and more. However, Git on Windows includes versions of these utilities in its installation. Furthermore, GnuWin32 has not been updated in many years. For these reasons, it makes sense to have the ability to run llvm tests in a way that is both: a) Easier on the user (less stuff to install) b) More up-to-date (The verions that ship with git are at least as new, if not newer, than the versions in GnuWin32. We add support for this here by attempting to detect where Git is installed using the Windows registry, confirming the existence of several common Unix tools, and then adding this location to lit's PATH environment. Differential Revision: https://reviews.llvm.org/D84380 Added: Modified: llvm/utils/lit/lit/llvm/config.py Removed: diff --git a/llvm/utils/lit/lit/llvm/config.py b/llvm/utils/lit/lit/llvm/config.py index 498e34cae3a5..949c5e694db7 100644 --- a/llvm/utils/lit/lit/llvm/config.py +++ b/llvm/utils/lit/lit/llvm/config.py @@ -1,3 +1,4 @@ +import itertools import os import platform import re @@ -8,6 +9,7 @@ from lit.llvm.subst import FindTool from lit.llvm.subst import ToolSubst +lit_path_displayed = False class LLVMConfig(object): @@ -20,19 +22,26 @@ def __init__(self, lit_config, config): self.use_lit_shell = False # Tweak PATH for Win32 to decide to use bash.exe or not. if sys.platform == 'win32': -# For tests that require Windows to run. -features.add('system-windows') - -# Seek sane tools in directories and set to $PATH. -path = self.lit_config.getToolsPath(config.lit_tools_dir, +# Seek necessary tools in directories and set to $PATH. +path = None +lit_tools_dir = getattr(config, 'lit_tools_dir', None) +required_tools = ['cmp.exe', 'grep.exe', 'sed.exe', ' diff .exe', 'echo.exe'] +path = self.lit_config.getToolsPath(lit_tools_dir, config.environment['PATH'], -['cmp.exe', 'grep.exe', 'sed.exe']) +required_tools) +if path is None: +path = self._find_git_windows_unix_tools(required_tools) if path is not None: self.with_environment('PATH', path, append_path=True) # Many tools behave strangely if these environment variables aren't set. self.with_system_environment(['SystemDrive', 'SystemRoot', 'TEMP', 'TMP']) self.use_lit_shell = True +global lit_path_displayed +if not self.lit_config.quiet and lit_path_displayed is False: +self.lit_config.note("using lit tools: {}".format(path)) +lit_path_displayed = True + # Choose between lit's internal shell pipeline runner and a real shell. If # LIT_USE_INTERNAL_SHELL is in the environment, we use that as an override. lit_shell_env = os.environ.get('LIT_USE_INTERNAL_SHELL') @@ -117,6 +126,35 @@ def __init__(self, lit_config, config): self.with_environment( 'DYLD_INSERT_LIBRARIES', gmalloc_path_str) +def _find_git_windows_unix_tools(self, tools_needed): +assert(sys.platform == 'win32') +if sys.version_info.major >= 3: +import winreg +else: +import _winreg as winreg + +# Search both the 64 and 32-bit hives, as well as HKLM + HKCU +masks = [0, winreg.KEY_WOW64_64KEY] +hives = [winreg.HKEY_LOCAL_MACHINE, winreg.HKEY_CURRENT_USER] +for mask, hive in itertools.product(masks, hives): +try: +with winreg.OpenKey(hive, r"SOFTWARE\GitForWindows", 0, +winreg.KEY_READ | mask) as key: +install_root, _ = winreg.QueryValueEx(key, 'InstallPath') + +if not install_root: +continue +candidate_path = os.path.join(install_root, 'usr', 'bin') +if not lit.util.checkToolsPath(candidate_path, tools_needed): +continue + +# We found it, stop enumerating. +return lit.util.to_string(candidate_path) +except: +continue + +return No
[llvm-branch-commits] [lld] [LLD][COFF] Don't dllimport from static libraries (#134443) (PR #138354)
https://github.com/aganea updated https://github.com/llvm/llvm-project/pull/138354 >From 902cc177fe89f13ce41f76372157d96b304d585f Mon Sep 17 00:00:00 2001 From: Alexandre Ganea Date: Mon, 7 Apr 2025 11:34:24 -0400 Subject: [PATCH 1/2] [LLD][COFF] Don't dllimport from static libraries (#134443) This reverts commit 6a1bdd9 and re-instate behavior that matches what MSVC link.exe does, that is, error out when trying to dllimport a symbol from a static library. A hint is now displayed in stdout, mentioning that we should rather dllimport the symbol from a import library. Fixes https://github.com/llvm/llvm-project/issues/131807 --- lld/COFF/Driver.cpp | 6 ++-- lld/COFF/SymbolTable.cpp | 20 ++- lld/COFF/SymbolTable.h| 5 +-- .../COFF/imports-static-lib-indirect.test | 26 +++ lld/test/COFF/imports-static-lib.test | 33 +++ lld/test/COFF/undefined_lazy.test | 26 --- 6 files changed, 74 insertions(+), 42 deletions(-) create mode 100644 lld/test/COFF/imports-static-lib-indirect.test create mode 100644 lld/test/COFF/imports-static-lib.test delete mode 100644 lld/test/COFF/undefined_lazy.test diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index ac3ac57bd17f4..f50ca529df4d7 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -2639,10 +2639,8 @@ void LinkerDriver::linkerMain(ArrayRef argsArr) { createECExportThunks(); // Resolve remaining undefined symbols and warn about imported locals. - ctx.forEachSymtab([&](SymbolTable &symtab) { -while (symtab.resolveRemainingUndefines()) - run(); - }); + ctx.forEachSymtab( + [&](SymbolTable &symtab) { symtab.resolveRemainingUndefines(); }); if (errorCount()) return; diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp index 307bd4a0c9411..8448d47d505f6 100644 --- a/lld/COFF/SymbolTable.cpp +++ b/lld/COFF/SymbolTable.cpp @@ -232,6 +232,17 @@ static void reportUndefinedSymbol(COFFLinkerContext &ctx, } if (numDisplayedRefs < numRefs) diag << "\n>>> referenced " << numRefs - numDisplayedRefs << " more times"; + + // Hints + StringRef name = undefDiag.sym->getName(); + if (name.consume_front("__imp_")) { +Symbol *imp = find(name); +if (imp && imp->isLazy()) { + diag << "\nNOTE: a relevant symbol '" << imp->getName() + << "' is available in " << toString(imp->getFile()) + << " but cannot be used because it is not an import library."; +} + } } void SymbolTable::loadMinGWSymbols() { @@ -432,11 +443,10 @@ void SymbolTable::reportUnresolvable() { reportProblemSymbols(undefs, /*localImports=*/nullptr, true); } -bool SymbolTable::resolveRemainingUndefines() { +void SymbolTable::resolveRemainingUndefines() { llvm::TimeTraceScope timeScope("Resolve remaining undefined symbols"); SmallPtrSet undefs; DenseMap localImports; - bool foundLazy = false; for (auto &i : symMap) { Symbol *sym = i.second; @@ -481,11 +491,6 @@ bool SymbolTable::resolveRemainingUndefines() { imp = findLocalSym(*mangledName); } } - if (imp && imp->isLazy()) { -forceLazy(imp); -foundLazy = true; -continue; - } if (imp && isa(imp)) { auto *d = cast(imp); replaceSymbol(sym, ctx, name, d); @@ -513,7 +518,6 @@ bool SymbolTable::resolveRemainingUndefines() { reportProblemSymbols( undefs, ctx.config.warnLocallyDefinedImported ? &localImports : nullptr, false); - return foundLazy; } std::pair SymbolTable::insert(StringRef name) { diff --git a/lld/COFF/SymbolTable.h b/lld/COFF/SymbolTable.h index ff6e8487f0734..2916c23d95c87 100644 --- a/lld/COFF/SymbolTable.h +++ b/lld/COFF/SymbolTable.h @@ -58,10 +58,7 @@ class SymbolTable { // Try to resolve any undefined symbols and update the symbol table // accordingly, then print an error message for any remaining undefined // symbols and warn about imported local symbols. - // Returns whether more files might need to be linked in to resolve lazy - // symbols, in which case the caller is expected to call the function again - // after linking those files. - bool resolveRemainingUndefines(); + void resolveRemainingUndefines(); // Load lazy objects that are needed for MinGW automatic import and for // doing stdcall fixups. diff --git a/lld/test/COFF/imports-static-lib-indirect.test b/lld/test/COFF/imports-static-lib-indirect.test new file mode 100644 index 0..beda0d7a31afd --- /dev/null +++ b/lld/test/COFF/imports-static-lib-indirect.test @@ -0,0 +1,26 @@ +# REQUIRES: x86 + +# Pulling in on both a dllimport symbol and a static symbol should only warn. +# RUN: split-file %s %t.dir +# RUN: llvm-mc --filetype=obj -triple=x86_64-windows-msvc %t.dir/other.s -o %t.other.obj +# RUN: llvm-mc --filetype=obj -triple=x86_64-windows-msvc %t.dir/main.s -o %t.
[llvm-branch-commits] [lld] [LLD][COFF] Don't dllimport from static libraries (#134443) (PR #138354)
https://github.com/aganea milestoned https://github.com/llvm/llvm-project/pull/138354 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [lld] [LLD][COFF] Don't dllimport from static libraries (#134443) (PR #138354)
https://github.com/aganea created https://github.com/llvm/llvm-project/pull/138354 Backport https://github.com/llvm/llvm-project/pull/134443 on release/20.x: > This reverts commit 6a1bdd9 and re-instate behavior that matches what MSVC > link.exe does, that is, error out when trying to dllimport a symbol from a > static library. > > A hint is now displayed in stdout, mentioning that we should rather dllimport > the symbol from a import library. > > Fixes https://github.com/llvm/llvm-project/issues/131807 >From 902cc177fe89f13ce41f76372157d96b304d585f Mon Sep 17 00:00:00 2001 From: Alexandre Ganea Date: Mon, 7 Apr 2025 11:34:24 -0400 Subject: [PATCH] [LLD][COFF] Don't dllimport from static libraries (#134443) This reverts commit 6a1bdd9 and re-instate behavior that matches what MSVC link.exe does, that is, error out when trying to dllimport a symbol from a static library. A hint is now displayed in stdout, mentioning that we should rather dllimport the symbol from a import library. Fixes https://github.com/llvm/llvm-project/issues/131807 --- lld/COFF/Driver.cpp | 6 ++-- lld/COFF/SymbolTable.cpp | 20 ++- lld/COFF/SymbolTable.h| 5 +-- .../COFF/imports-static-lib-indirect.test | 26 +++ lld/test/COFF/imports-static-lib.test | 33 +++ lld/test/COFF/undefined_lazy.test | 26 --- 6 files changed, 74 insertions(+), 42 deletions(-) create mode 100644 lld/test/COFF/imports-static-lib-indirect.test create mode 100644 lld/test/COFF/imports-static-lib.test delete mode 100644 lld/test/COFF/undefined_lazy.test diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index ac3ac57bd17f4..f50ca529df4d7 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -2639,10 +2639,8 @@ void LinkerDriver::linkerMain(ArrayRef argsArr) { createECExportThunks(); // Resolve remaining undefined symbols and warn about imported locals. - ctx.forEachSymtab([&](SymbolTable &symtab) { -while (symtab.resolveRemainingUndefines()) - run(); - }); + ctx.forEachSymtab( + [&](SymbolTable &symtab) { symtab.resolveRemainingUndefines(); }); if (errorCount()) return; diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp index 307bd4a0c9411..8448d47d505f6 100644 --- a/lld/COFF/SymbolTable.cpp +++ b/lld/COFF/SymbolTable.cpp @@ -232,6 +232,17 @@ static void reportUndefinedSymbol(COFFLinkerContext &ctx, } if (numDisplayedRefs < numRefs) diag << "\n>>> referenced " << numRefs - numDisplayedRefs << " more times"; + + // Hints + StringRef name = undefDiag.sym->getName(); + if (name.consume_front("__imp_")) { +Symbol *imp = find(name); +if (imp && imp->isLazy()) { + diag << "\nNOTE: a relevant symbol '" << imp->getName() + << "' is available in " << toString(imp->getFile()) + << " but cannot be used because it is not an import library."; +} + } } void SymbolTable::loadMinGWSymbols() { @@ -432,11 +443,10 @@ void SymbolTable::reportUnresolvable() { reportProblemSymbols(undefs, /*localImports=*/nullptr, true); } -bool SymbolTable::resolveRemainingUndefines() { +void SymbolTable::resolveRemainingUndefines() { llvm::TimeTraceScope timeScope("Resolve remaining undefined symbols"); SmallPtrSet undefs; DenseMap localImports; - bool foundLazy = false; for (auto &i : symMap) { Symbol *sym = i.second; @@ -481,11 +491,6 @@ bool SymbolTable::resolveRemainingUndefines() { imp = findLocalSym(*mangledName); } } - if (imp && imp->isLazy()) { -forceLazy(imp); -foundLazy = true; -continue; - } if (imp && isa(imp)) { auto *d = cast(imp); replaceSymbol(sym, ctx, name, d); @@ -513,7 +518,6 @@ bool SymbolTable::resolveRemainingUndefines() { reportProblemSymbols( undefs, ctx.config.warnLocallyDefinedImported ? &localImports : nullptr, false); - return foundLazy; } std::pair SymbolTable::insert(StringRef name) { diff --git a/lld/COFF/SymbolTable.h b/lld/COFF/SymbolTable.h index ff6e8487f0734..2916c23d95c87 100644 --- a/lld/COFF/SymbolTable.h +++ b/lld/COFF/SymbolTable.h @@ -58,10 +58,7 @@ class SymbolTable { // Try to resolve any undefined symbols and update the symbol table // accordingly, then print an error message for any remaining undefined // symbols and warn about imported local symbols. - // Returns whether more files might need to be linked in to resolve lazy - // symbols, in which case the caller is expected to call the function again - // after linking those files. - bool resolveRemainingUndefines(); + void resolveRemainingUndefines(); // Load lazy objects that are needed for MinGW automatic import and for // doing stdcall fixups. diff --git a/lld/test/COFF/imports-static-lib-indirect.test b/lld/test/COFF/imports-static-lib-indirect.test new file m
[llvm-branch-commits] [lld] release/20.x: Backport [LLD][COFF] Disallow importing DllMain from import libraries (#146610) (PR #146699)
aganea wrote: @rnk @mstorsjo is it ok if we integrate this into the release? @tstellar will there be a 20.1.8? https://github.com/llvm/llvm-project/pull/146699 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [lld] release/20.x: Backport [LLD][COFF] Disallow importing DllMain from import libraries (#146610) (PR #146699)
https://github.com/aganea updated https://github.com/llvm/llvm-project/pull/146699 >From cb11f22699cc5cf4761f7ef426721ef0496030f5 Mon Sep 17 00:00:00 2001 From: Alexandre Ganea Date: Wed, 2 Jul 2025 08:53:18 -0400 Subject: [PATCH 1/2] [LLD][COFF] Disallow importing DllMain from import libraries (#146610) This is a workaround for https://github.com/llvm/llvm-project/issues/82050 by skipping the `DllMain` symbol if seen in aimport library. If this situation occurs, after this commit a warning will also be displayed. The warning can be silenced with `/ignore:exporteddllmain` --- lld/COFF/Config.h | 1 + lld/COFF/Driver.cpp | 2 + lld/COFF/InputFiles.cpp | 40 +++- lld/test/COFF/exported-dllmain.test | 57 + 4 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 lld/test/COFF/exported-dllmain.test diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h index 0c7c4e91402f1..424e9578395b3 100644 --- a/lld/COFF/Config.h +++ b/lld/COFF/Config.h @@ -313,6 +313,7 @@ struct Configuration { bool warnDebugInfoUnusable = true; bool warnLongSectionNames = true; bool warnStdcallFixup = true; + bool warnExportedDllMain = true; bool incremental = true; bool integrityCheck = false; bool killAt = false; diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index a669b7e9296f6..8b2fc9f23178f 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -1625,6 +1625,8 @@ void LinkerDriver::linkerMain(ArrayRef argsArr) { config->warnLocallyDefinedImported = false; else if (s == "longsections") config->warnLongSectionNames = false; + else if (s == "exporteddllmain") +config->warnExportedDllMain = false; // Other warning numbers are ignored. } } diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp index 7b105fb4c17a2..b470b2a8d9080 100644 --- a/lld/COFF/InputFiles.cpp +++ b/lld/COFF/InputFiles.cpp @@ -117,6 +117,35 @@ static coff_symbol_generic *cloneSymbol(COFFSymbolRef sym) { } } +// Skip importing DllMain thunks from import libraries. +static bool fixupDllMain(COFFLinkerContext &ctx, llvm::object::Archive *file, + const Archive::Symbol &sym, bool &skipDllMain) { + if (skipDllMain) +return true; + const Archive::Child &c = + CHECK(sym.getMember(), file->getFileName() + + ": could not get the member for symbol " + + toCOFFString(ctx, sym)); + MemoryBufferRef mb = + CHECK(c.getMemoryBufferRef(), +file->getFileName() + +": could not get the buffer for a child buffer of the archive"); + if (identify_magic(mb.getBuffer()) == file_magic::coff_import_library) { +if (ctx.config.warnExportedDllMain) { + // We won't place DllMain symbols in the symbol table if they are + // coming from a import library. This message can be ignored with the flag + // '/ignore:exporteddllmain' + Warn(ctx) + << file->getFileName() + << ": skipping exported DllMain symbol [exporteddllmain]\nNOTE: this " + "might be a mistake when the DLL/library was produced."; +} +skipDllMain = true; +return true; + } + return false; +} + ArchiveFile::ArchiveFile(COFFLinkerContext &ctx, MemoryBufferRef m) : InputFile(ctx.symtab, ArchiveKind, m) {} @@ -140,8 +169,17 @@ void ArchiveFile::parse() { } // Read the symbol table to construct Lazy objects. - for (const Archive::Symbol &sym : file->symbols()) + bool skipDllMain = false; + for (const Archive::Symbol &sym : file->symbols()) { +// If the DllMain symbol was exported by mistake, skip importing it +// otherwise we might end up with a import thunk in the final binary which +// is wrong. +if (sym.getName() == "__imp_DllMain" || sym.getName() == "DllMain") { + if (fixupDllMain(ctx, file.get(), sym, skipDllMain)) +continue; +} ctx.symtab.addLazyArchive(this, sym); + } } // Returns a buffer pointing to a member file containing a given symbol. diff --git a/lld/test/COFF/exported-dllmain.test b/lld/test/COFF/exported-dllmain.test new file mode 100644 index 0..fcf6ed1005379 --- /dev/null +++ b/lld/test/COFF/exported-dllmain.test @@ -0,0 +1,57 @@ +REQUIRES: x86 +RUN: split-file %s %t.dir && cd %t.dir + +RUN: llvm-mc -filetype=obj -triple=x86_64-windows a.s -o a.obj + +RUN: llvm-mc -filetype=obj -triple=x86_64-windows b1.s -o b1.obj +RUN: llvm-mc -filetype=obj -triple=x86_64-windows b2.s -o b2.obj + +### This is the line where our problem occurs. Here, we export the DllMain symbol which shouldn't happen normally. +RUN: lld-link b1.obj b2.obj -out:b.dll -dll -implib:b.lib -entry:DllMain -export:bar -export:DllMain + +RUN: llvm-mc -filetype=obj -triple=x86_64-windows c.s -o c.obj +RUN: lld-link -lib c.obj -out:c.lib + +### Later, if b.lib is provided before
[llvm-branch-commits] [lld] release/20.x: Backport [LLD][COFF] Disallow importing DllMain from import libraries (#146610) (PR #146699)
@@ -313,6 +313,7 @@ struct Configuration { bool warnDebugInfoUnusable = true; bool warnLongSectionNames = true; bool warnStdcallFixup = true; + bool warnExportedDllMain = true; aganea wrote: Removed the field in this backport. https://github.com/llvm/llvm-project/pull/146699 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [lld] Backport [LLD][COFF] Disallow importing DllMain from import libraries (#146610) (PR #146699)
https://github.com/aganea milestoned https://github.com/llvm/llvm-project/pull/146699 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [lld] Backport [LLD][COFF] Disallow importing DllMain from import libraries (#146610) (PR #146699)
https://github.com/aganea created https://github.com/llvm/llvm-project/pull/146699 This is a workaround for https://github.com/llvm/llvm-project/issues/82050 by skipping the `DllMain` symbol if seen in aimport library. If this situation occurs, after this commit a warning will also be displayed. The warning can be silenced with `/ignore:exporteddllmain` >From cb11f22699cc5cf4761f7ef426721ef0496030f5 Mon Sep 17 00:00:00 2001 From: Alexandre Ganea Date: Wed, 2 Jul 2025 08:53:18 -0400 Subject: [PATCH] [LLD][COFF] Disallow importing DllMain from import libraries (#146610) This is a workaround for https://github.com/llvm/llvm-project/issues/82050 by skipping the `DllMain` symbol if seen in aimport library. If this situation occurs, after this commit a warning will also be displayed. The warning can be silenced with `/ignore:exporteddllmain` --- lld/COFF/Config.h | 1 + lld/COFF/Driver.cpp | 2 + lld/COFF/InputFiles.cpp | 40 +++- lld/test/COFF/exported-dllmain.test | 57 + 4 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 lld/test/COFF/exported-dllmain.test diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h index 0c7c4e91402f1..424e9578395b3 100644 --- a/lld/COFF/Config.h +++ b/lld/COFF/Config.h @@ -313,6 +313,7 @@ struct Configuration { bool warnDebugInfoUnusable = true; bool warnLongSectionNames = true; bool warnStdcallFixup = true; + bool warnExportedDllMain = true; bool incremental = true; bool integrityCheck = false; bool killAt = false; diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index a669b7e9296f6..8b2fc9f23178f 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -1625,6 +1625,8 @@ void LinkerDriver::linkerMain(ArrayRef argsArr) { config->warnLocallyDefinedImported = false; else if (s == "longsections") config->warnLongSectionNames = false; + else if (s == "exporteddllmain") +config->warnExportedDllMain = false; // Other warning numbers are ignored. } } diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp index 7b105fb4c17a2..b470b2a8d9080 100644 --- a/lld/COFF/InputFiles.cpp +++ b/lld/COFF/InputFiles.cpp @@ -117,6 +117,35 @@ static coff_symbol_generic *cloneSymbol(COFFSymbolRef sym) { } } +// Skip importing DllMain thunks from import libraries. +static bool fixupDllMain(COFFLinkerContext &ctx, llvm::object::Archive *file, + const Archive::Symbol &sym, bool &skipDllMain) { + if (skipDllMain) +return true; + const Archive::Child &c = + CHECK(sym.getMember(), file->getFileName() + + ": could not get the member for symbol " + + toCOFFString(ctx, sym)); + MemoryBufferRef mb = + CHECK(c.getMemoryBufferRef(), +file->getFileName() + +": could not get the buffer for a child buffer of the archive"); + if (identify_magic(mb.getBuffer()) == file_magic::coff_import_library) { +if (ctx.config.warnExportedDllMain) { + // We won't place DllMain symbols in the symbol table if they are + // coming from a import library. This message can be ignored with the flag + // '/ignore:exporteddllmain' + Warn(ctx) + << file->getFileName() + << ": skipping exported DllMain symbol [exporteddllmain]\nNOTE: this " + "might be a mistake when the DLL/library was produced."; +} +skipDllMain = true; +return true; + } + return false; +} + ArchiveFile::ArchiveFile(COFFLinkerContext &ctx, MemoryBufferRef m) : InputFile(ctx.symtab, ArchiveKind, m) {} @@ -140,8 +169,17 @@ void ArchiveFile::parse() { } // Read the symbol table to construct Lazy objects. - for (const Archive::Symbol &sym : file->symbols()) + bool skipDllMain = false; + for (const Archive::Symbol &sym : file->symbols()) { +// If the DllMain symbol was exported by mistake, skip importing it +// otherwise we might end up with a import thunk in the final binary which +// is wrong. +if (sym.getName() == "__imp_DllMain" || sym.getName() == "DllMain") { + if (fixupDllMain(ctx, file.get(), sym, skipDllMain)) +continue; +} ctx.symtab.addLazyArchive(this, sym); + } } // Returns a buffer pointing to a member file containing a given symbol. diff --git a/lld/test/COFF/exported-dllmain.test b/lld/test/COFF/exported-dllmain.test new file mode 100644 index 0..fcf6ed1005379 --- /dev/null +++ b/lld/test/COFF/exported-dllmain.test @@ -0,0 +1,57 @@ +REQUIRES: x86 +RUN: split-file %s %t.dir && cd %t.dir + +RUN: llvm-mc -filetype=obj -triple=x86_64-windows a.s -o a.obj + +RUN: llvm-mc -filetype=obj -triple=x86_64-windows b1.s -o b1.obj +RUN: llvm-mc -filetype=obj -triple=x86_64-windows b2.s -o b2.obj + +### This is the line where our problem occurs. Here, we export the DllMain symbol which sh
[llvm-branch-commits] [lld] release/20.x: Backport [LLD][COFF] Disallow importing DllMain from import libraries (#146610) (PR #146699)
https://github.com/aganea edited https://github.com/llvm/llvm-project/pull/146699 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [lld] release/20.x: Backport [LLD][COFF] Disallow importing DllMain from import libraries (#146610) (PR #146699)
https://github.com/aganea edited https://github.com/llvm/llvm-project/pull/146699 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits