Skip to content

Commit d29cb28

Browse files
committed
Pile of clean up and updates
1 parent 9afe5ca commit d29cb28

File tree

15 files changed

+116
-96
lines changed

15 files changed

+116
-96
lines changed

clang/include/clang/AST/Decl.h

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2537,7 +2537,21 @@ class FunctionDecl : public DeclaratorDecl,
25372537

25382538
/// Determines whether this function is one of the replaceable global
25392539
/// allocation functions described in isReplaceableGlobalAllocationFunction,
2540-
/// or is a function that may be treated as such during constant evaluation
2540+
/// or is a function that may be treated as such during constant evaluation.
2541+
/// This adds support for potentially templated type aware global allocation
2542+
/// functions of the form:
2543+
/// void *operator new(type-identity, std::size_t, std::align_val_t)
2544+
/// void *operator new(type-identity, std::size_t, std::align_val_t, const std::nothrow_t &) noexcept;
2545+
/// void *operator new[](type-identity, std::size_t, std::align_val_t)
2546+
/// void *operator new[](type-identity, std::size_t, std::align_val_t, const std::nothrow_t &) noexcept;
2547+
/// void operator delete(type-identity, void*, std::size_t, std::align_val_t) noexcept;
2548+
/// void operator delete(type-identity, void*, std::size_t, std::align_val_t, const std::nothrow_t &) noexcept;
2549+
/// void operator delete[](type-identity, void*, std::size_t, std::align_val_t) noexcept;
2550+
/// void operator delete[](type-identity, void*, std::size_t, std::align_val_t, const std::nothrow_t &) noexcept;
2551+
/// Where `type-identity` is a specialization of std::type_identity. If the
2552+
/// declaration is a templated function, it may not include a parameter pack
2553+
/// in the argument list, the type-identity parameter is required to be
2554+
/// dependent, and is the only permitted dependent parameter.
25412555
bool isUsableAsGlobalAllocationFunctionInConstantEvaluation(
25422556
std::optional<unsigned> *AlignmentParam = nullptr,
25432557
bool *IsNothrow = nullptr) const;
@@ -2548,6 +2562,14 @@ class FunctionDecl : public DeclaratorDecl,
25482562
/// Determine whether this is a destroying operator delete.
25492563
bool isDestroyingOperatorDelete() const;
25502564

2565+
/// Count of mandatory parameters for type aware operator new
2566+
static constexpr unsigned RequiredTypeAwareNewParameterCount =
2567+
/* type-identity */ 1 + /* size */ 1 + /* alignment */ 1;
2568+
2569+
/// Count of mandatory parameters for type aware operator delete
2570+
static constexpr unsigned RequiredTypeAwareDeleteParameterCount =
2571+
/* type-identity */ 1 + /* address */ 1 + /* size */ 1 + /* alignment */ 1;
2572+
25512573
/// Determine whether this is a type aware operator new or delete.
25522574
bool isTypeAwareOperatorNewOrDelete() const;
25532575

clang/include/clang/AST/DeclarationName.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,44 @@ class DeclarationName {
477477
return OO_None;
478478
}
479479

480+
bool isOperatorNew() const {
481+
if (getNameKind() != DeclarationName::CXXOperatorName)
482+
return false;
483+
switch (getCXXOverloadedOperator()) {
484+
case OO_New:
485+
case OO_Array_New:
486+
return true;
487+
default:
488+
return false;
489+
}
490+
}
491+
492+
bool isOperatorDelete() const {
493+
if (getNameKind() != DeclarationName::CXXOperatorName)
494+
return false;
495+
switch (getCXXOverloadedOperator()) {
496+
case OO_Delete:
497+
case OO_Array_Delete:
498+
return true;
499+
default:
500+
return false;
501+
}
502+
}
503+
504+
bool isOperatorNewOrDelete() const {
505+
if (getNameKind() != DeclarationName::CXXOperatorName)
506+
return false;
507+
switch (getCXXOverloadedOperator()) {
508+
case OO_New:
509+
case OO_Array_New:
510+
case OO_Delete:
511+
case OO_Array_Delete:
512+
return true;
513+
default:
514+
return false;
515+
}
516+
}
517+
480518
/// If this name is the name of a literal operator,
481519
/// retrieve the identifier associated with it.
482520
const IdentifierInfo *getCXXLiteralIdentifier() const {

clang/include/clang/Basic/Features.def

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,6 @@ FEATURE(clang_atomic_attributes, true)
317317

318318
// Type aware allocators
319319
FEATURE(cxx_type_aware_allocators, LangOpts.TypeAwareAllocators)
320-
FEATURE(cxx_type_aware_destroying_delete, LangOpts.TypeAwareDestroyingDelete)
321320

322321
// CUDA/HIP Features
323322
FEATURE(cuda_noinline_keyword, LangOpts.CUDA)

clang/include/clang/Basic/LangOptions.def

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,6 @@ LANGOPT(OpenACC , 1, 0, "OpenACC Enabled")
313313
LANGOPT(MSVCEnableStdcMacro , 1, 0, "Define __STDC__ with '-fms-compatibility'")
314314
LANGOPT(SizedDeallocation , 1, 0, "sized deallocation")
315315
LANGOPT(TypeAwareAllocators , 1, 1, "type aware C++ allocation operators")
316-
LANGOPT(TypeAwareDestroyingDelete , 1, 1, "type aware C++ destroying delete")
317316
LANGOPT(AlignedAllocation , 1, 0, "aligned allocation")
318317
LANGOPT(AlignedAllocationUnavailable, 1, 0, "aligned allocation functions are unavailable")
319318
LANGOPT(NewAlignOverride , 32, 0, "maximum alignment guaranteed by '::operator new(size_t)'")

clang/include/clang/Driver/Options.td

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3527,10 +3527,6 @@ defm cxx_type_aware_allocators : BoolFOption<"experimental-cxx-type-aware-alloca
35273527
LangOpts<"TypeAwareAllocators">, DefaultFalse,
35283528
PosFlag<SetTrue, [], [ClangOption], "Enable experimental C++ type aware allocator operators">,
35293529
NegFlag<SetFalse>, BothFlags<[], [ClangOption, CC1Option]>>;
3530-
defm cxx_type_aware_destroying_delete : BoolFOption<"experimental-cxx-type-aware-destroying-delete",
3531-
LangOpts<"TypeAwareDestroyingDelete">, DefaultFalse,
3532-
PosFlag<SetTrue, [], [ClangOption], "Enable experimental C++ type aware allocator operators for destroying delete">,
3533-
NegFlag<SetFalse>, BothFlags<[], [ClangOption, CC1Option]>>;
35343530
def fobjc_legacy_dispatch : Flag<["-"], "fobjc-legacy-dispatch">, Group<f_Group>;
35353531
def fobjc_new_property : Flag<["-"], "fobjc-new-property">, Group<clang_ignored_f_Group>;
35363532
defm objc_infer_related_result_type : BoolFOption<"objc-infer-related-result-type",

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4779,8 +4779,7 @@ bool Compiler<Emitter>::VisitCallExpr(const CallExpr *E) {
47794779
// Calls to replaceable operator new/operator delete.
47804780
if (FuncDecl &&
47814781
FuncDecl->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
4782-
if (FuncDecl->getDeclName().getCXXOverloadedOperator() == OO_New ||
4783-
FuncDecl->getDeclName().getCXXOverloadedOperator() == OO_Array_New) {
4782+
if (FuncDecl->getDeclName().isOperatorNew()) {
47844783
return VisitBuiltinCallExpr(E, Builtin::BI__builtin_operator_new);
47854784
} else {
47864785
assert(FuncDecl->getDeclName().getCXXOverloadedOperator() == OO_Delete);

clang/lib/AST/Decl.cpp

Lines changed: 16 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3362,12 +3362,7 @@ bool FunctionDecl::isMSVCRTEntryPoint() const {
33623362
}
33633363

33643364
bool FunctionDecl::isReservedGlobalPlacementOperator() const {
3365-
if (getDeclName().getNameKind() != DeclarationName::CXXOperatorName)
3366-
return false;
3367-
if (getDeclName().getCXXOverloadedOperator() != OO_New &&
3368-
getDeclName().getCXXOverloadedOperator() != OO_Delete &&
3369-
getDeclName().getCXXOverloadedOperator() != OO_Array_New &&
3370-
getDeclName().getCXXOverloadedOperator() != OO_Array_Delete)
3365+
if (!getDeclName().isOperatorNewOrDelete())
33713366
return false;
33723367

33733368
if (!getDeclContext()->getRedeclContext()->isTranslationUnit())
@@ -3390,12 +3385,7 @@ bool FunctionDecl::isReservedGlobalPlacementOperator() const {
33903385

33913386
bool FunctionDecl::isUsableAsGlobalAllocationFunctionInConstantEvaluation(
33923387
std::optional<unsigned> *AlignmentParam, bool *IsNothrow) const {
3393-
if (getDeclName().getNameKind() != DeclarationName::CXXOperatorName)
3394-
return false;
3395-
if (getDeclName().getCXXOverloadedOperator() != OO_New &&
3396-
getDeclName().getCXXOverloadedOperator() != OO_Delete &&
3397-
getDeclName().getCXXOverloadedOperator() != OO_Array_New &&
3398-
getDeclName().getCXXOverloadedOperator() != OO_Array_Delete)
3388+
if (!getDeclName().isOperatorNewOrDelete())
33993389
return false;
34003390

34013391
if (isa<CXXRecordDecl>(getDeclContext()))
@@ -3406,7 +3396,9 @@ bool FunctionDecl::isUsableAsGlobalAllocationFunctionInConstantEvaluation(
34063396
return false;
34073397

34083398
bool IsTypeAware = isTypeAwareOperatorNewOrDelete();
3409-
unsigned MaxParamCount = IsTypeAware + 4;
3399+
// address, (size or hot_cold_t), alignment, no_throw_t
3400+
unsigned MaxImplicitParameters = 4;
3401+
unsigned MaxParamCount = IsTypeAware + MaxImplicitParameters;
34103402
const auto *FPT = getType()->castAs<FunctionProtoType>();
34113403
if (FPT->getNumParams() == 0 || FPT->getNumParams() > MaxParamCount ||
34123404
FPT->isVariadic())
@@ -3506,32 +3498,28 @@ bool FunctionDecl::isDestroyingOperatorDelete() const {
35063498
// Within a class C, a single object deallocation function with signature
35073499
// (T, std::destroying_delete_t, <more params>)
35083500
// is a destroying operator delete.
3509-
if (!isa<CXXMethodDecl>(this) || getOverloadedOperator() != OO_Delete)
3501+
if (!isa<CXXMethodDecl>(this) || getOverloadedOperator() != OO_Delete ||
3502+
getNumParams() < 2)
35103503
return false;
35113504

3512-
unsigned DestroyingDeleteTagParam = 1;
35133505
if (isTypeAwareOperatorNewOrDelete())
3514-
++DestroyingDeleteTagParam;
3515-
3516-
if (getNumParams() <= DestroyingDeleteTagParam)
35173506
return false;
35183507

3519-
auto *RD =
3520-
getParamDecl(DestroyingDeleteTagParam)->getType()->getAsCXXRecordDecl();
3508+
auto *RD = getParamDecl(1)->getType()->getAsCXXRecordDecl();
35213509
return RD && RD->isInStdNamespace() && RD->getIdentifier() &&
35223510
RD->getIdentifier()->isStr("destroying_delete_t");
35233511
}
35243512

35253513
bool FunctionDecl::isTypeAwareOperatorNewOrDelete() const {
3526-
if (getDeclName().getNameKind() != DeclarationName::CXXOperatorName)
3527-
return false;
3528-
if (getDeclName().getCXXOverloadedOperator() != OO_New &&
3529-
getDeclName().getCXXOverloadedOperator() != OO_Delete &&
3530-
getDeclName().getCXXOverloadedOperator() != OO_Array_New &&
3531-
getDeclName().getCXXOverloadedOperator() != OO_Array_Delete)
3532-
return false;
3533-
if (getNumParams() < 2)
3514+
if (getDeclName().isOperatorNew()) {
3515+
if (getNumParams() < FunctionDecl::RequiredTypeAwareNewParameterCount)
3516+
return false;
3517+
} else if (getDeclName().isOperatorDelete()) {
3518+
if (getNumParams() < FunctionDecl::RequiredTypeAwareDeleteParameterCount)
3519+
return false;
3520+
} else
35343521
return false;
3522+
35353523
return getParamDecl(0)->getType()->isTypeIdentitySpecialization();
35363524
}
35373525

clang/lib/AST/DeclCXX.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2534,20 +2534,22 @@ bool CXXMethodDecl::isUsualDeallocationFunction(
25342534
return false;
25352535

25362536
bool IsTypeAware = isTypeAwareOperatorNewOrDelete();
2537+
if (IsTypeAware && isVariadic())
2538+
return false;
25372539

25382540
// C++ [basic.stc.dynamic.deallocation]p2:
25392541
// Pre-type aware allocators:
25402542
// A template instance is never a usual deallocation function,
25412543
// regardless of its signature.
25422544
// Pending final C++26 text:
25432545
// A template instance is only a usual deallocation function if it
2544-
// is a type aware deallocation function, and only the type-identity
2545-
// parameter is dependent.
2546+
// is a type aware deallocation function, only the type-identity
2547+
// parameter is dependent, and there is no parameter pack in the argument
2548+
// list.
25462549
if (FunctionTemplateDecl *PrimaryTemplate = getPrimaryTemplate()) {
2547-
if (!IsTypeAware) {
2550+
if (!IsTypeAware)
25482551
// Stop early on if the specialization is not explicitly type aware
25492552
return false;
2550-
}
25512553

25522554
FunctionDecl *SpecializedDecl = PrimaryTemplate->getTemplatedDecl();
25532555
// A type aware allocation function template is only valid if the first
@@ -2578,8 +2580,10 @@ bool CXXMethodDecl::isUsualDeallocationFunction(
25782580
// removing the std::destroying_delete_t parameter and changing the
25792581
// first parameter type from T* to void* results in the signature of
25802582
// a usual deallocation function.
2581-
if (isDestroyingOperatorDelete())
2583+
if (isDestroyingOperatorDelete()) {
2584+
assert(!IsTypeAware);
25822585
++UsualParams;
2586+
}
25832587

25842588
// C++ <=14 [basic.stc.dynamic.deallocation]p2:
25852589
// [...] If class T does not declare such an operator delete but does
@@ -2591,6 +2595,11 @@ bool CXXMethodDecl::isUsualDeallocationFunction(
25912595
// (void* [, size_t] [, std::align_val_t] [, ...])
25922596
// and all such functions are usual deallocation functions. It's not clear
25932597
// that allowing varargs functions was intentional.
2598+
//
2599+
// P2719 extends usual deallocation functions to permit
2600+
// (type_identity<U>, void*, size_t, std::align_val_t)
2601+
// it does not permit variadic or template parameter packs
2602+
25942603
ASTContext &Context = getASTContext();
25952604
if (UsualParams < getNumParams() &&
25962605
Context.hasSameUnqualifiedType(getParamDecl(UsualParams)->getType(),

clang/lib/AST/ExprConstant.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8340,8 +8340,7 @@ class ExprEvaluatorBase
83408340
} else
83418341
FD = LambdaCallOp;
83428342
} else if (FD->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
8343-
if (FD->getDeclName().getCXXOverloadedOperator() == OO_New ||
8344-
FD->getDeclName().getCXXOverloadedOperator() == OO_Array_New) {
8343+
if (FD->getDeclName().isOperatorNew()) {
83458344
LValue Ptr;
83468345
if (!HandleOperatorNewCall(Info, E, Ptr))
83478346
return false;

clang/lib/AST/Type.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3144,7 +3144,7 @@ bool Type::isTypeIdentitySpecialization() const {
31443144
if (!STDecl)
31453145
return false;
31463146
IdentifierInfo *II = STDecl->getIdentifier();
3147-
return II && STDecl->isInStdNamespace() && II->isStr("type_identity");
3147+
return STDecl->isInStdNamespace() && II->isStr("type_identity");
31483148
}
31493149

31503150
bool Type::isSpecifierType() const {

0 commit comments

Comments
 (0)