https://github.com/Rajveer100 updated https://github.com/llvm/llvm-project/pull/210973
>From e1656df3890c0cd1e8e796573f31fac0a3bb75af Mon Sep 17 00:00:00 2001 From: Rajveer <[email protected]> Date: Tue, 21 Jul 2026 18:07:30 +0530 Subject: [PATCH 1/2] [clang][SemaCXX] Fixed a crash when returning an initialization to a top-level deleted function Resolves #208488 This crash is caused due to requesting declaration alignment for undeduced types like `auto`. --- clang/docs/ReleaseNotes.md | 2 ++ clang/lib/Sema/SemaStmt.cpp | 7 +++++++ clang/test/SemaCXX/deleted-function-return.cpp | 8 ++++++++ 3 files changed, 17 insertions(+) create mode 100644 clang/test/SemaCXX/deleted-function-return.cpp diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index 28fea9a99b609..d8943d6af7a7d 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -334,6 +334,8 @@ latest release, please see the [Clang Web Site](https://clang.llvm.org) or the `[](Types... = args...) {}`). Clang now diagnoses the illegal default argument instead of asserting. (#GH210714) +- Fixed a crash when returning an initialization to a top-level deleted function. (#GH208488) + #### Bug Fixes to AST Handling - Fixed a non-deterministic ordering of unused local typedefs that made diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index cc325620883f0..83e0eb9caadca 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -3545,6 +3545,13 @@ Sema::NamedReturnInfo Sema::getNamedReturnInfo(const VarDecl *VD) { return NamedReturnInfo(); } + const Type *T = VDType.getTypePtr(); + if (T->getTypeClass() == Type::Auto) { + const auto *A = cast<DeducedType>(T); + if (A->isUndeducedAutoType()) + return NamedReturnInfo(); + } + // Variables with higher required alignment than their type's ABI // alignment cannot use NRVO. if (!VD->hasDependentAlignment() && !VDType->isIncompleteType() && diff --git a/clang/test/SemaCXX/deleted-function-return.cpp b/clang/test/SemaCXX/deleted-function-return.cpp new file mode 100644 index 0000000000000..9320b85cd1dc8 --- /dev/null +++ b/clang/test/SemaCXX/deleted-function-return.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -verify -std=c++2a -fsyntax-only %s + +auto f() = delete; // expected-note {{candidate function has been explicitly deleted}} + +auto g() { + auto x = f(); // expected-error {{call to deleted function 'f'}} + return x; +} >From 3820e62ad8399b0a45755594a29f80e1ba85ed66 Mon Sep 17 00:00:00 2001 From: Dan Blackwell <[email protected]> Date: Tue, 21 Jul 2026 14:08:51 +0100 Subject: [PATCH 2/2] [Darwin][TSan] Fix race in mach_vm_deallocate interceptor (#210716) I have seen an issue whereby the meta store in MetaMap::AllocBlock lands in the unmapped gap left during the tsan::MetaMap::ResetRange call; where the range is first unmapped, and then remapped with MAP_FIXED. This occurred under the mach_vm_deallocate interceptor, because it first does the deallocate call, and only then does it call UnmapShadow - leaving a gap where a fresh slab for malloc can land, only to have the meta region for that range mapped out from under it, resulting in a bad access fault. It is worth noting that there is a comment above the IsValidMmapRange function (which gets called during UnmapShadow), that describes this exact issue in the context of munmap. rdar://179172055 Assisted by: Claude --- .../test/SemaCXX/deleted-function-return.cpp | 7 ++- .../tsan/rtl/tsan_interceptors_mach_vm.cpp | 5 +- .../tsan/Darwin/mach_vm_deallocate_race.c | 57 +++++++++++++++++++ 3 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 compiler-rt/test/tsan/Darwin/mach_vm_deallocate_race.c diff --git a/clang/test/SemaCXX/deleted-function-return.cpp b/clang/test/SemaCXX/deleted-function-return.cpp index 9320b85cd1dc8..a0dd145ec0ec9 100644 --- a/clang/test/SemaCXX/deleted-function-return.cpp +++ b/clang/test/SemaCXX/deleted-function-return.cpp @@ -2,7 +2,12 @@ auto f() = delete; // expected-note {{candidate function has been explicitly deleted}} -auto g() { +auto g1() { auto x = f(); // expected-error {{call to deleted function 'f'}} return x; } + +auto g2() { + decltype(auto) x = f(); // expected-error {{call to deleted function 'f'}} + return x; +} diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_mach_vm.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_mach_vm.cpp index 6d62ff6a83825..4b0c86d772b5a 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_mach_vm.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_mach_vm.cpp @@ -44,10 +44,9 @@ TSAN_INTERCEPTOR(kern_return_t, mach_vm_deallocate, vm_map_t target, SCOPED_TSAN_INTERCEPTOR(mach_vm_deallocate, target, address, size); if (target != mach_task_self()) return REAL(mach_vm_deallocate)(target, address, size); - kern_return_t kr = REAL(mach_vm_deallocate)(target, address, size); - if (kr == KERN_SUCCESS && address) + if (address) UnmapShadow(thr, address, size); - return kr; + return REAL(mach_vm_deallocate)(target, address, size); } } // namespace __tsan diff --git a/compiler-rt/test/tsan/Darwin/mach_vm_deallocate_race.c b/compiler-rt/test/tsan/Darwin/mach_vm_deallocate_race.c new file mode 100644 index 0000000000000..ccbe8173922ee --- /dev/null +++ b/compiler-rt/test/tsan/Darwin/mach_vm_deallocate_race.c @@ -0,0 +1,57 @@ +// Test that concurrent mach_vm_deallocate / mach_vm_allocate on the same +// virtual address range do not race in the TSan runtime's shadow/meta reset. +// +// Several threads free a region while others reuse the same VA (via an address +// hint) and touch it. If mach_vm_deallocate resets the shadow/meta *after* the +// real deallocation, the freed VA can be handed to a reusing thread mid reset +// -> SEGV at a meta address (or clobbered metadata). Resetting before the real +// deallocation (while we still own the mapping) avoids this. +// +// RUN: %clang_tsan %s -o %t +// RUN: %env_tsan_opts=abort_on_error=0 %run %t 2>&1 | FileCheck %s + +// UNSUPPORTED: iossim + +#include <mach/mach.h> +#include <mach/mach_vm.h> +#include <pthread.h> +#include <stdio.h> + +static const mach_vm_size_t kSize = + 16 << 20; // >128KB forces ResetRange unmap path +static const int kThreads = 4; +static const long kIters = 1000; +static mach_vm_address_t g_hint; // shared placement hint (the contended VA) + +static void *worker(void *arg) { + for (long i = 0; i < kIters; i++) { + mach_vm_address_t a = g_hint; // prefer the just-freed VA + if (mach_vm_allocate(mach_task_self(), &a, kSize, VM_FLAGS_ANYWHERE) != + KERN_SUCCESS) + continue; + *(volatile char *)a = 1; // touch to check for faults + mach_vm_deallocate(mach_task_self(), a, kSize); + } + return NULL; +} + +int main(void) { + mach_vm_address_t a = 0; + if (mach_vm_allocate(mach_task_self(), &a, kSize, VM_FLAGS_ANYWHERE) != + KERN_SUCCESS) + return 1; + g_hint = a; + mach_vm_deallocate(mach_task_self(), a, kSize); + + pthread_t t[kThreads]; + for (int i = 0; i < kThreads; i++) + pthread_create(&t[i], NULL, worker, NULL); + for (int i = 0; i < kThreads; i++) + pthread_join(t[i], NULL); + + fprintf(stderr, "Done.\n"); + return 0; +} + +// CHECK-NOT: ThreadSanitizer +// CHECK: Done. _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
