[clang] [RFC] Initial implementation of P2719 (PR #113510)
cor3ntin wrote: As discussed offline, assuming the paper do get approved soon-ish, I don't think the documentation is necessary, at it justs described the c++ feature and cppreference is a better place to do that (that being said, it's a well written doc). Tangentially, maybe the clang community should work on an llvm.org blog post to present the various safety-related features/tools available https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -4778,6 +4784,16 @@ class Sema final : public SemaBase { CXXRecordDecl *getStdBadAlloc() const; EnumDecl *getStdAlignValT() const; + const ClassTemplateDecl *getStdTypeIdentity() const; + ClassTemplateDecl *getStdTypeIdentity(); + std::optional instantiateSpecializedTypeIdentity(QualType Subject); + bool isTypeIdentitySpecialization(QualType Type) const; + bool isTypeAwareOperatorNewOrDelete(const FunctionDecl *FnDecl) const; + bool isTypeAwareOperatorNewOrDelete(const FunctionTemplateDecl *FnDecl) const; + bool isTypeAwareOperatorNewOrDelete(const NamedDecl *FnDecl) const; cor3ntin wrote: Do we really need 3 functions there, or can we just expose the `NamedDecl` one and dispatch inside of it? https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
https://github.com/cor3ntin edited https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -1520,7 +1533,7 @@ static void EnterNewDeleteCleanup(CodeGenFunction &CGF, llvm::Value *AllocSize, CharUnits AllocAlign, const CallArgList &NewArgs) { - unsigned NumNonPlacementArgs = E->passAlignment() ? 2 : 1; + unsigned NumNonPlacementArgs = E->getNumImplicitArgs(); cor3ntin wrote: Nah ( they are implicitly static), but adding assertions would not hurt https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -3543,7 +3543,14 @@ def : Separate<["-"], "fnew-alignment">, Alias; def : Flag<["-"], "faligned-new">, Alias; def : Flag<["-"], "fno-aligned-new">, Alias; def faligned_new_EQ : Joined<["-"], "faligned-new=">; - +defm cxx_type_aware_allocators : BoolFOption<"experimental-cxx-type-aware-allocators", + LangOpts<"TypeAwareAllocators">, DefaultFalse, + PosFlag, + NegFlag, BothFlags<[], [ClangOption, CC1Option]>>; cor3ntin wrote: ```suggestion PosFlag, NegFlag, BothFlags<[], [ClangOption, CC1Option]>>; ``` https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -3482,15 +3486,40 @@ bool FunctionDecl::isDestroyingOperatorDelete() const { // Within a class C, a single object deallocation function with signature // (T, std::destroying_delete_t, ) // is a destroying operator delete. - if (!isa(this) || getOverloadedOperator() != OO_Delete || - getNumParams() < 2) + if (!isa(this) || getOverloadedOperator() != OO_Delete) +return false; + + unsigned NumParams = getNumParams(); + unsigned DestroyingDeleteTagParam = 1; + bool IsTypeAware = false; + if (NumParams > 0) +IsTypeAware = getParamDecl(0)->getType()->isTypeIdentitySpecialization(); cor3ntin wrote: There is some duplication with Sema::isTypeAwareOperatorNewOrDelete, can we simplify? https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -4778,6 +4784,16 @@ class Sema final : public SemaBase { CXXRecordDecl *getStdBadAlloc() const; EnumDecl *getStdAlignValT() const; + const ClassTemplateDecl *getStdTypeIdentity() const; + ClassTemplateDecl *getStdTypeIdentity(); + std::optional instantiateSpecializedTypeIdentity(QualType Subject); cor3ntin wrote: QualType already has an invalid state, why do we need the optional? https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -2709,14 +2831,63 @@ static bool resolveAllocationOverload( llvm_unreachable("Unreachable, bad result from BestViableFunction"); } -bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, - AllocationFunctionScope NewScope, - AllocationFunctionScope DeleteScope, - QualType AllocType, bool IsArray, - bool &PassAlignment, MultiExprArg PlaceArgs, - FunctionDecl *&OperatorNew, - FunctionDecl *&OperatorDelete, - bool Diagnose) { +enum class DeallocLookupMode { Untyped, OptionallyTyped, RequireTyped }; + +static void LookupGlobalDeallocationFunctions(Sema &S, SourceLocation Loc, + LookupResult &FoundDelete, + DeallocLookupMode Mode, + DeclarationName Name, + QualType DeallocType) { + S.LookupQualifiedName(FoundDelete, S.Context.getTranslationUnitDecl()); + if (Mode == DeallocLookupMode::OptionallyTyped) { +bool RemoveTypedDecl = Mode == DeallocLookupMode::Untyped; cor3ntin wrote: Is all of that dead code (RemoveTypedDecl can't be true, right?) ? https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -3130,6 +3130,30 @@ bool Type::isStdByteType() const { return false; } +const TemplateDecl *Type::getSpecializedTemplateDecl() const { + const Type *DesugaredType = getUnqualifiedDesugaredType(); + if (const auto *Specialization = + DesugaredType->getAs()) +return Specialization->getTemplateName().getAsTemplateDecl(); + if (const auto *Record = DesugaredType->getAsCXXRecordDecl()) { +if (const auto *CTS = dyn_cast(Record)) + return CTS->getSpecializedTemplate(); + } + return nullptr; +} + +bool Type::isTypeIdentitySpecialization() const { + const TemplateDecl *SpecializedDecl = getSpecializedTemplateDecl(); + if (!SpecializedDecl) +return false; + IdentifierInfo *II = SpecializedDecl->getIdentifier(); + if (!II) +return false; + if (!SpecializedDecl->isInStdNamespace()) +return false; + return II->isStr("type_identity"); cor3ntin wrote: Might as well collapse that on a single line https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -9712,19 +9712,34 @@ def warn_operator_new_returns_null : Warning< "%select{| or 'noexcept'}1">, InGroup; def err_operator_new_dependent_param_type : Error< - "%0 cannot take a dependent type as first parameter; " - "use size_t (%1) instead">; + "%select{|type aware}1 %0 cannot take a dependent type as %select{first|second}1 parameter; " + "use size_t (%2) instead">; def err_operator_new_param_type : Error< - "%0 takes type size_t (%1) as first parameter">; + "%select{|type aware}1 %0 takes type size_t (%2) as %select{first|second}1 parameter">; def err_operator_new_default_arg: Error< "parameter of %0 cannot have a default argument">; def err_operator_delete_dependent_param_type : Error< - "%0 cannot take a dependent type as first parameter; use %1 instead">; + "%select{|type aware}1 %0 cannot take a dependent type as %select{first|second}1 parameter; " + "use %2 instead">; def err_operator_delete_param_type : Error< - "first parameter of %0 must have type %1">; + "%select{first|second}1 parameter of%select{|type aware}1 %0 must have type %2">; def err_destroying_operator_delete_not_usual : Error< "destroying operator delete can have only an optional size and optional " "alignment parameter">; +def err_type_aware_destroying_operator_delete : Error< + "type aware destroying delete is not permitted, enable with '-fexperimental-cxx-type-aware-destroying-delete'">; +def err_unsupported_type_aware_allocator : Error< + "type aware allocation operators are disabled, enable with '-fexperimental-cxx-type-aware-allocators'">; cor3ntin wrote: Are these useful? The option is defaulted to true anyway right? And it's likely to land in 26 in a few weeks https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -3543,7 +3543,14 @@ def : Separate<["-"], "fnew-alignment">, Alias; def : Flag<["-"], "faligned-new">, Alias; def : Flag<["-"], "fno-aligned-new">, Alias; def faligned_new_EQ : Joined<["-"], "faligned-new=">; - +defm cxx_type_aware_allocators : BoolFOption<"experimental-cxx-type-aware-allocators", + LangOpts<"TypeAwareAllocators">, DefaultFalse, + PosFlag, + NegFlag, BothFlags<[], [ClangOption, CC1Option]>>; +defm cxx_type_aware_destroying_delete : BoolFOption<"experimental-cxx-type-aware-destroying-delete", + LangOpts<"TypeAwareDestroyingDelete">, DefaultFalse, + PosFlag, cor3ntin wrote: ```suggestion PosFlag, ``` https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -2696,6 +2699,8 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase { return static_cast(TypeBits.Dependence); } + const TemplateDecl *getSpecializedTemplateDecl() const; cor3ntin wrote: Does that need to be in the header? (the implementation only work for type, it's not exactly generic) https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -2146,6 +2146,12 @@ class Sema final : public SemaBase { isConstantEvaluatedOverride; } + TypeAwareAllocationMode allocationModeInCurrentContext() const { +if (getLangOpts().TypeAwareAllocators && !isConstantEvaluatedContext()) + return TypeAwareAllocationMode::Yes; +return TypeAwareAllocationMode::No; + } cor3ntin wrote: Damn this is novel. Do we have any concerns with odr or such? (the alternative is to just modify the evaluation of new expression to ignore type information) https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -3482,15 +3486,40 @@ bool FunctionDecl::isDestroyingOperatorDelete() const { // Within a class C, a single object deallocation function with signature // (T, std::destroying_delete_t, ) // is a destroying operator delete. - if (!isa(this) || getOverloadedOperator() != OO_Delete || - getNumParams() < 2) + if (!isa(this) || getOverloadedOperator() != OO_Delete) +return false; + cor3ntin wrote: We should probably assert this is not an explicit object member function (new/delete are treated as implicitly static) https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -2709,14 +2831,63 @@ static bool resolveAllocationOverload( llvm_unreachable("Unreachable, bad result from BestViableFunction"); } -bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, - AllocationFunctionScope NewScope, - AllocationFunctionScope DeleteScope, - QualType AllocType, bool IsArray, - bool &PassAlignment, MultiExprArg PlaceArgs, - FunctionDecl *&OperatorNew, - FunctionDecl *&OperatorDelete, - bool Diagnose) { +enum class DeallocLookupMode { Untyped, OptionallyTyped, RequireTyped }; + +static void LookupGlobalDeallocationFunctions(Sema &S, SourceLocation Loc, + LookupResult &FoundDelete, + DeallocLookupMode Mode, + DeclarationName Name, + QualType DeallocType) { + S.LookupQualifiedName(FoundDelete, S.Context.getTranslationUnitDecl()); + if (Mode == DeallocLookupMode::OptionallyTyped) { +bool RemoveTypedDecl = Mode == DeallocLookupMode::Untyped; +LookupResult::Filter Filter = FoundDelete.makeFilter(); +while (Filter.hasNext()) { + NamedDecl *Decl = Filter.next()->getUnderlyingDecl(); + bool DeclIsTypeAware = S.isTypeAwareOperatorNewOrDelete(Decl); + if (DeclIsTypeAware && RemoveTypedDecl) +Filter.erase(); +} +Filter.done(); + } +} + +static bool resolveAllocationOverload( +Sema &S, LookupResult &R, SourceRange Range, SmallVectorImpl &Args, +ImplicitAllocationParameters &IAP, FunctionDecl *&Operator, +OverloadCandidateSet *AlignedCandidates, Expr *AlignArg, bool Diagnose) { + Operator = nullptr; + if (isTypeAwareAllocation(IAP.PassTypeIdentity)) { +assert(Args[0]->getType()->isTypeIdentitySpecialization()); +SmallVector UntypedParameters; +UntypedParameters.reserve(Args.size() - 1); +UntypedParameters.append(Args.begin() + 1, Args.end()); +AlignedAllocationMode InitialAlignmentMode = IAP.PassAlignment; +if (resolveAllocationOverloadInterior( +S, R, Range, ResolveMode::Typed, Args, IAP.PassAlignment, Operator, +AlignedCandidates, AlignArg, Diagnose)) + return true; +if (Operator) + return false; +// There's no type aware allocator +IAP.PassTypeIdentity = TypeAwareAllocationMode::No; +// Restore alignment requirements +IAP.PassAlignment = InitialAlignmentMode; +// Finally prepare the type free parameter list +Args = UntypedParameters; cor3ntin wrote: Can you explain why we need to remove the type? (also, I think `Args.erase(Args.begin())` would work as well as saving a copy, right?) https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -3357,6 +3357,10 @@ bool FunctionDecl::isReservedGlobalPlacementOperator() const { return false; const auto *proto = getType()->castAs(); + if (proto->getNumParams() < 2) +return false; + if (proto->getParamType(0)->isTypeIdentitySpecialization()) +return false; cor3ntin wrote: We probably don't need to compare getNumParams() twice (line below) https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
https://github.com/cor3ntin commented: A quick first pass https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -16106,6 +16127,128 @@ bool Sema::CompleteConstructorCall(CXXConstructorDecl *Constructor, return Invalid; } +bool Sema::isTypeIdentitySpecialization(QualType Type) const { + const ClassTemplateDecl *TypeIdentity = getStdTypeIdentity(); + if (!TypeIdentity) +return false; + const TemplateDecl *SpecializedDecl = Type->getSpecializedTemplateDecl(); + return TypeIdentity == SpecializedDecl; +} + +bool Sema::isTypeAwareOperatorNewOrDelete(const FunctionDecl *FnDecl) const { + // Type aware operators + if (FnDecl->getNumParams() < 2) +return false; + const ParmVarDecl *ParamDecl = FnDecl->getParamDecl(0); + return isTypeIdentitySpecialization(ParamDecl->getType()); +} + +bool Sema::isTypeAwareOperatorNewOrDelete( +const FunctionTemplateDecl *FTD) const { + return isTypeAwareOperatorNewOrDelete(FTD->getTemplatedDecl()); +} + +bool Sema::isTypeAwareOperatorNewOrDelete(const NamedDecl *ND) const { + if (auto *FTD = dyn_cast(ND)) +return isTypeAwareOperatorNewOrDelete(FTD->getTemplatedDecl()); + if (auto *FnDecl = dyn_cast(ND)) +return isTypeAwareOperatorNewOrDelete(FnDecl); + return false; +} + +std::optional cor3ntin wrote: Just returning FunctionDecl * would be enough https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -16106,6 +16127,128 @@ bool Sema::CompleteConstructorCall(CXXConstructorDecl *Constructor, return Invalid; } +bool Sema::isTypeIdentitySpecialization(QualType Type) const { + const ClassTemplateDecl *TypeIdentity = getStdTypeIdentity(); + if (!TypeIdentity) +return false; + const TemplateDecl *SpecializedDecl = Type->getSpecializedTemplateDecl(); + return TypeIdentity == SpecializedDecl; +} + +bool Sema::isTypeAwareOperatorNewOrDelete(const FunctionDecl *FnDecl) const { + // Type aware operators + if (FnDecl->getNumParams() < 2) +return false; + const ParmVarDecl *ParamDecl = FnDecl->getParamDecl(0); + return isTypeIdentitySpecialization(ParamDecl->getType()); +} + +bool Sema::isTypeAwareOperatorNewOrDelete( +const FunctionTemplateDecl *FTD) const { + return isTypeAwareOperatorNewOrDelete(FTD->getTemplatedDecl()); +} + +bool Sema::isTypeAwareOperatorNewOrDelete(const NamedDecl *ND) const { + if (auto *FTD = dyn_cast(ND)) +return isTypeAwareOperatorNewOrDelete(FTD->getTemplatedDecl()); + if (auto *FnDecl = dyn_cast(ND)) +return isTypeAwareOperatorNewOrDelete(FnDecl); + return false; +} + +std::optional +Sema::instantiateTypeAwareUsualDelete(FunctionTemplateDecl *FnTemplateDecl, + QualType DeallocType) { + if (!isTypeAwareAllocation(allocationModeInCurrentContext())) cor3ntin wrote: Do we need some additional caching for that ? (or is the caching dome in Deduce Template Arguments enough?) https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -1847,15 +1913,42 @@ static bool hasNewExtendedAlignment(Sema &S, QualType AllocType) { S.getASTContext().getTargetInfo().getNewAlign(); } +static bool CheckDeleteOperator(Sema &S, SourceLocation StartLoc, +SourceRange Range, bool Diagnose, +CXXRecordDecl *NamingClass, DeclAccessPair Decl, +FunctionDecl *Operator) { + if (S.isTypeAwareOperatorNewOrDelete(Operator)) { +QualType SelectedTypeIdentityParameter = +Operator->getParamDecl(0)->getType(); +if (S.RequireCompleteType(StartLoc, SelectedTypeIdentityParameter, + diag::err_incomplete_type)) + return true; + } + + // FIXME: DiagnoseUseOfDecl? + if (Operator->isDeleted()) { +if (Diagnose) { + StringLiteral *Msg = Operator->getDeletedMessage(); + S.Diag(StartLoc, diag::err_deleted_function_use) + << (Msg != nullptr) << (Msg ? Msg->getString() : StringRef()); + S.NoteDeletedFunction(Operator); +} +return true; + } cor3ntin wrote: Unrelated to your patch but we should really move that diagnostic in its own function - that code is duplicated https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
https://github.com/ojhunt ready_for_review https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
ojhunt wrote: This has been tentatively approved C++26 - CWG didn't have time to look at it this week but EWG and SG23 have approved it. I did spend some time discussing semantics with a couple of folk in EWG and CWG and the feedback was fairly strongly on the side of "the operator delete used for cleanup when a constructor throws must have the same typed awaredness" (e.g. the existing exact placement new parameters match requirement). But this implementation currently allows fallback to a non-type aware delete, so I'm changing that and adding test cases to ensure correctness according to those semantics. https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
ojhunt wrote: > > Could anyone with a windows machine see if you can work out what is > > happening with the windows test failure? I don't understand why the tests > > are failing on the windows bot as it seems like it should simply fail > > everything (e.g. windows driver is going wrong) or it should work > > It looks like the latest commit did pass on Windows, so this may be redundant > but it also passes locally on my Windows machine. Yeah, it took some time to work out the issue and it was basically just the standard "I wrote tests without a sufficiently explicit target triple" :D https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
zmodem wrote: > Could anyone with a windows machine see if you can work out what is happening > with the windows test failure? I don't understand why the tests are failing > on the windows bot as it seems like it should simply fail everything (e.g. > windows driver is going wrong) or it should work It looks like the latest commit did pass on Windows, so this may be redundant but it also passes locally on my Windows machine. https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
ojhunt wrote: Could anyone with a windows machine see if you can work out what is happening with the windows test failure? I don't understand why the tests are failing on the windows bot as it seems like it should simply fail everything (e.g. windows driver is going wrong) or it should work https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -4749,6 +4753,15 @@ class Sema final : public SemaBase { CXXRecordDecl *getStdBadAlloc() const; EnumDecl *getStdAlignValT() const; + ClassTemplateDecl *getStdTypeIdentity() const; + std::optional InstantiateSpecializedTypeIdentity(QualType Subject); erichkeane wrote: IIRC, our coding standard says camel case: ``` Function names should be verb phrases (as they represent actions), and command-like function should be imperative. The name should be camel case, and start with a lower case letter (e.g. openFile() or isFoo()).``` https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -2234,6 +2234,17 @@ enum class CXXNewInitializationStyle { Braces }; +struct ImplicitAllocationParameters { + bool PassTypeIdentity; erichkeane wrote: For things that are stored (I think these arent?), we typically prefer bitfields for size. As far as scoped-enum: it makes call sites much more readable than a bunch of bools, and ensures type safety. A type that only has bools is a little less type safe, but its been a while since i reviewed this so i'm not sure how I feel about it yet. https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
https://github.com/ojhunt edited https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
ojhunt wrote: Ok, so I've gone through all my GitHub settings, and am hoping for a comment or something, to see if GH will actually ping me this time :D https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
ojhunt wrote: also sorry for cycling to and from "review" the GH interface is still not obvious to me https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -307,6 +307,10 @@ EXTENSION(datasizeof, LangOpts.CPlusPlus) FEATURE(cxx_abi_relative_vtable, LangOpts.CPlusPlus && LangOpts.RelativeCXXABIVTables) +// Type aware allocators +FEATURE(cxx_type_aware_allocators, LangOpts.TypeAwareAllocators) ojhunt wrote: Oh, I don't believe I've ever made a feature test macro (everything I've worked on has been via direct `__has_feature()` checks, I'll look into existing macros to see how they're implemented/exposed) https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
https://github.com/ojhunt converted_to_draft https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -3358,6 +3358,12 @@ bool FunctionDecl::isReservedGlobalPlacementOperator() const { return false; const auto *proto = getType()->castAs(); + if (proto->getNumParams() < 2) +return false; + bool IsTypeAwareAllocator = ojhunt wrote: Yeah, I think this may date back to before a bunch of the helpers like isTypeIdentitySpecialization() so the logic was probably somewhat longer https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -8126,7 +8143,7 @@ class Sema final : public SemaBase { /// The scope in which to find allocation functions. enum AllocationFunctionScope { -/// Only look for allocation functions in the global scope. +/// Only look for allocation functions in the global scope ojhunt wrote: *looks shifty* Nope, 100% absolutely critical for correctness https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -4749,6 +4753,15 @@ class Sema final : public SemaBase { CXXRecordDecl *getStdBadAlloc() const; EnumDecl *getStdAlignValT() const; + ClassTemplateDecl *getStdTypeIdentity() const; + std::optional InstantiateSpecializedTypeIdentity(QualType Subject); ojhunt wrote: What is the correct coding style? Over time I've been told upper case, whereas other times lower - in this particular case I followed lower case for the `get` for consistency with the neighboring `get` methods, and upper case for the new one because it didn't have a "consistency with similar methods" rationale and the feedback on other patches seemed to imply that functions are _meant_ to have upper case first letter (I think I actually intentionally capitalized this function before pushing the PR \o/) I'd prefer lower case start, but I just want to know which it is actually meant to be :D https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -2234,6 +2234,17 @@ enum class CXXNewInitializationStyle { Braces }; +struct ImplicitAllocationParameters { + bool PassTypeIdentity; ojhunt wrote: What is the rationale for bitfields? I'm generally opposed to flag enums as the language support is so poor, and unless there are very real performance considerations I'm not convinced they're worth the code complexity cost. I did originally try to unify Allocation and Deallocation but the usage of them in the code base differs a bit (one is much more "try to do this" vs the other's "do this") and I found that keeping them distinct gave clarity to the code. In general the way the new and delete AST construction works is kind of gnarly in a way I wish we could avoid as I think it creates unnecessary complexity in some places, and just causes weirdness in others, but I didn't want to combine "lets add a new feature to new/delete" and at the same time "lets completely restructure how new/delete work". I adopted these structs largely because there were already two undifferentiated bool args, and adding a third made things even more opaque, especially in conjunction with the extensive use of default parameters. https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
https://github.com/AaronBallman commented: Thank you for working on this! The changes should come with release notes in clang/docs/ReleaseNotes.rst so users know about the new functionality. Unless this is slated for inclusion in C++26, it should probably also come with user-facing documentation in the language extensions file. https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -2968,6 +3161,29 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, // deallocation function will be called. if (Matches.size() == 1) { OperatorDelete = Matches[0].second; +if (IsTypeAwareOperatorNewOrDelete(OperatorDelete) != +IAP.PassTypeIdentity) { + Diag(StartLoc, diag::warn_mismatching_type_aware_cleanup_deallocator); + int NewDiagIndex = IsTypeAwareOperatorNewOrDelete(OperatorNew) ? 0 : 1; + int DeleteDiagIndex = + IsTypeAwareOperatorNewOrDelete(OperatorDelete) ? 0 : 1; + Diag(OperatorNew->getLocation(), diag::note_type_aware_operator_declared) + << NewDiagIndex << OperatorNew->getDeclName(); AaronBallman wrote: The diagnostics engine knows how to print named declarations, so I think you can drop the `getDeclName()` calls when emitting these diagnostics. https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -9688,6 +9688,18 @@ def err_operator_delete_param_type : Error< def err_destroying_operator_delete_not_usual : Error< "destroying operator delete can have only an optional size and optional " "alignment parameter">; +def err_type_aware_destroying_operator_delete : Error< + "type aware destroying delete is not permitted">; +def err_unsupported_type_aware_allocator : Error< + "type aware allocation operators are disabled">; +def err_no_matching_type_aware_cleanup_deallocator_mismatch : Error< + "type aware %0 requires matching %1 in %2">; +def err_type_aware_operator_found : Note< + "type aware %0 found in %1">; +def warn_mismatching_type_aware_cleanup_deallocator : Warning< + "mismatching type aware allocation operators for constructor cleanup">, InGroup; AaronBallman wrote: ```suggestion "mismatched type aware allocation operators for constructor cleanup">, InGroup; ``` https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -1847,15 +1909,41 @@ static bool hasNewExtendedAlignment(Sema &S, QualType AllocType) { S.getASTContext().getTargetInfo().getNewAlign(); } +static bool CheckDeleteOperator(Sema &S, SourceLocation StartLoc, +SourceRange Range, bool Diagnose, +CXXRecordDecl *NamingClass, DeclAccessPair Decl, +FunctionDecl *Operator) { + if (S.IsTypeAwareOperatorNewOrDelete(Operator)) { +auto SelectedTypeIdentityParameter = Operator->getParamDecl(0)->getType(); +if (S.RequireCompleteType(StartLoc, SelectedTypeIdentityParameter, + diag::err_incomplete_type)) + return true; + } + + // FIXME: DiagnoseUseOfDecl? AaronBallman wrote: That does seem like a better approach because that also catches things like availability attributes, deprecation, etc. https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -1435,6 +1444,8 @@ namespace { unsigned NumPlacementArgs : 31; LLVM_PREFERRED_TYPE(bool) unsigned PassAlignmentToPlacementDelete : 1; +LLVM_PREFERRED_TYPE(bool) +unsigned PassTypeToPlacementDelete : 1; AaronBallman wrote: Because you're adding a bit here, you should remove a bit from `NumPlacementArgs` so we don't require another allocation unit for the bit-field. https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -3096,6 +3096,29 @@ bool Type::isStdByteType() const { return false; } +TemplateDecl *Type::getSpecializedTemplateDecl() const { + const auto *DesugaredType = getUnqualifiedDesugaredType(); + if (auto *Specialization = DesugaredType->getAs()) AaronBallman wrote: ```suggestion if (const auto *Specialization = DesugaredType->getAs()) ``` https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -1586,8 +1597,22 @@ bool CoroutineStmtBuilder::makeNewAndDeleteExpr() { if (NewRef.isInvalid()) return false; - SmallVector NewArgs(1, FrameSize); - if (S.getLangOpts().CoroAlignedAllocation && PassAlignment) + SmallVector NewArgs; + if (IAP.PassTypeIdentity) { +auto SpecializedTypeIdentity = AaronBallman wrote: Please spell out the type https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -4749,6 +4753,15 @@ class Sema final : public SemaBase { CXXRecordDecl *getStdBadAlloc() const; EnumDecl *getStdAlignValT() const; + ClassTemplateDecl *getStdTypeIdentity() const; AaronBallman wrote: Return a `const` pointer and add an overload? https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -1520,7 +1533,7 @@ static void EnterNewDeleteCleanup(CodeGenFunction &CGF, llvm::Value *AllocSize, CharUnits AllocAlign, const CallArgList &NewArgs) { - unsigned NumNonPlacementArgs = E->passAlignment() ? 2 : 1; + unsigned NumNonPlacementArgs = E->getNumImplicitArgs(); AaronBallman wrote: Is it possible to have a member placement delete which has an explicit object argument? https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -16110,6 +16128,127 @@ bool Sema::CompleteConstructorCall(CXXConstructorDecl *Constructor, return Invalid; } +bool Sema::IsTypeIdentitySpecialization(QualType Type) const { + auto *TypeIdentity = getStdTypeIdentity(); + if (!TypeIdentity) +return false; + auto *SpecializedDecl = Type->getSpecializedTemplateDecl(); + return TypeIdentity == SpecializedDecl; +} + +bool Sema::IsTypeAwareOperatorNewOrDelete(const FunctionDecl *FnDecl) const { + // Type aware operators + if (FnDecl->getNumParams() < 2) +return false; + const auto *ParamDecl = FnDecl->getParamDecl(0); + return IsTypeIdentitySpecialization(ParamDecl->getType()); +} + +bool Sema::IsTypeAwareOperatorNewOrDelete( +const FunctionTemplateDecl *FTD) const { + return IsTypeAwareOperatorNewOrDelete(FTD->getTemplatedDecl()); +} + +bool Sema::IsTypeAwareOperatorNewOrDelete(const NamedDecl *ND) const { + if (auto *FTD = dyn_cast(ND)) +return IsTypeAwareOperatorNewOrDelete(FTD->getTemplatedDecl()); + if (auto *FnDecl = dyn_cast(ND)) +return IsTypeAwareOperatorNewOrDelete(FnDecl); + return false; +} + +std::optional +Sema::InstantiateTypeAwareUsualDelete(FunctionTemplateDecl *FnTemplateDecl, + QualType DeallocType) { + if (!AllowTypeAwareAllocators()) +return std::nullopt; + + auto TemplateParameters = FnTemplateDecl->getTemplateParameters(); AaronBallman wrote: Spell out the type (I'll stop commenting on those -- if the type is not spelled out in the initializer explicitly, you should spell out the type instead of using auto, unless the type is incredibly obvious and stupid to spell out, like with iterators) https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -1773,14 +1776,40 @@ static bool isNonPlacementDeallocationFunction(Sema &S, FunctionDecl *FD) { namespace { struct UsualDeallocFnInfo { UsualDeallocFnInfo() : Found(), FD(nullptr) {} -UsualDeallocFnInfo(Sema &S, DeclAccessPair Found) +UsualDeallocFnInfo(Sema &S, DeclAccessPair Found, QualType AllocType) : Found(Found), FD(dyn_cast(Found->getUnderlyingDecl())), Destroying(false), HasSizeT(false), HasAlignValT(false), - CUDAPref(SemaCUDA::CFP_Native) { - // A function template declaration is never a usual deallocation function. - if (!FD) -return; + HasTypeIdentity(false), CUDAPref(SemaCUDA::CFP_Native) { + // A function template declaration is only a usual deallocation function + // if it is a typed delete AaronBallman wrote: ```suggestion // if it is a typed delete. ``` https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -8126,7 +8143,7 @@ class Sema final : public SemaBase { /// The scope in which to find allocation functions. enum AllocationFunctionScope { -/// Only look for allocation functions in the global scope. +/// Only look for allocation functions in the global scope AaronBallman wrote: ```suggestion /// Only look for allocation functions in the global scope. ``` https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -2699,6 +2702,8 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase { return static_cast(TypeBits.Dependence); } + TemplateDecl *getSpecializedTemplateDecl() const; AaronBallman wrote: Can this return a `const` pointer and then have a non-const overload which returns the non-const pointer? https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -3096,6 +3096,29 @@ bool Type::isStdByteType() const { return false; } +TemplateDecl *Type::getSpecializedTemplateDecl() const { + const auto *DesugaredType = getUnqualifiedDesugaredType(); + if (auto *Specialization = DesugaredType->getAs()) +return Specialization->getTemplateName().getAsTemplateDecl(); + if (const auto *Record = DesugaredType->getAsCXXRecordDecl()) { +if (auto *CTS = dyn_cast(Record)) AaronBallman wrote: ```suggestion if (const auto *CTS = dyn_cast(Record)) ``` https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -2627,16 +2731,21 @@ static bool resolveAllocationOverload( // FIXME: Find out how this interacts with the std::align_val_t fallback // once MSVC implements it. if (R.getLookupName().getCXXOverloadedOperator() == OO_Array_New && -S.Context.getLangOpts().MSVCCompat) { +S.Context.getLangOpts().MSVCCompat && Mode != ResolveMode::Typed) { AaronBallman wrote: H it's a bit weird that we're changing MSVC compat mode when I don't think MSVC implements this functionality at all. I'm not opposed, but do we want to support this in MSVC compat mode? https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -1524,6 +1524,10 @@ in addition with the pragmas or -fmax-tokens flag to get any warnings. }]; } +// Warning group for type aware allocators +def TypeAwareAllocatorMismatch : AaronBallman wrote: Do you expect to add more warnings under this group? If not, I'd suggest defining the group inline with the only warning using it. https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -16110,6 +16128,127 @@ bool Sema::CompleteConstructorCall(CXXConstructorDecl *Constructor, return Invalid; } +bool Sema::IsTypeIdentitySpecialization(QualType Type) const { + auto *TypeIdentity = getStdTypeIdentity(); + if (!TypeIdentity) +return false; + auto *SpecializedDecl = Type->getSpecializedTemplateDecl(); AaronBallman wrote: ```suggestion const auto *TypeIdentity = getStdTypeIdentity(); if (!TypeIdentity) return false; const auto *SpecializedDecl = Type->getSpecializedTemplateDecl(); ``` https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -3533,7 +3533,14 @@ def : Separate<["-"], "fnew-alignment">, Alias; def : Flag<["-"], "faligned-new">, Alias; def : Flag<["-"], "fno-aligned-new">, Alias; def faligned_new_EQ : Joined<["-"], "faligned-new=">; - +defm cxx_type_aware_allocators : BoolFOption<"cxx-type-aware-allocators", + LangOpts<"TypeAwareAllocators">, DefaultFalse, + PosFlag, + NegFlag, BothFlags<[], [ClangOption, CC1Option]>>; +defm cxx_type_aware_destroying_delete : BoolFOption<"cxx-type-aware-destroying-delete", + LangOpts<"TypeAwareDestroyingDelete">, DefaultFalse, + PosFlag, AaronBallman wrote: Is this paper heading towards C++26 in Poland? If not, we shouldn't document it as a C++ feature. IIRC the sentiment for this was pretty strong, but do we want to claim it's experimental so we can reserve the right to break users in the future if WG21 changes the design in breaking ways? https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
https://github.com/AaronBallman edited https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
@@ -16110,6 +16128,127 @@ bool Sema::CompleteConstructorCall(CXXConstructorDecl *Constructor, return Invalid; } +bool Sema::IsTypeIdentitySpecialization(QualType Type) const { + auto *TypeIdentity = getStdTypeIdentity(); + if (!TypeIdentity) +return false; + auto *SpecializedDecl = Type->getSpecializedTemplateDecl(); + return TypeIdentity == SpecializedDecl; +} + +bool Sema::IsTypeAwareOperatorNewOrDelete(const FunctionDecl *FnDecl) const { + // Type aware operators + if (FnDecl->getNumParams() < 2) +return false; + const auto *ParamDecl = FnDecl->getParamDecl(0); + return IsTypeIdentitySpecialization(ParamDecl->getType()); +} + +bool Sema::IsTypeAwareOperatorNewOrDelete( +const FunctionTemplateDecl *FTD) const { + return IsTypeAwareOperatorNewOrDelete(FTD->getTemplatedDecl()); +} AaronBallman wrote: Do we need these overloads? Both `FunctionDecl` and `FunctionTemplateDecl` inherit from `NamedDecl`, so it seems like the last overload should be all we'd need? https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC] Initial implementation of P2719 (PR #113510)
https://github.com/cor3ntin edited https://github.com/llvm/llvm-project/pull/113510 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits