[clang-tools-extra] 54d78b6 - Remove the ThreadLocal template from LLVM.
Author: Owen Anderson Date: 2023-01-09T21:12:27-07:00 New Revision: 54d78b639b9c18b42abd4fac5c6e76105f06b3ef URL: https://github.com/llvm/llvm-project/commit/54d78b639b9c18b42abd4fac5c6e76105f06b3ef DIFF: https://github.com/llvm/llvm-project/commit/54d78b639b9c18b42abd4fac5c6e76105f06b3ef.diff LOG: Remove the ThreadLocal template from LLVM. This has been obsoleted by C++ thread_local for a long time. As far as I know, Xcode was the last supported toolchain to add support for C++ thread_local in 2016. As a precaution, use LLVM_THREAD_LOCAL which provides even greater backwards compatibility, allowing this to function even pre-C++11 versions of GCC. Reviewed By: majnemer Differential Revision: https://reviews.llvm.org/D141347 Added: Modified: clang-tools-extra/clangd/support/ThreadCrashReporter.cpp llvm/lib/Support/CMakeLists.txt llvm/lib/Support/CrashRecoveryContext.cpp llvm/unittests/Support/CMakeLists.txt mlir/include/mlir/Support/ThreadLocalCache.h Removed: llvm/include/llvm/Support/ThreadLocal.h llvm/lib/Support/ThreadLocal.cpp llvm/lib/Support/Unix/ThreadLocal.inc llvm/lib/Support/Windows/ThreadLocal.inc llvm/unittests/Support/ThreadLocalTest.cpp diff --git a/clang-tools-extra/clangd/support/ThreadCrashReporter.cpp b/clang-tools-extra/clangd/support/ThreadCrashReporter.cpp index 05afb3b25f28e..9551bbfda43c1 100644 --- a/clang-tools-extra/clangd/support/ThreadCrashReporter.cpp +++ b/clang-tools-extra/clangd/support/ThreadCrashReporter.cpp @@ -7,7 +7,6 @@ //===--===// #include "support/ThreadCrashReporter.h" -#include "llvm/Support/ThreadLocal.h" #include namespace clang { diff --git a/llvm/include/llvm/Support/ThreadLocal.h b/llvm/include/llvm/Support/ThreadLocal.h deleted file mode 100644 index d6838c15fc345..0 --- a/llvm/include/llvm/Support/ThreadLocal.h +++ /dev/null @@ -1,62 +0,0 @@ -//===- llvm/Support/ThreadLocal.h - Thread Local Data *- 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 -// -//===--===// -// -// This file declares the llvm::sys::ThreadLocal class. -// -//===--===// - -#ifndef LLVM_SUPPORT_THREADLOCAL_H -#define LLVM_SUPPORT_THREADLOCAL_H - -#include "llvm/Support/DataTypes.h" -#include "llvm/Support/Threading.h" -#include - -namespace llvm { - namespace sys { -// ThreadLocalImpl - Common base class of all ThreadLocal instantiations. -// YOU SHOULD NEVER USE THIS DIRECTLY. -class ThreadLocalImpl { - typedef uint64_t ThreadLocalDataTy; - /// Platform-specific thread local data. - /// - /// This is embedded in the class and we avoid malloc'ing/free'ing it, - /// to make this class more safe for use along with CrashRecoveryContext. - union { -char data[sizeof(ThreadLocalDataTy)]; -ThreadLocalDataTy align_data; - }; -public: - ThreadLocalImpl(); - virtual ~ThreadLocalImpl(); - void setInstance(const void* d); - void *getInstance(); - void removeInstance(); -}; - -/// ThreadLocal - A class used to abstract thread-local storage. It holds, -/// for each thread, a pointer a single object of type T. -template -class ThreadLocal : public ThreadLocalImpl { -public: - ThreadLocal() : ThreadLocalImpl() { } - - /// get - Fetches a pointer to the object associated with the current - /// thread. If no object has yet been associated, it returns NULL; - T* get() { return static_cast(getInstance()); } - - // set - Associates a pointer to an object with the current thread. - void set(T* d) { setInstance(d); } - - // erase - Removes the pointer associated with the current thread. - void erase() { removeInstance(); } -}; - } -} - -#endif diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt index 46469c6e9e624..9b5402fa54f0f 100644 --- a/llvm/lib/Support/CMakeLists.txt +++ b/llvm/lib/Support/CMakeLists.txt @@ -260,7 +260,6 @@ add_llvm_component_library(LLVMSupport Program.cpp RWMutex.cpp Signals.cpp - ThreadLocal.cpp Threading.cpp Valgrind.cpp Watchdog.cpp diff --git a/llvm/lib/Support/CrashRecoveryContext.cpp b/llvm/lib/Support/CrashRecoveryContext.cpp index c7c384c9edc22..9e792d1f51777 100644 --- a/llvm/lib/Support/CrashRecoveryContext.cpp +++ b/llvm/lib/Support/CrashRecoveryContext.cpp @@ -11,7 +11,6 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ExitCodes.h" #include "llvm/Support/Signals.h" -#include "llvm/Support/Thr
[clang-tools-extra] ef9aa34 - Revert "Remove the ThreadLocal template from LLVM."
Author: Owen Anderson Date: 2023-01-09T21:21:38-07:00 New Revision: ef9aa34f0274cdbfa82c47f8ab99f02679fd0d13 URL: https://github.com/llvm/llvm-project/commit/ef9aa34f0274cdbfa82c47f8ab99f02679fd0d13 DIFF: https://github.com/llvm/llvm-project/commit/ef9aa34f0274cdbfa82c47f8ab99f02679fd0d13.diff LOG: Revert "Remove the ThreadLocal template from LLVM." This reverts commit 54d78b639b9c18b42abd4fac5c6e76105f06b3ef. Added: llvm/include/llvm/Support/ThreadLocal.h llvm/lib/Support/ThreadLocal.cpp llvm/lib/Support/Unix/ThreadLocal.inc llvm/lib/Support/Windows/ThreadLocal.inc llvm/unittests/Support/ThreadLocalTest.cpp Modified: clang-tools-extra/clangd/support/ThreadCrashReporter.cpp llvm/lib/Support/CMakeLists.txt llvm/lib/Support/CrashRecoveryContext.cpp llvm/unittests/Support/CMakeLists.txt mlir/include/mlir/Support/ThreadLocalCache.h Removed: diff --git a/clang-tools-extra/clangd/support/ThreadCrashReporter.cpp b/clang-tools-extra/clangd/support/ThreadCrashReporter.cpp index 9551bbfda43c1..05afb3b25f28e 100644 --- a/clang-tools-extra/clangd/support/ThreadCrashReporter.cpp +++ b/clang-tools-extra/clangd/support/ThreadCrashReporter.cpp @@ -7,6 +7,7 @@ //===--===// #include "support/ThreadCrashReporter.h" +#include "llvm/Support/ThreadLocal.h" #include namespace clang { diff --git a/llvm/include/llvm/Support/ThreadLocal.h b/llvm/include/llvm/Support/ThreadLocal.h new file mode 100644 index 0..d6838c15fc345 --- /dev/null +++ b/llvm/include/llvm/Support/ThreadLocal.h @@ -0,0 +1,62 @@ +//===- llvm/Support/ThreadLocal.h - Thread Local Data *- 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 +// +//===--===// +// +// This file declares the llvm::sys::ThreadLocal class. +// +//===--===// + +#ifndef LLVM_SUPPORT_THREADLOCAL_H +#define LLVM_SUPPORT_THREADLOCAL_H + +#include "llvm/Support/DataTypes.h" +#include "llvm/Support/Threading.h" +#include + +namespace llvm { + namespace sys { +// ThreadLocalImpl - Common base class of all ThreadLocal instantiations. +// YOU SHOULD NEVER USE THIS DIRECTLY. +class ThreadLocalImpl { + typedef uint64_t ThreadLocalDataTy; + /// Platform-specific thread local data. + /// + /// This is embedded in the class and we avoid malloc'ing/free'ing it, + /// to make this class more safe for use along with CrashRecoveryContext. + union { +char data[sizeof(ThreadLocalDataTy)]; +ThreadLocalDataTy align_data; + }; +public: + ThreadLocalImpl(); + virtual ~ThreadLocalImpl(); + void setInstance(const void* d); + void *getInstance(); + void removeInstance(); +}; + +/// ThreadLocal - A class used to abstract thread-local storage. It holds, +/// for each thread, a pointer a single object of type T. +template +class ThreadLocal : public ThreadLocalImpl { +public: + ThreadLocal() : ThreadLocalImpl() { } + + /// get - Fetches a pointer to the object associated with the current + /// thread. If no object has yet been associated, it returns NULL; + T* get() { return static_cast(getInstance()); } + + // set - Associates a pointer to an object with the current thread. + void set(T* d) { setInstance(d); } + + // erase - Removes the pointer associated with the current thread. + void erase() { removeInstance(); } +}; + } +} + +#endif diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt index 9b5402fa54f0f..46469c6e9e624 100644 --- a/llvm/lib/Support/CMakeLists.txt +++ b/llvm/lib/Support/CMakeLists.txt @@ -260,6 +260,7 @@ add_llvm_component_library(LLVMSupport Program.cpp RWMutex.cpp Signals.cpp + ThreadLocal.cpp Threading.cpp Valgrind.cpp Watchdog.cpp diff --git a/llvm/lib/Support/CrashRecoveryContext.cpp b/llvm/lib/Support/CrashRecoveryContext.cpp index 9e792d1f51777..c7c384c9edc22 100644 --- a/llvm/lib/Support/CrashRecoveryContext.cpp +++ b/llvm/lib/Support/CrashRecoveryContext.cpp @@ -11,6 +11,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ExitCodes.h" #include "llvm/Support/Signals.h" +#include "llvm/Support/ThreadLocal.h" #include "llvm/Support/thread.h" #include #include @@ -20,7 +21,11 @@ using namespace llvm; namespace { struct CrashRecoveryContextImpl; -LLVM_THREAD_LOCAL static const CrashRecoveryContextImpl *CurrentContext; + +sys::ThreadLocal &getCurrentContext() { + static sys::ThreadLocal CurrentContext; + return
[clang-tools-extra] e4e0f93 - Remove the ThreadLocal template from LLVM.
Author: Owen Anderson Date: 2023-01-10T21:07:52-07:00 New Revision: e4e0f933079859c12983f955e7ee66ba4fb39932 URL: https://github.com/llvm/llvm-project/commit/e4e0f933079859c12983f955e7ee66ba4fb39932 DIFF: https://github.com/llvm/llvm-project/commit/e4e0f933079859c12983f955e7ee66ba4fb39932.diff LOG: Remove the ThreadLocal template from LLVM. This has been obsoleted by C++ thread_local for a long time. As far as I know, Xcode was the last supported toolchain to add support for C++ thread_local in 2016. As a precaution, use LLVM_THREAD_LOCAL which provides even greater backwards compatibility, allowing this to function even pre-C++11 versions of GCC. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D141349 Added: Modified: clang-tools-extra/clangd/support/ThreadCrashReporter.cpp llvm/lib/Support/CMakeLists.txt llvm/lib/Support/CrashRecoveryContext.cpp llvm/unittests/Support/CMakeLists.txt mlir/include/mlir/Support/ThreadLocalCache.h Removed: llvm/include/llvm/Support/ThreadLocal.h llvm/lib/Support/ThreadLocal.cpp llvm/lib/Support/Unix/ThreadLocal.inc llvm/lib/Support/Windows/ThreadLocal.inc llvm/unittests/Support/ThreadLocalTest.cpp diff --git a/clang-tools-extra/clangd/support/ThreadCrashReporter.cpp b/clang-tools-extra/clangd/support/ThreadCrashReporter.cpp index 05afb3b25f28e..9551bbfda43c1 100644 --- a/clang-tools-extra/clangd/support/ThreadCrashReporter.cpp +++ b/clang-tools-extra/clangd/support/ThreadCrashReporter.cpp @@ -7,7 +7,6 @@ //===--===// #include "support/ThreadCrashReporter.h" -#include "llvm/Support/ThreadLocal.h" #include namespace clang { diff --git a/llvm/include/llvm/Support/ThreadLocal.h b/llvm/include/llvm/Support/ThreadLocal.h deleted file mode 100644 index d6838c15fc345..0 --- a/llvm/include/llvm/Support/ThreadLocal.h +++ /dev/null @@ -1,62 +0,0 @@ -//===- llvm/Support/ThreadLocal.h - Thread Local Data *- 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 -// -//===--===// -// -// This file declares the llvm::sys::ThreadLocal class. -// -//===--===// - -#ifndef LLVM_SUPPORT_THREADLOCAL_H -#define LLVM_SUPPORT_THREADLOCAL_H - -#include "llvm/Support/DataTypes.h" -#include "llvm/Support/Threading.h" -#include - -namespace llvm { - namespace sys { -// ThreadLocalImpl - Common base class of all ThreadLocal instantiations. -// YOU SHOULD NEVER USE THIS DIRECTLY. -class ThreadLocalImpl { - typedef uint64_t ThreadLocalDataTy; - /// Platform-specific thread local data. - /// - /// This is embedded in the class and we avoid malloc'ing/free'ing it, - /// to make this class more safe for use along with CrashRecoveryContext. - union { -char data[sizeof(ThreadLocalDataTy)]; -ThreadLocalDataTy align_data; - }; -public: - ThreadLocalImpl(); - virtual ~ThreadLocalImpl(); - void setInstance(const void* d); - void *getInstance(); - void removeInstance(); -}; - -/// ThreadLocal - A class used to abstract thread-local storage. It holds, -/// for each thread, a pointer a single object of type T. -template -class ThreadLocal : public ThreadLocalImpl { -public: - ThreadLocal() : ThreadLocalImpl() { } - - /// get - Fetches a pointer to the object associated with the current - /// thread. If no object has yet been associated, it returns NULL; - T* get() { return static_cast(getInstance()); } - - // set - Associates a pointer to an object with the current thread. - void set(T* d) { setInstance(d); } - - // erase - Removes the pointer associated with the current thread. - void erase() { removeInstance(); } -}; - } -} - -#endif diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt index 46469c6e9e624..9b5402fa54f0f 100644 --- a/llvm/lib/Support/CMakeLists.txt +++ b/llvm/lib/Support/CMakeLists.txt @@ -260,7 +260,6 @@ add_llvm_component_library(LLVMSupport Program.cpp RWMutex.cpp Signals.cpp - ThreadLocal.cpp Threading.cpp Valgrind.cpp Watchdog.cpp diff --git a/llvm/lib/Support/CrashRecoveryContext.cpp b/llvm/lib/Support/CrashRecoveryContext.cpp index c7c384c9edc22..fe0df90e9f2ea 100644 --- a/llvm/lib/Support/CrashRecoveryContext.cpp +++ b/llvm/lib/Support/CrashRecoveryContext.cpp @@ -11,8 +11,8 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ExitCodes.h" #include "llvm/Support/Signals.h" -#include "llvm/Support/Thread
[PATCH] D16041: Change vfs::FileSystem to be managed with std::shared_ptr
resistor created this revision. resistor added reviewers: chandlerc, bkramer, klimek. resistor added a subscriber: cfe-commits. resistor set the repository for this revision to rL LLVM. Herald added a subscriber: klimek. Managing it with IntrusiveRefCntPtr caused the virtual destructor not to be called properly. Repository: rL LLVM http://reviews.llvm.org/D16041 Files: include/clang/Basic/FileManager.h include/clang/Basic/VirtualFileSystem.h include/clang/Driver/Driver.h include/clang/Frontend/CompilerInstance.h include/clang/Frontend/CompilerInvocation.h include/clang/Tooling/Tooling.h lib/Basic/FileManager.cpp lib/Basic/VirtualFileSystem.cpp lib/Driver/Driver.cpp lib/Format/Format.cpp lib/Frontend/ASTUnit.cpp lib/Frontend/CompilerInstance.cpp lib/Frontend/CompilerInvocation.cpp lib/Frontend/FrontendAction.cpp lib/Index/SimpleFormatContext.h lib/StaticAnalyzer/Frontend/ModelInjector.cpp lib/Tooling/Core/Replacement.cpp lib/Tooling/Tooling.cpp tools/clang-format/ClangFormat.cpp unittests/Basic/VirtualFileSystemTest.cpp unittests/Driver/ToolChainTest.cpp unittests/Lex/PPCallbacksTest.cpp unittests/Tooling/RewriterTestContext.h unittests/Tooling/ToolingTest.cpp Index: unittests/Tooling/ToolingTest.cpp === --- unittests/Tooling/ToolingTest.cpp +++ unittests/Tooling/ToolingTest.cpp @@ -149,9 +149,9 @@ } TEST(ToolInvocation, TestMapVirtualFile) { - llvm::IntrusiveRefCntPtr OverlayFileSystem( + std::shared_ptr OverlayFileSystem( new vfs::OverlayFileSystem(vfs::getRealFileSystem())); - llvm::IntrusiveRefCntPtr InMemoryFileSystem( + std::shared_ptr InMemoryFileSystem( new vfs::InMemoryFileSystem); OverlayFileSystem->pushOverlay(InMemoryFileSystem); llvm::IntrusiveRefCntPtr Files( @@ -175,9 +175,9 @@ // mapped module.map is found on the include path. In the future, expand this // test to run a full modules enabled compilation, so we make sure we can // rerun modules compilations with a virtual file system. - llvm::IntrusiveRefCntPtr OverlayFileSystem( + std::shared_ptr OverlayFileSystem( new vfs::OverlayFileSystem(vfs::getRealFileSystem())); - llvm::IntrusiveRefCntPtr InMemoryFileSystem( + std::shared_ptr InMemoryFileSystem( new vfs::InMemoryFileSystem); OverlayFileSystem->pushOverlay(InMemoryFileSystem); llvm::IntrusiveRefCntPtr Files( Index: unittests/Tooling/RewriterTestContext.h === --- unittests/Tooling/RewriterTestContext.h +++ unittests/Tooling/RewriterTestContext.h @@ -114,8 +114,8 @@ IntrusiveRefCntPtr DiagOpts; DiagnosticsEngine Diagnostics; TextDiagnosticPrinter DiagnosticPrinter; - IntrusiveRefCntPtr InMemoryFileSystem; - IntrusiveRefCntPtr OverlayFileSystem; + std::shared_ptr InMemoryFileSystem; + std::shared_ptr OverlayFileSystem; FileManager Files; SourceManager Sources; LangOptions Options; Index: unittests/Lex/PPCallbacksTest.cpp === --- unittests/Lex/PPCallbacksTest.cpp +++ unittests/Lex/PPCallbacksTest.cpp @@ -119,7 +119,7 @@ Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts); } - IntrusiveRefCntPtr InMemoryFileSystem; + std::shared_ptr InMemoryFileSystem; FileManager FileMgr; IntrusiveRefCntPtr DiagID; IntrusiveRefCntPtr DiagOpts; Index: unittests/Driver/ToolChainTest.cpp === --- unittests/Driver/ToolChainTest.cpp +++ unittests/Driver/ToolChainTest.cpp @@ -31,7 +31,7 @@ IntrusiveRefCntPtr DiagID(new DiagnosticIDs()); struct TestDiagnosticConsumer : public DiagnosticConsumer {}; DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer); - IntrusiveRefCntPtr InMemoryFileSystem( + std::shared_ptr InMemoryFileSystem( new vfs::InMemoryFileSystem); Driver TheDriver("/bin/clang", "arm-linux-gnueabihf", Diags, InMemoryFileSystem); @@ -84,7 +84,7 @@ IntrusiveRefCntPtr DiagID(new DiagnosticIDs()); struct TestDiagnosticConsumer : public DiagnosticConsumer {}; DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer); - IntrusiveRefCntPtr InMemoryFileSystem( + std::shared_ptr InMemoryFileSystem( new vfs::InMemoryFileSystem); Driver TheDriver("/home/test/bin/clang", "arm-linux-gnueabi", Diags, InMemoryFileSystem); Index: unittests/Basic/VirtualFileSystemTest.cpp === --- unittests/Basic/VirtualFileSystemTest.cpp +++ unittests/Basic/VirtualFileSystemTest.cpp @@ -134,7 +134,7 @@ } // end anonymous namespace TEST(VirtualFileSystemTest, StatusQueries) { - IntrusiveRefCntPtr D(new DummyFileSystem()); + std::shared_ptr D(new DummyFileSystem()); ErrorOr Status((std::error_code())); D->addRegularFile("/foo"); @@ -174,1
Re: [PATCH] D16041: Change vfs::FileSystem to be managed with std::shared_ptr
> On Jan 11, 2016, at 8:25 AM, David Blaikie wrote: > > > > On Sun, Jan 10, 2016 at 11:42 PM, Owen Anderson via cfe-commits > wrote: > resistor created this revision. > resistor added reviewers: chandlerc, bkramer, klimek. > resistor added a subscriber: cfe-commits. > resistor set the repository for this revision to rL LLVM. > Herald added a subscriber: klimek. > > Managing it with IntrusiveRefCntPtr caused the virtual destructor not to be > called properly. > > Regardless of the broader discussion on this patch, I'm confused by why this > ^ would be the case. What is it that IntrusiveRefCntPtr is doing that's > causing problems with destruction? (& I'm all for changing this to > non-intrusive smart pointers over intrusive ones anyway, but I'd still like > to understand the extra motivation here) > ThreadSafeRefCountedBase, which classes must inherit from in order to use IntrusiveRefCntPtr, does not handle virtual destructors properly. For the non-thread safe version, there is RefCountBaseVPTR which solves this problem. An alternative solution would have been to add a corresponding ThreadSafeRefCountedBaseVPTR, but IMO at that point one might as well use shared_ptr since it’s 90% of the way there. —Owen ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D16041: Change vfs::FileSystem to be managed with std::shared_ptr
> On Jan 11, 2016, at 2:13 PM, Benjamin Kramer wrote: > > On Mon, Jan 11, 2016 at 8:08 PM, Owen Anderson <mailto:resis...@mac.com>> wrote: >> >>> On Jan 11, 2016, at 8:25 AM, David Blaikie wrote: >>> >>> >>> >>> On Sun, Jan 10, 2016 at 11:42 PM, Owen Anderson via cfe-commits >>> wrote: >>> resistor created this revision. >>> resistor added reviewers: chandlerc, bkramer, klimek. >>> resistor added a subscriber: cfe-commits. >>> resistor set the repository for this revision to rL LLVM. >>> Herald added a subscriber: klimek. >>> >>> Managing it with IntrusiveRefCntPtr caused the virtual destructor not to be >>> called properly. >>> >>> Regardless of the broader discussion on this patch, I'm confused by why >>> this ^ would be the case. What is it that IntrusiveRefCntPtr is doing >>> that's causing problems with destruction? (& I'm all for changing this to >>> non-intrusive smart pointers over intrusive ones anyway, but I'd still like >>> to understand the extra motivation here) >>> >> >> ThreadSafeRefCountedBase, which classes must inherit from in order to use >> IntrusiveRefCntPtr, does not handle virtual destructors properly. For the >> non-thread safe version, there is RefCountBaseVPTR which solves this >> problem. An alternative solution would have been to add a corresponding >> ThreadSafeRefCountedBaseVPTR, but IMO at that point one might as well use >> shared_ptr since it’s 90% of the way there. > > I find this surprising. ThreadSafeRefCountedBase calls > "delete static_cast(this)". As FileSystem has a > virtual dtor, polymorphic deletion should just work. Am I missing > something? I’m not an expert on this stuff, but I’ll refer you to the difference between RefCountedBase and RefCountedBaseVPTR, and point out that ThreadSafeRefCountedBase is like the former rather than the latter. —Owen___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Do not emit template parameter objects as COMDATs when they have internal linkage. (PR #125448)
https://github.com/resistor closed https://github.com/llvm/llvm-project/pull/125448 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Do not emit template parameter objects as COMDATs when they have internal linkage. (PR #125448)
@@ -3765,7 +3765,7 @@ ConstantAddress CodeGenModule::GetAddrOfTemplateParamObject( auto *GV = new llvm::GlobalVariable(getModule(), Init->getType(), /*isConstant=*/true, Linkage, Init, Name); setGVProperties(GV, TPO); - if (supportsCOMDAT()) + if (supportsCOMDAT() && Linkage == llvm::GlobalValue::LinkOnceODRLinkage) resistor wrote: Linkage is set to either LinkOnceODRLinkage or InternalLinkage a few lines above this. https://github.com/llvm/llvm-project/pull/125448 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Do not emit template parameter objects as COMDATs when they have internal linkage. (PR #125448)
https://github.com/resistor created https://github.com/llvm/llvm-project/pull/125448 Per the ELF spec, section groups may only contain local symbols if those symbols are only referenced from within the section group. [1] In the case of template parameter objects, they can be referenced from outside the group when the type of the object was declared in an anonymous namespace. In that case, we can't place the object in a COMDAT. This matches GCC's linkage behavior on the test input. [1]: https://www.sco.com/developers/gabi/latest/ch4.sheader.html#section_groups >From 7aa7a526bc6876cfe9b3c68e09e3e5f84befed03 Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Mon, 3 Feb 2025 15:41:20 +1300 Subject: [PATCH] [clang] Do not emit template parameter objects as COMDATs when they have internal linkage. Per the ELF spec, section groups may only contain local symbols if those symbols are only referenced from within the section group. [1] In the case of template parameter objects, they can be referenced from outside the group when the type of the object was declared in an anonymous namespace. In that case, we can't place the object in a COMDAT. This matches GCC's linkage behavior on the test input. [1]: https://www.sco.com/developers/gabi/latest/ch4.sheader.html#section_groups --- clang/lib/CodeGen/CodeGenModule.cpp | 2 +- .../test/CodeGenCXX/nocomdat-local-symbol.cpp | 38 +++ 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 clang/test/CodeGenCXX/nocomdat-local-symbol.cpp diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 05879cd486a8c98..82002b8d8e4d4f1 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -3765,7 +3765,7 @@ ConstantAddress CodeGenModule::GetAddrOfTemplateParamObject( auto *GV = new llvm::GlobalVariable(getModule(), Init->getType(), /*isConstant=*/true, Linkage, Init, Name); setGVProperties(GV, TPO); - if (supportsCOMDAT()) + if (supportsCOMDAT() && Linkage == llvm::GlobalValue::LinkOnceODRLinkage) GV->setComdat(TheModule.getOrInsertComdat(GV->getName())); Emitter.finalize(GV); diff --git a/clang/test/CodeGenCXX/nocomdat-local-symbol.cpp b/clang/test/CodeGenCXX/nocomdat-local-symbol.cpp new file mode 100644 index 000..3beb7d2197dd597 --- /dev/null +++ b/clang/test/CodeGenCXX/nocomdat-local-symbol.cpp @@ -0,0 +1,38 @@ +// RUN: %clang_cc1 -emit-llvm -std=c++20 -triple x86_64-unknown-linux-gnu %s -o - | FileCheck %s + +// COMDAT groups in ELF objects are not permitted to contain local symbols. While template parameter +// objects are normally emitted in COMDATs, we shouldn't do so if they would have internal linkage. + +extern "C" int printf(...); +typedef __typeof__(sizeof(0)) size_t; + +namespace { +template +struct DebugContext +{ +char value[N]; +constexpr DebugContext(const char (&str)[N]) { +for (size_t i = 0; i < N; ++i) { +value[i] = str[i]; +} +} +}; +} + +template +struct ConditionalDebug +{ +public: +static void log() { +printf("%s", Context.value); +} +}; + +using Debug = ConditionalDebug<"compartment A">; + +void foo() { + Debug::log(); +} + +// CHECK-NOT: $_ZTAXtlN12_GLOBAL__N_112DebugContextILm14EEEtlA14_cLc99ELc111ELc109ELc112ELc97ELc114ELc116ELc109ELc101ELc110ELc116ELc32ELc65 = comdat any +// CHECK: @_ZTAXtlN12_GLOBAL__N_112DebugContextILm14EEEtlA14_cLc99ELc111ELc109ELc112ELc97ELc114ELc116ELc109ELc101ELc110ELc116ELc32ELc65 = internal constant %"struct.(anonymous namespace)::DebugContext" { [14 x i8] c"compartment A\00" } \ No newline at end of file ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Do not emit template parameter objects as COMDATs when they have internal linkage. (PR #125448)
https://github.com/resistor updated https://github.com/llvm/llvm-project/pull/125448 >From fabd1f091d018e76d59777ce29a9d16ef6abb48f Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Mon, 3 Feb 2025 15:41:20 +1300 Subject: [PATCH] [clang] Do not emit template parameter objects as COMDATs when they have internal linkage. Per the ELF spec, section groups may only contain local symbols if those symbols are only referenced from within the section group. [1] In the case of template parameter objects, they can be referenced from outside the group when the type of the object was declared in an anonymous namespace. In that case, we can't place the object in a COMDAT. This matches GCC's linkage behavior on the test input. [1]: https://www.sco.com/developers/gabi/latest/ch4.sheader.html#section_groups --- clang/lib/CodeGen/CodeGenModule.cpp | 2 +- clang/test/CodeGenCXX/template-param-objects.cpp | 13 + 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 05879cd486a8c9..82002b8d8e4d4f 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -3765,7 +3765,7 @@ ConstantAddress CodeGenModule::GetAddrOfTemplateParamObject( auto *GV = new llvm::GlobalVariable(getModule(), Init->getType(), /*isConstant=*/true, Linkage, Init, Name); setGVProperties(GV, TPO); - if (supportsCOMDAT()) + if (supportsCOMDAT() && Linkage == llvm::GlobalValue::LinkOnceODRLinkage) GV->setComdat(TheModule.getOrInsertComdat(GV->getName())); Emitter.finalize(GV); diff --git a/clang/test/CodeGenCXX/template-param-objects.cpp b/clang/test/CodeGenCXX/template-param-objects.cpp index 11ebd21521e83b..afe68c034def22 100644 --- a/clang/test/CodeGenCXX/template-param-objects.cpp +++ b/clang/test/CodeGenCXX/template-param-objects.cpp @@ -5,6 +5,9 @@ struct S { char buf[32]; }; template constexpr const char *begin() { return s.buf; } template constexpr const char *end() { return s.buf + __builtin_strlen(s.buf); } +namespace { struct T { char buf[32]; }; } +template constexpr const char* begin_anon() { return t.buf; } + // ITANIUM: [[HELLO:@_ZTAXtl1StlA32_cLc104ELc101ELc108ELc108ELc111ELc32ELc119ELc111ELc114ELc108ELc100]] // MSABI: [[HELLO:@"[?][?]__N2US@@3D0GI@@0GF@@0GM@@0GM@@0GP@@0CA@@0HH@@0GP@@0HC@@0GM@@0GE@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@"]] // ITANIUM-SAME: = linkonce_odr constant { <{ [11 x i8], [21 x i8] }> } { <{ [11 x i8], [21 x i8] }> <{ [11 x i8] c"hello world", [21 x i8] zeroinitializer }> }, comdat @@ -19,3 +22,13 @@ const char *p = begin(); // MSABI: @"?q@@3PEBDEB" // CHECK-SAME: global ptr getelementptr (i8, ptr [[HELLO]], i64 11) const char *q = end(); + + +// ITANIUM: [[HELLOANON:@_ZTAXtlN12_GLOBAL__N_11TEtlA32_cLc104ELc101ELc108ELc108ELc111ELc32ELc97ELc110ELc111ELc110]] +// MSABI: [[HELLOANON:@"[?][?]__N2UT@[?]A0xFD1119C8@@3D0GI@@0GF@@0GM@@0GM@@0GP@@0CA@@0GB@@0GO@@0GP@@0GO@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@"]] +// CHECK-SAME: internal constant { <{ [10 x i8], [22 x i8] }> } { <{ [10 x i8], [22 x i8] }> <{ [10 x i8] c"hello anon", [22 x i8] zeroinitializer }> } +// ITANIUM: @r +// MSABI: @"?r@@3PEBDEB" +// CHECK-SAME: global ptr [[HELLOANON]] +// CHECK-NOT: comdat +const char *r = begin_anon(); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Do not emit template parameter objects as COMDATs when they have internal linkage. (PR #125448)
@@ -0,0 +1,38 @@ +// RUN: %clang_cc1 -emit-llvm -std=c++20 -triple x86_64-unknown-linux-gnu %s -o - | FileCheck %s + +// COMDAT groups in ELF objects are not permitted to contain local symbols. While template parameter +// objects are normally emitted in COMDATs, we shouldn't do so if they would have internal linkage. + +extern "C" int printf(...); +typedef __typeof__(sizeof(0)) size_t; + +namespace { +template +struct DebugContext +{ +char value[N]; +constexpr DebugContext(const char (&str)[N]) { resistor wrote: Done and folded into existing test. https://github.com/llvm/llvm-project/pull/125448 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Do not emit template parameter objects as COMDATs when they have internal linkage. (PR #125448)
@@ -0,0 +1,38 @@ +// RUN: %clang_cc1 -emit-llvm -std=c++20 -triple x86_64-unknown-linux-gnu %s -o - | FileCheck %s resistor wrote: Done https://github.com/llvm/llvm-project/pull/125448 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Do not emit template parameter objects as COMDATs when they have internal linkage. (PR #125448)
https://github.com/resistor updated https://github.com/llvm/llvm-project/pull/125448 >From 8d2ed55358510e45c03934aaaffccbf12d0bffce Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Mon, 3 Feb 2025 15:41:20 +1300 Subject: [PATCH] [clang] Do not emit template parameter objects as COMDATs when they have internal linkage. Per the ELF spec, section groups may only contain local symbols if those symbols are only referenced from within the section group. [1] In the case of template parameter objects, they can be referenced from outside the group when the type of the object was declared in an anonymous namespace. In that case, we can't place the object in a COMDAT. This matches GCC's linkage behavior on the test input. [1]: https://www.sco.com/developers/gabi/latest/ch4.sheader.html#section_groups --- clang/lib/CodeGen/CodeGenModule.cpp | 2 +- clang/test/CodeGenCXX/template-param-objects.cpp | 10 ++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 05879cd486a8c9..82002b8d8e4d4f 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -3765,7 +3765,7 @@ ConstantAddress CodeGenModule::GetAddrOfTemplateParamObject( auto *GV = new llvm::GlobalVariable(getModule(), Init->getType(), /*isConstant=*/true, Linkage, Init, Name); setGVProperties(GV, TPO); - if (supportsCOMDAT()) + if (supportsCOMDAT() && Linkage == llvm::GlobalValue::LinkOnceODRLinkage) GV->setComdat(TheModule.getOrInsertComdat(GV->getName())); Emitter.finalize(GV); diff --git a/clang/test/CodeGenCXX/template-param-objects.cpp b/clang/test/CodeGenCXX/template-param-objects.cpp index 11ebd21521e83b..ff6acc438d137a 100644 --- a/clang/test/CodeGenCXX/template-param-objects.cpp +++ b/clang/test/CodeGenCXX/template-param-objects.cpp @@ -5,6 +5,9 @@ struct S { char buf[32]; }; template constexpr const char *begin() { return s.buf; } template constexpr const char *end() { return s.buf + __builtin_strlen(s.buf); } +namespace { struct T { char buf[32]; }; } +template constexpr const char* begin_anon() { return t.buf; } + // ITANIUM: [[HELLO:@_ZTAXtl1StlA32_cLc104ELc101ELc108ELc108ELc111ELc32ELc119ELc111ELc114ELc108ELc100]] // MSABI: [[HELLO:@"[?][?]__N2US@@3D0GI@@0GF@@0GM@@0GM@@0GP@@0CA@@0HH@@0GP@@0HC@@0GM@@0GE@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@"]] // ITANIUM-SAME: = linkonce_odr constant { <{ [11 x i8], [21 x i8] }> } { <{ [11 x i8], [21 x i8] }> <{ [11 x i8] c"hello world", [21 x i8] zeroinitializer }> }, comdat @@ -19,3 +22,10 @@ const char *p = begin(); // MSABI: @"?q@@3PEBDEB" // CHECK-SAME: global ptr getelementptr (i8, ptr [[HELLO]], i64 11) const char *q = end(); + + +// CHECK: internal constant { <{ [10 x i8], [22 x i8] }> } { <{ [10 x i8], [22 x i8] }> <{ [10 x i8] c"hello anon", [22 x i8] zeroinitializer }> } +// CHECK-NOT: comdat +// ITANIUM: @r +// MSABI: @"?r@@3PEBDEB" +const char *r = begin_anon(); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Do not emit template parameter objects as COMDATs when they have internal linkage. (PR #125448)
https://github.com/resistor updated https://github.com/llvm/llvm-project/pull/125448 >From b3078fa4389f6be3f0b8c463ab9e79f1b4a9d23b Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Mon, 3 Feb 2025 15:41:20 +1300 Subject: [PATCH] [clang] Do not emit template parameter objects as COMDATs when they have internal linkage. Per the ELF spec, section groups may only contain local symbols if those symbols are only referenced from within the section group. [1] In the case of template parameter objects, they can be referenced from outside the group when the type of the object was declared in an anonymous namespace. In that case, we can't place the object in a COMDAT. This matches GCC's linkage behavior on the test input. [1]: https://www.sco.com/developers/gabi/latest/ch4.sheader.html#section_groups --- clang/lib/CodeGen/CodeGenModule.cpp | 2 +- clang/test/CodeGenCXX/template-param-objects.cpp | 13 + 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 05879cd486a8c9..82002b8d8e4d4f 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -3765,7 +3765,7 @@ ConstantAddress CodeGenModule::GetAddrOfTemplateParamObject( auto *GV = new llvm::GlobalVariable(getModule(), Init->getType(), /*isConstant=*/true, Linkage, Init, Name); setGVProperties(GV, TPO); - if (supportsCOMDAT()) + if (supportsCOMDAT() && Linkage == llvm::GlobalValue::LinkOnceODRLinkage) GV->setComdat(TheModule.getOrInsertComdat(GV->getName())); Emitter.finalize(GV); diff --git a/clang/test/CodeGenCXX/template-param-objects.cpp b/clang/test/CodeGenCXX/template-param-objects.cpp index 11ebd21521e83b..4b78e1e84f8638 100644 --- a/clang/test/CodeGenCXX/template-param-objects.cpp +++ b/clang/test/CodeGenCXX/template-param-objects.cpp @@ -5,6 +5,9 @@ struct S { char buf[32]; }; template constexpr const char *begin() { return s.buf; } template constexpr const char *end() { return s.buf + __builtin_strlen(s.buf); } +namespace { struct T { char buf[32]; }; } +template constexpr const char* begin_anon() { return t.buf; } + // ITANIUM: [[HELLO:@_ZTAXtl1StlA32_cLc104ELc101ELc108ELc108ELc111ELc32ELc119ELc111ELc114ELc108ELc100]] // MSABI: [[HELLO:@"[?][?]__N2US@@3D0GI@@0GF@@0GM@@0GM@@0GP@@0CA@@0HH@@0GP@@0HC@@0GM@@0GE@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@"]] // ITANIUM-SAME: = linkonce_odr constant { <{ [11 x i8], [21 x i8] }> } { <{ [11 x i8], [21 x i8] }> <{ [11 x i8] c"hello world", [21 x i8] zeroinitializer }> }, comdat @@ -19,3 +22,13 @@ const char *p = begin(); // MSABI: @"?q@@3PEBDEB" // CHECK-SAME: global ptr getelementptr (i8, ptr [[HELLO]], i64 11) const char *q = end(); + + +// ITANIUM: [[HELLOANON:@_ZTAXtlN12_GLOBAL__N_11TEtlA32_cLc104ELc101ELc108ELc108ELc111ELc32ELc97ELc110ELc111ELc110]] +// MSABI: [[HELLOANON:@"\?\?__N2UT@\?A0xFD1119C8@@3D0GI@@0GF@@0GM@@0GM@@0GP@@0CA@@0GB@@0GO@@0GP@@0GO@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@"]] +// CHECK-SAME: internal constant { <{ [10 x i8], [22 x i8] }> } { <{ [10 x i8], [22 x i8] }> <{ [10 x i8] c"hello anon", [22 x i8] zeroinitializer }> } +// ITANIUM: @r +// MSABI: @"?r@@3PEBDEB" +// CHECK-SAME: global ptr [[HELLOANON]] +// CHECK-NOT: comdat +const char *r = begin_anon(); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] Reapply 19c708c "FunctionDecl::getFunctionTypeLoc: ignore function type attributes (#118420)" (PR #136484)
https://github.com/resistor created https://github.com/llvm/llvm-project/pull/136484 Avoid using PreservesMost in the testcase as it is not supported on all targets. Original PR #118290. - Co-authored-by: v01dxyz Co-authored-by: Owen Anderson >From 74b5c5db64638641aa21435bb529d143d5e6e10d Mon Sep 17 00:00:00 2001 From: Robert Dazi <14996868+v01d...@users.noreply.github.com> Date: Sat, 19 Apr 2025 13:39:18 +0200 Subject: [PATCH] Reapply 19c708c "FunctionDecl::getFunctionTypeLoc: ignore function type attributes (#118420)" Avoid using PreservesMost in the testcase as it is not supported on all targets. Original PR #118290. - Co-authored-by: v01dxyz Co-authored-by: Owen Anderson --- .../clangd/unittests/InlayHintTests.cpp | 14 ++-- clang/lib/AST/Decl.cpp| 21 +- clang/unittests/AST/AttrTest.cpp | 69 +++ 3 files changed, 96 insertions(+), 8 deletions(-) diff --git a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp index 77d78b8777fe3..030e499577706 100644 --- a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp +++ b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp @@ -1577,19 +1577,21 @@ TEST(TypeHints, Aliased) { } TEST(TypeHints, CallingConvention) { - // Check that we don't crash for lambdas without a FunctionTypeLoc + // Check that we don't crash for lambdas with an annotation // https://github.com/clangd/clangd/issues/2223 - std::string Code = R"cpp( + Annotations Source(R"cpp( void test() { - []() __cdecl {}; + []($lambda[[)]]__cdecl {}; } - )cpp"; - TestTU TU = TestTU::withCode(Code); + )cpp"); + TestTU TU = TestTU::withCode(Source.code()); TU.ExtraArgs.push_back("--target=x86_64-w64-mingw32"); TU.PredefineMacros = true; // for the __cdecl auto AST = TU.build(); - EXPECT_THAT(hintsOfKind(AST, InlayHintKind::Type), IsEmpty()); + EXPECT_THAT( + hintsOfKind(AST, InlayHintKind::Type), + ElementsAre(HintMatcher(ExpectedHint{"-> void", "lambda"}, Source))); } TEST(TypeHints, Decltype) { diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index ad1cb01592e9b..1d9208f0e1c72 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -3910,8 +3910,25 @@ bool FunctionDecl::doesDeclarationForceExternallyVisibleDefinition() const { FunctionTypeLoc FunctionDecl::getFunctionTypeLoc() const { const TypeSourceInfo *TSI = getTypeSourceInfo(); - return TSI ? TSI->getTypeLoc().IgnoreParens().getAs() - : FunctionTypeLoc(); + + if (!TSI) +return FunctionTypeLoc(); + + TypeLoc TL = TSI->getTypeLoc(); + FunctionTypeLoc FTL; + + while (!(FTL = TL.getAs())) { +if (const auto PTL = TL.getAs()) + TL = PTL.getInnerLoc(); +else if (const auto ATL = TL.getAs()) + TL = ATL.getEquivalentTypeLoc(); +else if (const auto MQTL = TL.getAs()) + TL = MQTL.getInnerLoc(); +else + break; + } + + return FTL; } SourceRange FunctionDecl::getReturnTypeSourceRange() const { diff --git a/clang/unittests/AST/AttrTest.cpp b/clang/unittests/AST/AttrTest.cpp index 46c3f5729021e..bbf1c0f9a382b 100644 --- a/clang/unittests/AST/AttrTest.cpp +++ b/clang/unittests/AST/AttrTest.cpp @@ -86,6 +86,22 @@ TEST(Attr, AnnotateType) { struct S { int mem; }; int [[clang::annotate_type("int")]] S::* [[clang::annotate_type("ptr_to_mem")]] ptr_to_member = &S::mem; + +// Function Type Attributes +__attribute__((noreturn)) int f_noreturn(); + +#define NO_RETURN __attribute__((noreturn)) +NO_RETURN int f_macro_attribue(); + +int (__attribute__((noreturn)) f_paren_attribute)(); + +int ( + NO_RETURN + ( +__attribute__((warn_unused_result)) +(f_w_paren_and_attr) + ) +) (); )cpp"); { @@ -153,6 +169,59 @@ TEST(Attr, AnnotateType) { EXPECT_EQ(IntTL.getType(), AST->getASTContext().IntTy); } + { +const FunctionDecl *Func = getFunctionNode(AST.get(), "f_noreturn"); +const FunctionTypeLoc FTL = Func->getFunctionTypeLoc(); +const FunctionType *FT = FTL.getTypePtr(); + +EXPECT_TRUE(FT->getNoReturnAttr()); + } + + { +for (auto should_have_func_type_loc : { + "f_macro_attribue", + "f_paren_attribute", + "f_w_paren_and_attr", + }) { + llvm::errs() << "O: " << should_have_func_type_loc << "\n"; + const FunctionDecl *Func = + getFunctionNode(AST.get(), should_have_func_type_loc); + + EXPECT_TRUE(Func->getFunctionTypeLoc()); +} + } + + // The following test verifies getFunctionTypeLoc returns a type + // which takes into account the attribute (instead of only the nake + // type). + // + // This is hard to do with C/C++ because it seems using a function + // type attribute with a C/C++ function declaration only results + // with either: + // + // 1. It does NOT produce any AttributedType
[clang] [clang-tools-extra] Reapply 19c708c "FunctionDecl::getFunctionTypeLoc: ignore function type attributes (#118420)" (PR #136484)
https://github.com/resistor edited https://github.com/llvm/llvm-project/pull/136484 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] a15ef95 - Revert "FunctionDecl::getFunctionTypeLoc: ignore function type attributes (#118420)"
Author: Owen Anderson Date: 2025-04-20T00:01:53+12:00 New Revision: a15ef95de47620d580df21bdf35afeeb324e452d URL: https://github.com/llvm/llvm-project/commit/a15ef95de47620d580df21bdf35afeeb324e452d DIFF: https://github.com/llvm/llvm-project/commit/a15ef95de47620d580df21bdf35afeeb324e452d.diff LOG: Revert "FunctionDecl::getFunctionTypeLoc: ignore function type attributes (#118420)" This reverts commit 19c708c18963ac24822564824cb5401e71a49943 because it caused test failures on non-x86 targets. Added: Modified: clang-tools-extra/clangd/unittests/InlayHintTests.cpp clang/lib/AST/Decl.cpp clang/unittests/AST/AttrTest.cpp Removed: diff --git a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp index 030e499577706..77d78b8777fe3 100644 --- a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp +++ b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp @@ -1577,21 +1577,19 @@ TEST(TypeHints, Aliased) { } TEST(TypeHints, CallingConvention) { - // Check that we don't crash for lambdas with an annotation + // Check that we don't crash for lambdas without a FunctionTypeLoc // https://github.com/clangd/clangd/issues/2223 - Annotations Source(R"cpp( + std::string Code = R"cpp( void test() { - []($lambda[[)]]__cdecl {}; + []() __cdecl {}; } - )cpp"); - TestTU TU = TestTU::withCode(Source.code()); + )cpp"; + TestTU TU = TestTU::withCode(Code); TU.ExtraArgs.push_back("--target=x86_64-w64-mingw32"); TU.PredefineMacros = true; // for the __cdecl auto AST = TU.build(); - EXPECT_THAT( - hintsOfKind(AST, InlayHintKind::Type), - ElementsAre(HintMatcher(ExpectedHint{"-> void", "lambda"}, Source))); + EXPECT_THAT(hintsOfKind(AST, InlayHintKind::Type), IsEmpty()); } TEST(TypeHints, Decltype) { diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 1d9208f0e1c72..ad1cb01592e9b 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -3910,25 +3910,8 @@ bool FunctionDecl::doesDeclarationForceExternallyVisibleDefinition() const { FunctionTypeLoc FunctionDecl::getFunctionTypeLoc() const { const TypeSourceInfo *TSI = getTypeSourceInfo(); - - if (!TSI) -return FunctionTypeLoc(); - - TypeLoc TL = TSI->getTypeLoc(); - FunctionTypeLoc FTL; - - while (!(FTL = TL.getAs())) { -if (const auto PTL = TL.getAs()) - TL = PTL.getInnerLoc(); -else if (const auto ATL = TL.getAs()) - TL = ATL.getEquivalentTypeLoc(); -else if (const auto MQTL = TL.getAs()) - TL = MQTL.getInnerLoc(); -else - break; - } - - return FTL; + return TSI ? TSI->getTypeLoc().IgnoreParens().getAs() + : FunctionTypeLoc(); } SourceRange FunctionDecl::getReturnTypeSourceRange() const { diff --git a/clang/unittests/AST/AttrTest.cpp b/clang/unittests/AST/AttrTest.cpp index 3be362895b77e..46c3f5729021e 100644 --- a/clang/unittests/AST/AttrTest.cpp +++ b/clang/unittests/AST/AttrTest.cpp @@ -86,23 +86,6 @@ TEST(Attr, AnnotateType) { struct S { int mem; }; int [[clang::annotate_type("int")]] S::* [[clang::annotate_type("ptr_to_mem")]] ptr_to_member = &S::mem; - -// Function Type Attributes -__attribute__((noreturn)) int f_noreturn(); -__attribute__((preserve_most)) int f_cc_preserve_most(); - -#define PRESERVE_MOST __attribute__((preserve_most)) -PRESERVE_MOST int f_macro_attribue(); - -int (__attribute__((preserve_most)) f_paren_attribute)(); - -int ( - PRESERVE_MOST - ( -__attribute__((warn_unused_result)) -(f_w_paren_and_attr) - ) -) (); )cpp"); { @@ -170,67 +153,6 @@ TEST(Attr, AnnotateType) { EXPECT_EQ(IntTL.getType(), AST->getASTContext().IntTy); } - { -const FunctionDecl *Func = getFunctionNode(AST.get(), "f_noreturn"); -const FunctionTypeLoc FTL = Func->getFunctionTypeLoc(); -const FunctionType *FT = FTL.getTypePtr(); - -EXPECT_TRUE(FT->getNoReturnAttr()); - } - - { -const FunctionDecl *Func = getFunctionNode(AST.get(), "f_cc_preserve_most"); -const FunctionTypeLoc FTL = Func->getFunctionTypeLoc(); -const FunctionType *FT = FTL.getTypePtr(); - -EXPECT_TRUE(FT->getCallConv() == CC_PreserveMost); - } - - { -for (auto should_have_func_type_loc : { - "f_macro_attribue", - "f_paren_attribute", - "f_w_paren_and_attr", - }) { - llvm::errs() << "O: " << should_have_func_type_loc << "\n"; - const FunctionDecl *Func = - getFunctionNode(AST.get(), should_have_func_type_loc); - - EXPECT_TRUE(Func->getFunctionTypeLoc()); -} - } - - // The following test verifies getFunctionTypeLoc returns a type - // which takes into account the attribute (instead of only the nake - // type). - // - // This is hard to do with C/C++ because it seems using a funct
[clang] [clang-tools-extra] FunctionDecl::getFunctionTypeLoc: ignore function type attributes (PR #118420)
resistor wrote: Reverted as the test fails on non-x86 targets. Will fix and re-PR. https://github.com/llvm/llvm-project/pull/118420 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] FunctionDecl::getFunctionTypeLoc: ignore function type attributes (PR #118420)
https://github.com/resistor closed https://github.com/llvm/llvm-project/pull/118420 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] FunctionDecl::getFunctionTypeLoc: ignore function type attributes (PR #118420)
https://github.com/resistor updated https://github.com/llvm/llvm-project/pull/118420 >From b6f013097c0003e37800ad13b420e50e3c84511b Mon Sep 17 00:00:00 2001 From: v01dxyz Date: Tue, 3 Dec 2024 04:52:33 +0100 Subject: [PATCH 1/8] FunctionDecl::getFunctionTypeLoc: ignore function type attributes --- clang/lib/AST/Decl.cpp | 13 +++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 741e908cf9bc5..7df66b3bb7e14 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -3876,8 +3876,17 @@ bool FunctionDecl::doesDeclarationForceExternallyVisibleDefinition() const { FunctionTypeLoc FunctionDecl::getFunctionTypeLoc() const { const TypeSourceInfo *TSI = getTypeSourceInfo(); - return TSI ? TSI->getTypeLoc().IgnoreParens().getAs() - : FunctionTypeLoc(); + + if (!TSI) +return FunctionTypeLoc(); + + TypeLoc TL = TSI->getTypeLoc().IgnoreParens(); + + // ignore function type attributes + while (auto ATL = TL.getAs()) +TL = ATL.getModifiedLoc(); + + return TL.getAs(); } SourceRange FunctionDecl::getReturnTypeSourceRange() const { >From d5faa43a7e9c27d9493b9a171fe4d283952a5103 Mon Sep 17 00:00:00 2001 From: v01dxyz Date: Sun, 8 Dec 2024 02:16:44 +0100 Subject: [PATCH 2/8] tmp: Add test and replace ignore parens by getAsAdjusted --- clang/lib/AST/Decl.cpp | 8 +-- clang/unittests/AST/AttrTest.cpp | 40 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 7df66b3bb7e14..2ec5f5753427d 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -3880,13 +3880,7 @@ FunctionTypeLoc FunctionDecl::getFunctionTypeLoc() const { if (!TSI) return FunctionTypeLoc(); - TypeLoc TL = TSI->getTypeLoc().IgnoreParens(); - - // ignore function type attributes - while (auto ATL = TL.getAs()) -TL = ATL.getModifiedLoc(); - - return TL.getAs(); + return TSI->getTypeLoc().getAsAdjusted(); } SourceRange FunctionDecl::getReturnTypeSourceRange() const { diff --git a/clang/unittests/AST/AttrTest.cpp b/clang/unittests/AST/AttrTest.cpp index 46c3f5729021e..6cf879c401251 100644 --- a/clang/unittests/AST/AttrTest.cpp +++ b/clang/unittests/AST/AttrTest.cpp @@ -86,6 +86,9 @@ TEST(Attr, AnnotateType) { struct S { int mem; }; int [[clang::annotate_type("int")]] S::* [[clang::annotate_type("ptr_to_mem")]] ptr_to_member = &S::mem; + +// Function Type Attributes +__attribute__((noreturn)) int f_noreturn(); )cpp"); { @@ -153,6 +156,42 @@ TEST(Attr, AnnotateType) { EXPECT_EQ(IntTL.getType(), AST->getASTContext().IntTy); } + { +const FunctionDecl *Func = getFunctionNode(AST.get(), "f_noreturn"); +const FunctionTypeLoc FTL = Func->getFunctionTypeLoc(); +const FunctionType *FT = FTL.getTypePtr(); + +EXPECT_TRUE(FT->getExtInfo().getNoReturn()); + } + + // The following test verifies getFunctionTypeLoc returns a type + // which takes into account the attribute (instead of only the nake + // type). + // + // This is hard to do with C/C++ because it seems using a function + // type attribute with a C/C++ -function declaration only results + // with either: + // + // 1. It does NOT produce any AttributedType (for example it only + // sets one flag of the FunctionType's ExtInfo, ie NoReturn). + // 2. It produces an AttributedType with modified type and + // equivalent type that are equal (for example, that's what + // happens with Calling Convention attributes). + // + // Fortunately, ObjC has one specific function type attribute that + // creates an AttributedType with different modified type and + // equivalent type. + auto AST_ObjC = buildASTFromCodeWithArgs(R"objc( +__attribute__((ns_returns_retained)) id f(); + )objc", {"-fobjc-arc",}, "input.mm"); + { +const FunctionDecl *f = getFunctionNode(AST_ObjC.get(), "f"); +const FunctionTypeLoc FTL = f->getFunctionTypeLoc(); + +const FunctionType *FT = FTL.getTypePtr(); +EXPECT_TRUE(FT->getExtInfo().getProducesResult()); + } + // Test type annotation on an `__auto_type` type in C mode. AST = buildASTFromCodeWithArgs(R"c( __auto_type [[clang::annotate_type("auto")]] auto_var = 1; @@ -166,6 +205,7 @@ TEST(Attr, AnnotateType) { AutoTypeLoc AutoTL; AssertAnnotatedAs(Var->getTypeSourceInfo()->getTypeLoc(), "auto", AutoTL); } + } TEST(Attr, RegularKeywordAttribute) { >From 7e647b98756f64fbcaccba808dae2abaf9bdb2d1 Mon Sep 17 00:00:00 2001 From: v01dxyz Date: Sun, 8 Dec 2024 02:55:33 +0100 Subject: [PATCH 3/8] tmp: getAsAdjusted use getModifiedLoc, replace the loop by a custom one --- clang/lib/AST/Decl.cpp | 14 +- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 2ec5f5753427d..110ef70562c72 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/A
[clang] [clang-tools-extra] Reapply 19c708c "FunctionDecl::getFunctionTypeLoc: ignore function type attributes (#118420)" (PR #136484)
https://github.com/resistor closed https://github.com/llvm/llvm-project/pull/136484 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][RISCV] Always pass & return flexible array member structs indirectly. (PR #148541)
https://github.com/resistor created https://github.com/llvm/llvm-project/pull/148541 This fixes an issue reported in https://github.com/llvm/llvm-project/issues/148536 where writes to flexible array members would sometimes be lost if the struct happened to hit one of the cases where it would be passed in GPRs rather than on the stack. >From 83495625bddb6e4e5fce6bb11d655c6e1628c5e0 Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Mon, 14 Jul 2025 00:32:55 +0700 Subject: [PATCH] [clang][RISCV] Always pass & return flexible array member structs indirectly. This fixes an issue reported in https://github.com/llvm/llvm-project/issues/148536 where writes to flexible array members would sometimes be lost if the struct happened to hit one of the cases where it would be passed in GPRs rather than on the stack. --- clang/lib/CodeGen/Targets/RISCV.cpp | 4 ++ .../RISCV/abi-flexible-array-members.cpp | 46 +++ 2 files changed, 50 insertions(+) create mode 100644 clang/test/CodeGen/RISCV/abi-flexible-array-members.cpp diff --git a/clang/lib/CodeGen/Targets/RISCV.cpp b/clang/lib/CodeGen/Targets/RISCV.cpp index e3232b61a693c..5bf0f29903f56 100644 --- a/clang/lib/CodeGen/Targets/RISCV.cpp +++ b/clang/lib/CodeGen/Targets/RISCV.cpp @@ -609,6 +609,10 @@ ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed, if (isEmptyRecord(getContext(), Ty, true) && Size == 0) return ABIArgInfo::getIgnore(); + // Structures with flexible arrays are always indirect. + if (Ty->isStructureTypeWithFlexibleArrayMember()) +return getNaturalAlignIndirect(Ty, /*ByVal=*/false); + // Pass floating point values via FPRs if possible. if (IsFixed && Ty->isFloatingType() && !Ty->isComplexType() && FLen >= Size && ArgFPRsLeft) { diff --git a/clang/test/CodeGen/RISCV/abi-flexible-array-members.cpp b/clang/test/CodeGen/RISCV/abi-flexible-array-members.cpp new file mode 100644 index 0..b6f25982fd3f6 --- /dev/null +++ b/clang/test/CodeGen/RISCV/abi-flexible-array-members.cpp @@ -0,0 +1,46 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --filter "^define |^entry:" --version 2 +// RUN: %clang_cc1 -x c++ -triple riscv32 -target-feature +f -target-abi ilp32f -emit-llvm %s -o - \ +// RUN: | FileCheck -check-prefixes=CHECK32 %s +// RUN: %clang_cc1 -x c++ -triple riscv32 -target-feature +f -target-feature +d -target-abi ilp32d -emit-llvm %s -o - \ +// RUN: | FileCheck -check-prefixes=CHECK32 %s +// RUN: %clang_cc1 -x c++ -triple riscv64 -target-feature +f -target-abi lp64f -emit-llvm %s -o - \ +// RUN: | FileCheck -check-prefixes=CHECK64 %s +// RUN: %clang_cc1 -x c++ -triple riscv64 -target-feature +f -target-feature +d -target-abi lp64d -emit-llvm %s -o - \ +// RUN: | FileCheck -check-prefixes=CHECK64 %s + +#include + +// Structs containing C99 flexible array members should always be passed and returned on the stack. + +struct s1 { +int a; +int b[]; +}; + +// CHECK32-LABEL: define dso_local void @_Z7test_012s1 +// CHECK32-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_S1:%.*]]) align 4 [[AGG_RESULT:%.*]], ptr noundef byval([[STRUCT_S1]]) align 4 [[A:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK32: entry: +// +// CHECK64-LABEL: define dso_local void @_Z7test_012s1 +// CHECK64-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_S1:%.*]]) align 4 [[AGG_RESULT:%.*]], ptr noundef byval([[STRUCT_S1]]) align 4 [[A:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK64: entry: +// +struct s1 test_01(struct s1 a) { + return a; +} + + +// CHECK32-LABEL: define dso_local void @_Z7test_02v +// CHECK32-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_S1:%.*]]) align 4 [[AGG_RESULT:%.*]]) #[[ATTR0]] { +// CHECK32: entry: +// +// CHECK64-LABEL: define dso_local void @_Z7test_02v +// CHECK64-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_S1:%.*]]) align 4 [[AGG_RESULT:%.*]]) #[[ATTR0]] { +// CHECK64: entry: +// +struct s1 test_02() { +struct s1 r; +r.a = 0; +r.b[0] = 1; +return r; +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][RISCV] Always pass & return flexible array member structs indirectly. (PR #148541)
https://github.com/resistor closed https://github.com/llvm/llvm-project/pull/148541 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits