[clang] [clang] make it possible to disable c++26 type aware allocators (PR #138372)
Oliver Hunt via cfe-commits
cfe-commits at lists.llvm.org
Fri May 2 18:54:42 PDT 2025
https://github.com/ojhunt created https://github.com/llvm/llvm-project/pull/138372
Per the feedback from the Clang Area Team, this PR makes P2719 only on by default when targeting C++26, and adds a flag to explicitly enable or disable support.
>From ce3630845859d8771ec112c1c091134953bac7c5 Mon Sep 17 00:00:00 2001
From: Oliver Hunt <oliver at apple.com>
Date: Fri, 2 May 2025 18:15:57 -0700
Subject: [PATCH] [clang] make it possible to disable c++26 type aware
allocators
Per the feedback from the Clang Area Team, this PR makes P2719
only on by default when targeting C++26, and adds a flag to
explicitly enable or disable support.
---
clang/docs/ReleaseNotes.rst | 2 +
.../clang/Basic/DiagnosticSemaKinds.td | 3 +
clang/include/clang/Basic/LangOptions.def | 1 +
clang/include/clang/Driver/Options.td | 6 ++
clang/lib/CodeGen/CGExprCXX.cpp | 1 +
clang/lib/Driver/ToolChains/Clang.cpp | 5 +
clang/lib/Frontend/InitPreprocessor.cpp | 3 +-
clang/lib/Sema/SemaDeclCXX.cpp | 99 +++++++++++--------
clang/lib/Sema/SemaExprCXX.cpp | 4 +-
.../test/CodeGenCXX/type-aware-allocators.cpp | 10 +-
.../test/CodeGenCXX/type-aware-coroutines.cpp | 2 +-
.../type-aware-placement-operators.cpp | 8 +-
...pe-aware-destroying-new-and-delete-pch.cpp | 4 +-
clang/test/SemaCXX/type-aware-coroutines.cpp | 19 +++-
...are-new-delete-basic-free-declarations.cpp | 74 ++++++++++++--
...new-delete-basic-in-class-declarations.cpp | 58 +++++++++--
16 files changed, 227 insertions(+), 72 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 4bd9d904e1ea9..53fb4e640a351 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -110,6 +110,8 @@ C++2c Feature Support
- Implemented `P0963R3 Structured binding declaration as a condition <https://wg21.link/P0963R3>`_.
- Implemented `P2719R4 Type-aware allocation and deallocation functions <https://wg21.link/P2719>`_.
+ This is enabled by default when targeting C++2c, and can be enabled or disabled by
+ the ``-fcxx-type-aware-allocators`` and ``-fno-cxx-type-aware-allocators`` options.
C++23 Feature Support
^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index e5a7cdc14a737..eb28f0ce9c8fd 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9956,6 +9956,9 @@ def warn_cxx26_type_aware_allocators : Warning<
def err_type_aware_allocator_missing_matching_operator : Error<
"declaration of type aware %0 in %1 must have matching type aware %2"
>;
+def err_type_aware_allocators_disabled
+ : Error<"type aware %0 declared but type aware allocator support is "
+ "disabled. Pass -fcxx-type-aware-allocators to enable it">;
def note_unmatched_type_aware_allocator_declared : Note<
"unmatched type aware %0 declared here">;
def err_mismatching_type_aware_cleanup_deallocator : Error<
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index 930c1c06d1a76..7dc817119c9ac 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -314,6 +314,7 @@ LANGOPT(SizedDeallocation , 1, 0, "sized deallocation")
LANGOPT(AlignedAllocation , 1, 0, "aligned allocation")
LANGOPT(AlignedAllocationUnavailable, 1, 0, "aligned allocation functions are unavailable")
LANGOPT(NewAlignOverride , 32, 0, "maximum alignment guaranteed by '::operator new(size_t)'")
+LANGOPT(CXXTypeAwareAllocators, 1, 0, "type aware allocators")
BENIGN_LANGOPT(ModulesCodegen , 1, 0, "Modules code generation")
BENIGN_LANGOPT(ModulesDebugInfo , 1, 0, "Modules debug info")
BENIGN_LANGOPT(ElideConstructors , 1, 1, "C++ copy constructor elision")
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 736088a70d189..cea63f2636152 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3539,6 +3539,12 @@ def : Separate<["-"], "fnew-alignment">, Alias<fnew_alignment_EQ>;
def : Flag<["-"], "faligned-new">, Alias<faligned_allocation>;
def : Flag<["-"], "fno-aligned-new">, Alias<fno_aligned_allocation>;
def faligned_new_EQ : Joined<["-"], "faligned-new=">;
+defm cxx_type_aware_allocators
+ : BoolFOption<"cxx-type-aware-allocators",
+ LangOpts<"CXXTypeAwareAllocators">, Default<cpp26.KeyPath>,
+ PosFlag<SetTrue, [], [],
+ "Enable support for C++26's type aware allocators">,
+ NegFlag<SetFalse>, BothFlags<[], [ClangOption, CC1Option]>>;
def fobjc_legacy_dispatch : Flag<["-"], "fobjc-legacy-dispatch">, Group<f_Group>;
def fobjc_new_property : Flag<["-"], "fobjc-new-property">, Group<clang_ignored_f_Group>;
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp
index 3e8c42d5a6f4b..eaa513313e182 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/lib/CodeGen/CGExprCXX.cpp
@@ -1487,6 +1487,7 @@ namespace {
TypeAwareAllocationMode TypeAwareDeallocation =
TypeAwareAllocationMode::No;
if (OperatorDelete->isTypeAwareOperatorNewOrDelete()) {
+ assert(CGF.getLangOpts().CXXTypeAwareAllocators);
TypeAwareDeallocation = TypeAwareAllocationMode::Yes;
QualType SpecializedTypeIdentity = FPT->getParamType(0);
++FirstNonTypeArg;
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 6dabf9d842b7b..d2788a0973ed4 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -7516,6 +7516,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.addLastArg(CmdArgs, options::OPT_fsized_deallocation,
options::OPT_fno_sized_deallocation);
+ // -fcxx-type-aware-allocators is on by default in C++26 onwards and otherwise
+ // off by default.
+ Args.addLastArg(CmdArgs, options::OPT_fcxx_type_aware_allocators,
+ options::OPT_fno_cxx_type_aware_allocators);
+
// -faligned-allocation is on by default in C++17 onwards and otherwise off
// by default.
if (Arg *A = Args.getLastArg(options::OPT_faligned_allocation,
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index 1f297f228fc1b..6d95c7d0e4c4e 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -778,7 +778,8 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts,
Builder.defineMacro("__cpp_impl_destroying_delete", "201806L");
// TODO: Final number?
- Builder.defineMacro("__cpp_type_aware_allocators", "202500L");
+ if (LangOpts.CXXTypeAwareAllocators)
+ Builder.defineMacro("__cpp_type_aware_allocators", "202500L");
}
/// InitializeOpenCLFeatureTestMacros - Define OpenCL macros based on target
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 22e21524c54be..a574508e18a05 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -7326,47 +7326,50 @@ void Sema::CheckCompletedCXXClass(Scope *S, CXXRecordDecl *Record) {
checkCUDADeviceBuiltinTextureClassTemplate(*this, Record);
}
- llvm::SmallDenseMap<OverloadedOperatorKind,
- llvm::SmallVector<const FunctionDecl *, 2>, 4>
- TypeAwareDecls{{OO_New, {}},
- {OO_Array_New, {}},
- {OO_Delete, {}},
- {OO_Array_New, {}}};
- for (auto *D : Record->decls()) {
- const FunctionDecl *FnDecl = D->getAsFunction();
- if (!FnDecl || !FnDecl->isTypeAwareOperatorNewOrDelete())
- continue;
- assert(FnDecl->getDeclName().isAnyOperatorNewOrDelete());
- TypeAwareDecls[FnDecl->getOverloadedOperator()].push_back(FnDecl);
- }
- auto CheckMismatchedTypeAwareAllocators =
- [this, &TypeAwareDecls, Record](OverloadedOperatorKind NewKind,
- OverloadedOperatorKind DeleteKind) {
- auto &NewDecls = TypeAwareDecls[NewKind];
- auto &DeleteDecls = TypeAwareDecls[DeleteKind];
- if (NewDecls.empty() == DeleteDecls.empty())
- return;
- DeclarationName FoundOperator =
- Context.DeclarationNames.getCXXOperatorName(
- NewDecls.empty() ? DeleteKind : NewKind);
- DeclarationName MissingOperator =
- Context.DeclarationNames.getCXXOperatorName(
- NewDecls.empty() ? NewKind : DeleteKind);
- Diag(Record->getLocation(),
- diag::err_type_aware_allocator_missing_matching_operator)
- << FoundOperator << Context.getRecordType(Record)
- << MissingOperator;
- for (auto MD : NewDecls)
- Diag(MD->getLocation(),
- diag::note_unmatched_type_aware_allocator_declared)
- << MD;
- for (auto MD : DeleteDecls)
- Diag(MD->getLocation(),
- diag::note_unmatched_type_aware_allocator_declared)
- << MD;
- };
- CheckMismatchedTypeAwareAllocators(OO_New, OO_Delete);
- CheckMismatchedTypeAwareAllocators(OO_Array_New, OO_Array_Delete);
+ if (getLangOpts().CXXTypeAwareAllocators) {
+ llvm::SmallDenseMap<OverloadedOperatorKind,
+ llvm::SmallVector<const FunctionDecl *, 2>, 4>
+ TypeAwareDecls{{OO_New, {}},
+ {OO_Array_New, {}},
+ {OO_Delete, {}},
+ {OO_Array_New, {}}};
+ for (auto *D : Record->decls()) {
+ const FunctionDecl *FnDecl = D->getAsFunction();
+ if (!FnDecl || !FnDecl->isTypeAwareOperatorNewOrDelete())
+ continue;
+ assert(FnDecl->getDeclName().isAnyOperatorNewOrDelete());
+ TypeAwareDecls[FnDecl->getOverloadedOperator()].push_back(FnDecl);
+ }
+
+ auto CheckMismatchedTypeAwareAllocators =
+ [this, &TypeAwareDecls, Record](OverloadedOperatorKind NewKind,
+ OverloadedOperatorKind DeleteKind) {
+ auto &NewDecls = TypeAwareDecls[NewKind];
+ auto &DeleteDecls = TypeAwareDecls[DeleteKind];
+ if (NewDecls.empty() == DeleteDecls.empty())
+ return;
+ DeclarationName FoundOperator =
+ Context.DeclarationNames.getCXXOperatorName(
+ NewDecls.empty() ? DeleteKind : NewKind);
+ DeclarationName MissingOperator =
+ Context.DeclarationNames.getCXXOperatorName(
+ NewDecls.empty() ? NewKind : DeleteKind);
+ Diag(Record->getLocation(),
+ diag::err_type_aware_allocator_missing_matching_operator)
+ << FoundOperator << Context.getRecordType(Record)
+ << MissingOperator;
+ for (auto MD : NewDecls)
+ Diag(MD->getLocation(),
+ diag::note_unmatched_type_aware_allocator_declared)
+ << MD;
+ for (auto MD : DeleteDecls)
+ Diag(MD->getLocation(),
+ diag::note_unmatched_type_aware_allocator_declared)
+ << MD;
+ };
+ CheckMismatchedTypeAwareAllocators(OO_New, OO_Delete);
+ CheckMismatchedTypeAwareAllocators(OO_Array_New, OO_Array_Delete);
+ }
}
/// Look up the special member function that would be called by a special
@@ -16439,7 +16442,8 @@ bool Sema::CompleteConstructorCall(CXXConstructorDecl *Constructor,
TypeAwareAllocationMode Sema::ShouldUseTypeAwareOperatorNewOrDelete() const {
bool SeenTypedOperators = Context.hasSeenTypeAwareOperatorNewOrDelete();
- return typeAwareAllocationModeFromBool(SeenTypedOperators);
+ return typeAwareAllocationModeFromBool(getLangOpts().CXXTypeAwareAllocators &&
+ SeenTypedOperators);
}
FunctionDecl *
@@ -16587,6 +16591,11 @@ static inline bool CheckOperatorNewDeleteTypes(
unsigned MinimumMandatoryArgumentCount = 1;
unsigned SizeParameterIndex = 0;
if (IsPotentiallyTypeAware) {
+ if (!SemaRef.getLangOpts().CXXTypeAwareAllocators)
+ return SemaRef.Diag(FnDecl->getLocation(),
+ diag::err_type_aware_allocators_disabled)
+ << FnDecl->getDeclName();
+
// We don't emit this diagnosis for template instantiations as we will
// have already emitted it for the original template declaration.
if (!FnDecl->isTemplateInstantiation()) {
@@ -16699,7 +16708,7 @@ static inline bool CheckOperatorNewDeleteTypes(
return true;
FnDecl->setIsTypeAwareOperatorNewOrDelete();
- return MalformedTypeIdentity;
+ return MalformedTypeIdentity || !SemaRef.getLangOpts().CXXTypeAwareAllocators;
}
static bool CheckOperatorNewDeclaration(Sema &SemaRef, FunctionDecl *FnDecl) {
@@ -16746,6 +16755,10 @@ CheckOperatorDeleteDeclaration(Sema &SemaRef, FunctionDecl *FnDecl) {
// pile of incorrect parameter type errors.
if (MD && IsPotentiallyTypeAwareOperatorNewOrDelete(
SemaRef, MD, /*WasMalformed=*/nullptr)) {
+ if (!SemaRef.getLangOpts().CXXTypeAwareAllocators)
+ return SemaRef.Diag(FnDecl->getLocation(),
+ diag::err_type_aware_allocators_disabled)
+ << FnDecl->getDeclName();
QualType AddressParamType =
SemaRef.Context.getCanonicalType(MD->getParamDecl(1)->getType());
if (AddressParamType != SemaRef.Context.VoidPtrTy &&
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 235ea1529b0b8..ee01411729cd8 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -1768,7 +1768,7 @@ namespace {
// A function template declaration is only a usual deallocation function
// if it is a typed delete.
if (!FD) {
- if (AllocType.isNull())
+ if (AllocType.isNull() || !S.getLangOpts().CXXTypeAwareAllocators)
return;
auto *FTD = dyn_cast<FunctionTemplateDecl>(Found->getUnderlyingDecl());
if (!FTD)
@@ -1786,7 +1786,7 @@ namespace {
// type being deallocated, or if the type-identity parameter of the
// deallocation function does not match the constructed type_identity
// specialization we reject the declaration.
- if (AllocType.isNull()) {
+ if (AllocType.isNull() || !S.getLangOpts().CXXTypeAwareAllocators) {
FD = nullptr;
return;
}
diff --git a/clang/test/CodeGenCXX/type-aware-allocators.cpp b/clang/test/CodeGenCXX/type-aware-allocators.cpp
index cce9197ed0d12..7b49f1537db8a 100644
--- a/clang/test/CodeGenCXX/type-aware-allocators.cpp
+++ b/clang/test/CodeGenCXX/type-aware-allocators.cpp
@@ -1,14 +1,14 @@
-// RUN: %clang_cc1 %s -triple arm64-apple-macosx -fsized-deallocation -faligned-allocation -emit-llvm -fcxx-exceptions -fexceptions -std=c++23 -o - -Wno-c++26-extensions | FileCheck --check-prefixes=CHECK,CHECK_SIZED_ALIGNED %s
-// RUN: %clang_cc1 %s -triple arm64-apple-macosx -fno-sized-deallocation -faligned-allocation -emit-llvm -fcxx-exceptions -fexceptions -std=c++23 -o - -Wno-c++26-extensions | FileCheck --check-prefixes=CHECK,CHECK_NO_SIZE_ALIGNED %s
-// RUN: %clang_cc1 %s -triple arm64-apple-macosx -fno-sized-deallocation -fno-aligned-allocation -emit-llvm -fcxx-exceptions -fexceptions -std=c++23 -o - -Wno-c++26-extensions | FileCheck --check-prefixes=CHECK,CHECK_NO_SIZE_NO_ALIGN %s
-// RUN: %clang_cc1 %s -triple arm64-apple-macosx -fsized-deallocation -fno-aligned-allocation -emit-llvm -fcxx-exceptions -fexceptions -std=c++23 -o - -Wno-c++26-extensions | FileCheck --check-prefixes=CHECK,CHECK_SIZED_NO_ALIGN %s
+// RUN: %clang_cc1 %s -triple arm64-apple-macosx -fcxx-type-aware-allocators -fsized-deallocation -faligned-allocation -emit-llvm -fcxx-exceptions -fexceptions -std=c++23 -o - -Wno-c++26-extensions | FileCheck --check-prefixes=CHECK,CHECK_SIZED_ALIGNED %s
+// RUN: %clang_cc1 %s -triple arm64-apple-macosx -fcxx-type-aware-allocators -fno-sized-deallocation -faligned-allocation -emit-llvm -fcxx-exceptions -fexceptions -std=c++23 -o - -Wno-c++26-extensions | FileCheck --check-prefixes=CHECK,CHECK_NO_SIZE_ALIGNED %s
+// RUN: %clang_cc1 %s -triple arm64-apple-macosx -fcxx-type-aware-allocators -fno-sized-deallocation -fno-aligned-allocation -emit-llvm -fcxx-exceptions -fexceptions -std=c++23 -o - -Wno-c++26-extensions | FileCheck --check-prefixes=CHECK,CHECK_NO_SIZE_NO_ALIGN %s
+// RUN: %clang_cc1 %s -triple arm64-apple-macosx -fcxx-type-aware-allocators -fsized-deallocation -fno-aligned-allocation -emit-llvm -fcxx-exceptions -fexceptions -std=c++23 -o - -Wno-c++26-extensions | FileCheck --check-prefixes=CHECK,CHECK_SIZED_NO_ALIGN %s
+
// Test default behaviour with c++26
// RUN: %clang_cc1 %s -triple arm64-apple-macosx -fsized-deallocation -faligned-allocation -emit-llvm -fcxx-exceptions -fexceptions -std=c++26 -o - | FileCheck --check-prefixes=CHECK,CHECK_SIZED_ALIGNED %s
// RUN: %clang_cc1 %s -triple arm64-apple-macosx -fno-sized-deallocation -faligned-allocation -emit-llvm -fcxx-exceptions -fexceptions -std=c++26 -o - | FileCheck --check-prefixes=CHECK,CHECK_NO_SIZE_ALIGNED %s
// RUN: %clang_cc1 %s -triple arm64-apple-macosx -fno-sized-deallocation -fno-aligned-allocation -emit-llvm -fcxx-exceptions -fexceptions -std=c++26 -o - | FileCheck --check-prefixes=CHECK,CHECK_NO_SIZE_NO_ALIGN %s
// RUN: %clang_cc1 %s -triple arm64-apple-macosx -fsized-deallocation -fno-aligned-allocation -emit-llvm -fcxx-exceptions -fexceptions -std=c++26 -o - | FileCheck --check-prefixes=CHECK,CHECK_SIZED_NO_ALIGN %s
-
namespace std {
template <class T> struct type_identity {
typedef T type;
diff --git a/clang/test/CodeGenCXX/type-aware-coroutines.cpp b/clang/test/CodeGenCXX/type-aware-coroutines.cpp
index 0a19079d987e9..5ac314dbb5e2f 100644
--- a/clang/test/CodeGenCXX/type-aware-coroutines.cpp
+++ b/clang/test/CodeGenCXX/type-aware-coroutines.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple arm64-apple-macosx %s -std=c++23 -fcoroutines -fexceptions -emit-llvm -Wno-coro-type-aware-allocation-function -o - | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-apple-macosx %s -std=c++23 -fcxx-type-aware-allocators -fcoroutines -fexceptions -emit-llvm -Wno-coro-type-aware-allocation-function -o - | FileCheck %s
// RUN: %clang_cc1 -triple arm64-apple-macosx %s -std=c++26 -fcoroutines -fexceptions -emit-llvm -Wno-coro-type-aware-allocation-function -o - | FileCheck %s
#include "Inputs/std-coroutine.h"
diff --git a/clang/test/CodeGenCXX/type-aware-placement-operators.cpp b/clang/test/CodeGenCXX/type-aware-placement-operators.cpp
index 858db62ffcfb0..ec34b1077b749 100644
--- a/clang/test/CodeGenCXX/type-aware-placement-operators.cpp
+++ b/clang/test/CodeGenCXX/type-aware-placement-operators.cpp
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 %s -triple arm64-apple-macosx -emit-llvm -fcxx-exceptions -fexceptions -std=c++23 -fsized-deallocation -faligned-allocation -o - | FileCheck %s
-// RUN: %clang_cc1 %s -triple arm64-apple-macosx -emit-llvm -fcxx-exceptions -fexceptions -std=c++23 -fno-sized-deallocation -faligned-allocation -o - | FileCheck %s
-// RUN: %clang_cc1 %s -triple arm64-apple-macosx -emit-llvm -fcxx-exceptions -fexceptions -std=c++23 -fsized-deallocation -fno-aligned-allocation -o - | FileCheck %s
-// RUN: %clang_cc1 %s -triple arm64-apple-macosx -emit-llvm -fcxx-exceptions -fexceptions -std=c++23 -fno-aligned-allocation -fno-sized-deallocation -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple arm64-apple-macosx -emit-llvm -fcxx-exceptions -fexceptions -std=c++23 -fcxx-type-aware-allocators -fsized-deallocation -faligned-allocation -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple arm64-apple-macosx -emit-llvm -fcxx-exceptions -fexceptions -std=c++23 -fcxx-type-aware-allocators -fno-sized-deallocation -faligned-allocation -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple arm64-apple-macosx -emit-llvm -fcxx-exceptions -fexceptions -std=c++23 -fcxx-type-aware-allocators -fsized-deallocation -fno-aligned-allocation -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple arm64-apple-macosx -emit-llvm -fcxx-exceptions -fexceptions -std=c++23 -fcxx-type-aware-allocators -fno-aligned-allocation -fno-sized-deallocation -o - | FileCheck %s
namespace std {
template <class T> struct type_identity {};
diff --git a/clang/test/PCH/type-aware-destroying-new-and-delete-pch.cpp b/clang/test/PCH/type-aware-destroying-new-and-delete-pch.cpp
index d8f7f5dd50c78..b542b03b8b4fb 100644
--- a/clang/test/PCH/type-aware-destroying-new-and-delete-pch.cpp
+++ b/clang/test/PCH/type-aware-destroying-new-and-delete-pch.cpp
@@ -5,8 +5,8 @@
// RUN: %clang_cc1 -x c++ -std=c++26 -emit-pch -o %t %S/Inputs/type_aware_destroying_new_delete.h
// RUN: %clang_cc1 -x c++ -std=c++26 -include-pch %t -emit-llvm -o - %s
-// RUN: %clang_cc1 -x c++ -std=c++11 -emit-pch -fpch-instantiate-templates -o %t %S/Inputs/type_aware_destroying_new_delete.h
-// RUN: %clang_cc1 -x c++ -std=c++11 -include-pch %t -emit-llvm -o - %s
+// RUN: %clang_cc1 -x c++ -std=c++11 -fcxx-type-aware-allocators -emit-pch -fpch-instantiate-templates -o %t %S/Inputs/type_aware_destroying_new_delete.h
+// RUN: %clang_cc1 -x c++ -std=c++11 -fcxx-type-aware-allocators -include-pch %t -emit-llvm -o - %s
static void call_in_pch_function(void) {
diff --git a/clang/test/SemaCXX/type-aware-coroutines.cpp b/clang/test/SemaCXX/type-aware-coroutines.cpp
index a54d37c47dbd9..3ec3d3953db45 100644
--- a/clang/test/SemaCXX/type-aware-coroutines.cpp
+++ b/clang/test/SemaCXX/type-aware-coroutines.cpp
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -triple arm64-apple-macosx -fsyntax-only -verify %s -std=c++26 -fcoroutines -fexceptions -Wall -Wpedantic
+// RUN: %clang_cc1 -triple arm64-apple-macosx -fsyntax-only -verify %s -std=c++26 -fcoroutines -fexceptions -Wall -Wpedantic
+// Type aware allocators disabled
+// RUN: %clang_cc1 -triple arm64-apple-macosx -fsyntax-only -verify=no_type_aware %s -std=c++26 -fcoroutines -fno-cxx-type-aware-allocators -fexceptions -Wall -Wpedantic
#include "Inputs/std-coroutine.h"
@@ -16,9 +18,13 @@ struct Allocator {};
struct resumable {
struct promise_type {
void *operator new(std::type_identity<promise_type>, std::size_t sz, std::align_val_t, int); // #resumable_tan1
+ // no_type_aware-error at -1 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
void *operator new(std::type_identity<promise_type>, std::size_t sz, std::align_val_t, float); // #resumable_tan2
+ // no_type_aware-error at -1 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
void operator delete(std::type_identity<promise_type>, void *, std::size_t sz, std::align_val_t); // #resumable_tad1
+ // no_type_aware-error at -1 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <typename T> void operator delete(std::type_identity<T>, void *, std::size_t sz, std::align_val_t) = delete; // #resumable_tad2
+ // no_type_aware-error at -1 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
resumable get_return_object() { return {}; }
auto initial_suspend() { return std::suspend_always(); }
@@ -32,7 +38,9 @@ struct resumable {
struct resumable2 {
struct promise_type {
template <typename... Args> void *operator new(std::type_identity<promise_type>, std::size_t sz, std::align_val_t, Args...); // #resumable2_tan1
+ // no_type_aware-error at -1 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
void operator delete(std::type_identity<promise_type>, void *, std::size_t sz, std::align_val_t); // #resumable2_tad2
+ // no_type_aware-error at -1 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
resumable2 get_return_object() { return {}; }
auto initial_suspend() { return std::suspend_always(); }
@@ -50,6 +58,7 @@ struct resumable3 {
// expected-note@#resumable3_tan {{unmatched type aware 'operator new' declared here}}
void *operator new(std::size_t sz, float);
void *operator new(std::type_identity<promise_type>, std::size_t sz, std::align_val_t, float); // #resumable3_tan
+ // no_type_aware-error at -1 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
void operator delete(void *);
resumable3 get_return_object() { return {}; }
@@ -66,6 +75,7 @@ struct resumable4 {
// expected-note@#resumable4_tad {{unmatched type aware 'operator delete' declared here}}
void *operator new(std::size_t sz, float);
template <typename T> void operator delete(std::type_identity<T>, void *, std::size_t, std::align_val_t); // #resumable4_tad
+ // no_type_aware-error at -1 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
resumable4 get_return_object() { return {}; }
auto initial_suspend() { return std::suspend_always(); }
@@ -82,6 +92,7 @@ struct resumable5 {
void *operator new(std::size_t sz, float);
void operator delete(void *);
template <typename T> void operator delete(std::type_identity<T>, void *, std::size_t, std::align_val_t); // #resumable5_tad
+ // no_type_aware-error at -1 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
resumable5 get_return_object() { return {}; }
auto initial_suspend() { return std::suspend_always(); }
@@ -97,6 +108,7 @@ resumable f1(int) {
// expected-note at -2 {{type aware 'operator new' will not be used for coroutine allocation}}
// expected-note@#resumable_tan1 {{type aware 'operator new' declared here}}
// expected-note@#resumable_tan2 {{type aware 'operator new' declared here}}
+ // no_type_aware-error at -5 {{'operator new' provided by 'std::coroutine_traits<resumable, int>::promise_type' (aka 'resumable::promise_type') is not usable with the function signature of 'f1'}}
co_return;
}
@@ -105,6 +117,7 @@ resumable f2(float) {
// expected-note at -2 {{type aware 'operator new' will not be used for coroutine allocation}}
// expected-note@#resumable_tan1 {{type aware 'operator new' declared here}}
// expected-note@#resumable_tan2 {{type aware 'operator new' declared here}}
+ // no_type_aware-error at -5 {{'operator new' provided by 'std::coroutine_traits<resumable, float>::promise_type' (aka 'resumable::promise_type') is not usable with the function signature of 'f2'}}
co_return;
}
@@ -112,6 +125,7 @@ resumable2 f3(int, float, const char*, Allocator) {
// expected-error at -1 {{'operator new' provided by 'std::coroutine_traits<resumable2, int, float, const char *, Allocator>::promise_type' (aka 'resumable2::promise_type') is not usable with the function signature of 'f3'}}
// expected-note at -2 {{type aware 'operator new' will not be used for coroutine allocation}}
// expected-note@#resumable2_tan1 {{type aware 'operator new' declared here}}
+ // no_type_aware-error at -4 {{'operator new' provided by 'std::coroutine_traits<resumable2, int, float, const char *, Allocator>::promise_type' (aka 'resumable2::promise_type') is not usable with the function signature of 'f3'}}
co_yield 1;
co_return;
}
@@ -121,6 +135,7 @@ resumable f4(int n = 10) {
// expected-note at -2 {{type aware 'operator new' will not be used for coroutine allocation}}
// expected-note@#resumable_tan1 {{type aware 'operator new' declared here}}
// expected-note@#resumable_tan2 {{type aware 'operator new' declared here}}
+ // no_type_aware-error at -5 {{'operator new' provided by 'std::coroutine_traits<resumable, int>::promise_type' (aka 'resumable::promise_type') is not usable with the function signature of 'f4'}}
for (int i = 0; i < n; i++)
co_yield i;
}
@@ -135,6 +150,8 @@ resumable4 f6(float) {
// expected-warning at -2 {{type aware 'operator delete' will not be used for coroutine allocation}}
// expected-note@#resumable4_tad {{type aware 'operator delete' declared here}}
// expected-note@#resumable4_tad {{member 'operator delete' declared here}}
+ // no_type_aware-error at -5 {{no suitable member 'operator delete' in 'promise_type'}}
+ // no_type_aware-note@#resumable4_tad {{member 'operator delete' declared here}}
co_return;
}
diff --git a/clang/test/SemaCXX/type-aware-new-delete-basic-free-declarations.cpp b/clang/test/SemaCXX/type-aware-new-delete-basic-free-declarations.cpp
index c85b92718479a..8cdcac3b05907 100644
--- a/clang/test/SemaCXX/type-aware-new-delete-basic-free-declarations.cpp
+++ b/clang/test/SemaCXX/type-aware-new-delete-basic-free-declarations.cpp
@@ -1,7 +1,18 @@
-// RUN: %clang_cc1 -triple arm64-apple-macosx -fsyntax-only -verify %s -std=c++26 -fsized-deallocation -faligned-allocation
-// RUN: %clang_cc1 -triple arm64-apple-macosx -fsyntax-only -verify %s -std=c++26 -fno-sized-deallocation -faligned-allocation
-// RUN: %clang_cc1 -triple arm64-apple-macosx -fsyntax-only -verify %s -std=c++26 -fno-sized-deallocation -fno-aligned-allocation
-// RUN: %clang_cc1 -triple arm64-apple-macosx -fsyntax-only -verify %s -std=c++26 -fsized-deallocation -fno-aligned-allocation
+// RUN: %clang_cc1 -triple arm64-apple-macosx -fsyntax-only -verify=expected,both %s -std=c++26 -fsized-deallocation -faligned-allocation
+// RUN: %clang_cc1 -triple arm64-apple-macosx -fsyntax-only -verify=expected,both %s -std=c++26 -fno-sized-deallocation -faligned-allocation
+// RUN: %clang_cc1 -triple arm64-apple-macosx -fsyntax-only -verify=expected,both %s -std=c++26 -fno-sized-deallocation -fno-aligned-allocation
+// RUN: %clang_cc1 -triple arm64-apple-macosx -fsyntax-only -verify=expected,both %s -std=c++26 -fsized-deallocation -fno-aligned-allocation
+// RUN: %clang_cc1 -triple arm64-apple-macosx -fsyntax-only -verify=no_taa_disabled,both %s -std=c++26 -fno-cxx-type-aware-allocators -DNO_TYPE_AWARE_ALLOCATORS
+
+#ifdef NO_TYPE_AWARE_ALLOCATORS
+#ifdef __cpp_type_aware_allocators
+#error __cpp_type_aware_allocators erroneously defined
+#endif
+#else
+#ifndef __cpp_type_aware_allocators
+#error __cpp_type_aware_allocators should be defined
+#endif
+#endif
namespace std {
template <class T> struct type_identity {};
@@ -16,32 +27,46 @@ template <typename T> struct TemplateTestType {};
// Valid free declarations
void *operator new(std::type_identity<int>, size_t, std::align_val_t); // #1
+// no_taa_disabled-error at -1 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
void *operator new(std::type_identity<int>, size_t, std::align_val_t, TestType&); // #2
+// no_taa_disabled-error at -1 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <typename T> void *operator new(std::type_identity<T>, size_t, std::align_val_t); // #3
+// no_taa_disabled-error at -1 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <typename T> void *operator new(std::type_identity<T>, size_t, std::align_val_t, TestType&); // #4
+// no_taa_disabled-error at -1 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <typename T> void *operator new(std::type_identity<TemplateTestType<T>>, size_t, std::align_val_t, TestType&); // #5
+// no_taa_disabled-error at -1 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <typename T, typename U> void *operator new(std::type_identity<T>, size_t, std::align_val_t, TemplateTestType<U>&); // #6
+// no_taa_disabled-error at -1 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <template <typename> class T> void *operator new(std::type_identity<T<int>>, size_t, std::align_val_t); // #7
+// no_taa_disabled-error at -1 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
void operator delete(std::type_identity<int>, void *, size_t, std::align_val_t); // #8
+// no_taa_disabled-error at -1 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <typename T> void operator delete(std::type_identity<T>, void *, size_t, std::align_val_t); // #9
+// no_taa_disabled-error at -1 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <typename T> void operator delete(std::type_identity<TemplateTestType<T>>, void *, size_t, std::align_val_t); // #10
+// no_taa_disabled-error at -1 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <template <typename> class T> void operator delete(std::type_identity<T<int>>, void *, size_t, std::align_val_t); // #11
+// no_taa_disabled-error at -1 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
typedef std::type_identity<float> TypeIdentityAlias1;
void *operator new(TypeIdentityAlias1, size_t, std::align_val_t); // #12
+// no_taa_disabled-error at -1 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
using TypeIdentityAlias2 = std::type_identity<double>;
void *operator new(TypeIdentityAlias2, size_t, std::align_val_t); // #13
+// no_taa_disabled-error at -1 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <typename T> using TypeIdentityAlias3 = std::type_identity<T>;
template <typename T> void *operator new(TypeIdentityAlias3<T>, size_t, std::align_val_t); // #14
+// no_taa_disabled-error at -1 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <typename T> void *operator new(T, size_t, std::align_val_t);
-// expected-error at -1 {{'operator new' cannot take a dependent type as its 1st parameter}}
+// both-error at -1 {{'operator new' cannot take a dependent type as its 1st parameter}}
template <typename T> void operator delete(T, void*, size_t, std::align_val_t);
-// expected-error at -1 {{'operator delete' cannot take a dependent type as its 1st parameter}}
+// both-error at -1 {{'operator delete' cannot take a dependent type as its 1st parameter}}
template <typename T> struct S {
typedef std::type_identity<T> type_identity;
@@ -51,43 +76,60 @@ template <typename T> struct S {
};
template <typename T> void *operator new(typename S<T>::type_identity, size_t, std::align_val_t);
-// expected-error at -1 {{'operator new' cannot take a dependent type as its 1st parameter}}
+// both-error at -1 {{'operator new' cannot take a dependent type as its 1st parameter}}
// Invalid type aware declarations
void *operator new(std::type_identity<int>, size_t);
// expected-error at -1 {{type aware 'operator new' must have at least three parameters}}
+// no_taa_disabled-error at -2 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
void *operator new(std::type_identity<int>, size_t, TestType&);
// expected-error at -1 {{type aware 'operator new' takes type std::align_val_t ('std::align_val_t') as 3rd parameter}}
+// no_taa_disabled-error at -2 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
void operator delete(std::type_identity<int>, void *);
// expected-error at -1 {{type aware 'operator delete' must have at least four parameters}}
+// no_taa_disabled-error at -2 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
void operator delete(std::type_identity<int>, void *, size_t);
// expected-error at -1 {{type aware 'operator delete' must have at least four parameters}}
+// no_taa_disabled-error at -2 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
void operator delete(std::type_identity<int>, void *, std::align_val_t);
// expected-error at -1 {{type aware 'operator delete' must have at least four parameters}}
+// no_taa_disabled-error at -2 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <typename T> void operator delete(std::type_identity<T>, void *);
// expected-error at -1 {{type aware 'operator delete' must have at least four parameters}}
+// no_taa_disabled-error at -2 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <typename T> void operator delete(std::type_identity<T>, void *, std::align_val_t);
// expected-error at -1 {{type aware 'operator delete' must have at least four parameters}}
+// no_taa_disabled-error at -2 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <typename T> void operator delete(std::type_identity<T>, void *, size_t);
// expected-error at -1 {{type aware 'operator delete' must have at least four parameters}}
+// no_taa_disabled-error at -2 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <typename T, typename U> void *operator new(std::type_identity<T>, U);
// expected-error at -1 {{type aware 'operator new' must have at least three parameters}}
+// no_taa_disabled-error at -2 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <typename T, typename U> void operator delete(std::type_identity<T>, U, size_t, std::align_val_t);
// expected-error at -1 {{type aware 'operator delete' cannot take a dependent type as its 2nd parameter; use 'void *' instead}}
+// no_taa_disabled-error at -2 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <typename T, typename U> void operator delete(std::type_identity<T>, void *, U, std::align_val_t);
// expected-error at -1 {{type aware 'operator delete' cannot take a dependent type as its 3rd parameter; use 'unsigned long' instead}}
+// no_taa_disabled-error at -2 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <typename T, typename U> void operator delete(std::type_identity<T>, void *, size_t, U);
// expected-error at -1 {{type aware 'operator delete' cannot take a dependent type as its 4th parameter; use 'std::align_val_t' instead}}
+// no_taa_disabled-error at -2 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <typename U> void *operator new(std::type_identity<int>, typename S<U>::size_ty, std::align_val_t);
// expected-error at -1 {{type aware 'operator new' cannot take a dependent type as its 2nd parameter; use size_t ('unsigned long') instead}}
+// no_taa_disabled-error at -2 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <typename U> void operator delete(std::type_identity<int>, typename S<U>::ptr_ty, size_t, std::align_val_t);
// expected-error at -1 {{type aware 'operator delete' cannot take a dependent type as its 2nd parameter; use 'void *' instead}}
+// no_taa_disabled-error at -2 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <typename T, typename U> void *operator new(std::type_identity<T>, typename S<U>::size_ty, std::align_val_t);
// expected-error at -1 {{type aware 'operator new' cannot take a dependent type as its 2nd parameter; use size_t ('unsigned long') instead}}
+// no_taa_disabled-error at -2 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <typename T, typename U> void operator delete(std::type_identity<T>, typename S<U>::ptr_ty, size_t, std::align_val_t);
// expected-error at -1 {{type aware 'operator delete' cannot take a dependent type as its 2nd parameter; use 'void *' instead}}
+// no_taa_disabled-error at -2 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <typename T, typename U> void operator delete(std::type_identity<T>, void *, size_t, typename S<U>::align_val_ty);
// expected-error at -1 {{type aware 'operator delete' cannot take a dependent type as its 4th parameter; use 'std::align_val_t' instead}}
+// no_taa_disabled-error at -2 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <typename T> using Alias = T;
template <typename T> using TypeIdentityAlias = std::type_identity<T>;
@@ -95,25 +137,43 @@ typedef std::type_identity<double> TypedefAlias;
using UsingAlias = std::type_identity<float>;
void *operator new(Alias<size_t>, std::align_val_t);
template <typename T> void *operator new(Alias<std::type_identity<T>>, Alias<size_t>, std::align_val_t);
+// no_taa_disabled-error at -1 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
void *operator new(Alias<std::type_identity<int>>, size_t, std::align_val_t);
+// no_taa_disabled-error at -1 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <typename T> void operator delete(Alias<std::type_identity<T>>, void *, size_t, std::align_val_t);
+// no_taa_disabled-error at -1 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
void operator delete(Alias<std::type_identity<int>>, void *, size_t, std::align_val_t);
+// no_taa_disabled-error at -1 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <typename T> void *operator new(TypeIdentityAlias<T>, size_t, std::align_val_t);
+// no_taa_disabled-error at -1 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
void *operator new(TypeIdentityAlias<int>, size_t, std::align_val_t);
+// no_taa_disabled-error at -1 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <typename T> void operator delete(TypeIdentityAlias<T>, void *, size_t, std::align_val_t);
+// no_taa_disabled-error at -1 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
void operator delete(TypeIdentityAlias<int>, void *, size_t, std::align_val_t);
+// no_taa_disabled-error at -1 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <typename T> void *operator new(TypedefAlias, size_t, std::align_val_t);
+// no_taa_disabled-error at -1 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
void *operator new(TypedefAlias, size_t, std::align_val_t);
+// no_taa_disabled-error at -1 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <typename T> void operator delete(TypedefAlias, void *, size_t, std::align_val_t);
+// no_taa_disabled-error at -1 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
void operator delete(TypedefAlias, void *, size_t, std::align_val_t);
+// no_taa_disabled-error at -1 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <typename T> void *operator new(UsingAlias, size_t, std::align_val_t);
+// no_taa_disabled-error at -1 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
void *operator new(UsingAlias, size_t, std::align_val_t);
+// no_taa_disabled-error at -1 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <typename T> void operator delete(UsingAlias, void *, size_t, std::align_val_t);
+// no_taa_disabled-error at -1 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
void operator delete(UsingAlias, void *, size_t, std::align_val_t);
+// no_taa_disabled-error at -1 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
class ForwardDecl;
void *operator new(std::type_identity<ForwardDecl>, size_t, std::align_val_t);
+// no_taa_disabled-error at -1 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
void operator delete(std::type_identity<ForwardDecl>, void*, size_t, std::align_val_t);
+// no_taa_disabled-error at -1 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
diff --git a/clang/test/SemaCXX/type-aware-new-delete-basic-in-class-declarations.cpp b/clang/test/SemaCXX/type-aware-new-delete-basic-in-class-declarations.cpp
index 34bd1d4206be1..8db1e291b9ae0 100644
--- a/clang/test/SemaCXX/type-aware-new-delete-basic-in-class-declarations.cpp
+++ b/clang/test/SemaCXX/type-aware-new-delete-basic-in-class-declarations.cpp
@@ -1,6 +1,7 @@
-// RUN: %clang_cc1 -triple arm64-apple-macosx -fsyntax-only -verify=expected,precxx26 %s -std=c++23
+// RUN: %clang_cc1 -triple arm64-apple-macosx -fsyntax-only -verify=expected,precxx26 %s -std=c++23 -fcxx-type-aware-allocators
// RUN: %clang_cc1 -triple arm64-apple-macosx -fsyntax-only -verify %s -std=c++26
-
+// RUN: %clang_cc1 -triple arm64-apple-macosx -fsyntax-only -verify=no_type_aware %s -std=c++23 -Wno-c++26-extensions
+// RUN: %clang_cc1 -triple arm64-apple-macosx -fsyntax-only -verify=no_type_aware %s -std=c++26 -fno-cxx-type-aware-allocators
namespace std {
template <class T> struct type_identity {};
enum class align_val_t : __SIZE_TYPE__ {};
@@ -12,49 +13,61 @@ using size_t = __SIZE_TYPE__;
// Basic valid declarations
struct S {
void *operator new(std::type_identity<S>, size_t, std::align_val_t); // #1
+ // no_type_aware-error@#1 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
void operator delete(std::type_identity<S>, void *, size_t, std::align_val_t); // #2
// precxx26-warning@#1 {{type aware allocators are a C++2c extension}}
// precxx26-warning@#2 {{type aware allocators are a C++2c extension}}
+ // no_type_aware-error@#2 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
void operator delete(S *, std::destroying_delete_t);
};
template <typename T> struct S2 {
void *operator new(std::type_identity<S2<T>>, size_t, std::align_val_t); // #3
+ // no_type_aware-error@#3 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
void operator delete(std::type_identity<S2<T>>, void *, size_t, std::align_val_t); // #4
// precxx26-warning@#3 {{type aware allocators are a C++2c extension}}
// precxx26-warning@#4 {{type aware allocators are a C++2c extension}}
+ // no_type_aware-error@#4 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
void operator delete(S2 *, std::destroying_delete_t);
};
struct S3 {
template <typename T> void *operator new(std::type_identity<T>, size_t, std::align_val_t); // #5
+ // no_type_aware-error@#5 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <typename T> void operator delete(std::type_identity<T>, void *, size_t, std::align_val_t); // #6
// precxx26-warning@#5 {{type aware allocators are a C++2c extension}}
// precxx26-warning@#6 {{type aware allocators are a C++2c extension}}
+ // no_type_aware-error@#6 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
void operator delete(S3 *, std::destroying_delete_t);
};
struct S4 {
template <typename T> void *operator new(std::type_identity<T>, size_t, std::align_val_t); // #7
+ // no_type_aware-error@#7 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <typename T> void operator delete(std::type_identity<T>, void *, size_t, std::align_val_t); // #8
+ // no_type_aware-error@#8 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <typename T> void operator delete(std::type_identity<T>, S4 *, std::destroying_delete_t, size_t, std::align_val_t); // #9
// precxx26-warning@#7 {{type aware allocators are a C++2c extension}}
// precxx26-warning@#8 {{type aware allocators are a C++2c extension}}
// expected-error@#9 {{destroying delete is not permitted to be type aware}}
+ // no_type_aware-error@#9 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
};
struct S5 {
template <typename T> void operator delete(std::type_identity<T>, T *, size_t, std::align_val_t); // #10
// expected-error@#10 {{type aware 'operator delete' cannot take a dependent type as its 2nd parameter}}
+ // no_type_aware-error@#10 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
// precxx26-warning@#10 {{type aware allocators are a C++2c extension}}
};
struct S6 {
template <typename T> void *operator new(std::type_identity<S6>, T, std::align_val_t); // #11
// expected-error@#11 {{type aware 'operator new' cannot take a dependent type as its 2nd parameter}}
+ // no_type_aware-error@#11 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
// precxx26-warning@#11 {{type aware allocators are a C++2c extension}}
template <typename T> void operator delete(std::type_identity<S6>, T, size_t, std::align_val_t); // #12
// expected-error@#12 {{type aware 'operator delete' cannot take a dependent type as its 2nd parameter}}
+ // no_type_aware-error@#12 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
// precxx26-warning@#12 {{type aware allocators are a C++2c extension}}
};
@@ -62,30 +75,38 @@ template <typename U>
struct S7 {
template <typename T> void *operator new(std::type_identity<T>, U, std::align_val_t); // #13
// expected-error@#13 {{type aware 'operator new' cannot take a dependent type as its 2nd parameter;}}
+ // no_type_aware-error@#13 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
// precxx26-warning@#13 {{type aware allocators are a C++2c extension}}
template <typename T> void operator delete(std::type_identity<T>, U, size_t, std::align_val_t); // #14
// expected-error@#14 {{type aware 'operator delete' cannot take a dependent type as its 2nd parameter;}}
+ // no_type_aware-error@#14 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
// precxx26-warning@#14 {{type aware allocators are a C++2c extension}}
template <typename T> void operator delete(std::type_identity<T>, S7 *, std::destroying_delete_t, U, std::align_val_t); // #15
// expected-error@#15 {{destroying delete is not permitted to be type aware}}
+ // no_type_aware-error@#15 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
void operator delete(S7 *, std::destroying_delete_t, U); // #16
};
void f() {
S7<int> s;
// expected-note at -1 {{in instantiation of template class 'S7<int>' requested here}}
+ // no_type_aware-note at -2 {{in instantiation of template class 'S7<int>' requested here}}
// expected-error@#16 {{destroying operator delete can have only an optional size and optional alignment parameter}}
+ // no_type_aware-error@#16 {{destroying operator delete can have only an optional size and optional alignment parameter}}
}
struct S8 {
template <typename T, typename U> void *operator new(std::type_identity<T>, U, std::align_val_t); // #17
// expected-error@#17 {{type aware 'operator new' cannot take a dependent type as its 2nd parameter;}}
+ // no_type_aware-error@#17 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
// precxx26-warning@#17 {{type aware allocators are a C++2c extension}}
template <typename T, typename U> void operator delete(std::type_identity<T>, U, size_t, std::align_val_t); // #18
// expected-error@#18 {{type aware 'operator delete' cannot take a dependent type as its 2nd parameter;}}
+ // no_type_aware-error@#18 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
// precxx26-warning@#18 {{type aware allocators are a C++2c extension}}
template <typename T, typename U> void operator delete(std::type_identity<T>, S8 *, std::destroying_delete_t, U, std::align_val_t); // #19
// expected-error@#19 {{destroying delete is not permitted to be type aware}}
+ // no_type_aware-error@#19 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
};
template <typename T> using Alias = T;
@@ -93,58 +114,83 @@ template <typename T> using TypeIdentityAlias = std::type_identity<T>;
typedef std::type_identity<double> TypedefAlias;
using UsingAlias = std::type_identity<float>;
struct S9 {
- void *operator new(Alias<size_t>, std::align_val_t);
+ void *operator new(Alias<size_t>, std::align_val_t); // #S9_typed_new
template <typename T> void *operator new(Alias<std::type_identity<T>>, Alias<size_t>, std::align_val_t); // #20
// precxx26-warning@#20 {{type aware allocators are a C++2c extension}}
+ // no_type_aware-error at -2 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
void *operator new(Alias<std::type_identity<int>>, size_t, std::align_val_t);
// precxx26-warning at -1 {{type aware allocators are a C++2c extension}}
+ // no_type_aware-error at -2 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <typename T> void operator delete(Alias<std::type_identity<T>>, void *, size_t, std::align_val_t); // #21
// precxx26-warning@#21{{type aware allocators are a C++2c extension}}
- void operator delete(Alias<std::type_identity<int>>, void *, size_t, std::align_val_t);
+ // no_type_aware-error@#21 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
+ void operator delete(Alias<std::type_identity<int>>, void *, size_t, std::align_val_t); // #S9_typed_delete
// precxx26-warning at -1 {{type aware allocators are a C++2c extension}}
+ // no_type_aware-error at -2 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
};
struct S10 {
template <typename T> void *operator new(TypeIdentityAlias<T>, size_t, std::align_val_t); // #22
// precxx26-warning@#22 {{type aware allocators are a C++2c extension}}
+ // no_type_aware-error at -2 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
void *operator new(TypeIdentityAlias<int>, size_t, std::align_val_t);
// precxx26-warning at -1 {{type aware allocators are a C++2c extension}}
+ // no_type_aware-error at -2 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <typename T> void operator delete(TypeIdentityAlias<T>, void *, size_t, std::align_val_t); // #23
+ // precxx26-warning@#23 {{type aware allocators are a C++2c extension}}
+ // no_type_aware-error@#23 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
+ void operator delete(TypeIdentityAlias<int>, void *, size_t, std::align_val_t); // #S10_typed_delete
// precxx26-warning at -1 {{type aware allocators are a C++2c extension}}
- void operator delete(TypeIdentityAlias<int>, void *, size_t, std::align_val_t);
- // precxx26-warning at -1 {{type aware allocators are a C++2c extension}}
+ // no_type_aware-error at -2 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
};
void test() {
S9 *s9 = new S9;
+ // no_type_aware-error at -1 {{no matching function for call to 'operator new'}}
+ // no_type_aware-note@#S9_typed_new {{candidate function not viable: requires 2 arguments, but 1 was provided}}
delete s9;
+ // no_type_aware-error at -1 {{no suitable member 'operator delete' in 'S9'}}
+ // no_type_aware-note@#S9_typed_delete {{member 'operator delete' declared here}}
S10 *s10 = new S10;
+ // no_type_aware-error at -1 {{no matching function for call to 'operator new'}}
delete s10;
+ // no_type_aware-error at -1 {{no suitable member 'operator delete' in 'S10'}}
+ // no_type_aware-note@#S10_typed_delete {{member 'operator delete' declared here}}
}
struct S11 {
template <typename T> void *operator new(TypedefAlias, size_t, std::align_val_t);
// precxx26-warning at -1 {{type aware allocators are a C++2c extension}}
+ // no_type_aware-error at -2 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
void *operator new(TypedefAlias, size_t, std::align_val_t);
// precxx26-warning at -1 {{type aware allocators are a C++2c extension}}
+ // no_type_aware-error at -2 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <typename T> void operator delete(TypedefAlias, void *, size_t, std::align_val_t);
// precxx26-warning at -1 {{type aware allocators are a C++2c extension}}
+ // no_type_aware-error at -2 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
void operator delete(TypedefAlias, void *, size_t, std::align_val_t);
// precxx26-warning at -1 {{type aware allocators are a C++2c extension}}
+ // no_type_aware-error at -2 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
};
struct S12 {
template <typename T> void *operator new(UsingAlias, size_t, std::align_val_t);
// precxx26-warning at -1 {{type aware allocators are a C++2c extension}}
+ // no_type_aware-error at -2 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
void *operator new(UsingAlias, size_t, std::align_val_t);
// precxx26-warning at -1 {{type aware allocators are a C++2c extension}}
+ // no_type_aware-error at -2 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
template <typename T> void operator delete(UsingAlias, void *, size_t, std::align_val_t);
// precxx26-warning at -1 {{type aware allocators are a C++2c extension}}
+ // no_type_aware-error at -2 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
void operator delete(UsingAlias, void *, size_t, std::align_val_t);
// precxx26-warning at -1 {{type aware allocators are a C++2c extension}}
+ // no_type_aware-error at -2 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
};
struct S13 {
void *operator new(std::type_identity<S13>, size_t, std::align_val_t);
// precxx26-warning at -1 {{type aware allocators are a C++2c extension}}
+ // no_type_aware-error at -2 {{type aware 'operator new' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
void operator delete(std::type_identity<S13>, void*, size_t, std::align_val_t);
// precxx26-warning at -1 {{type aware allocators are a C++2c extension}}
+ // no_type_aware-error at -2 {{type aware 'operator delete' declared but type aware allocator support is disabled. Pass -fcxx-type-aware-allocators to enable it}}
};
More information about the cfe-commits
mailing list