@@ -3395,22 +3395,36 @@ bool FunctionDecl::isUsableAsGlobalAllocationFunctionInConstantEvaluation(
33953395 if (!getDeclContext ()->getRedeclContext ()->isTranslationUnit ())
33963396 return false ;
33973397
3398- bool IsTypeAware = isTypeAwareOperatorNewOrDelete ();
3399- // address, (size or hot_cold_t), alignment, no_throw_t
3400- unsigned MaxImplicitParameters = 4 ;
3401- unsigned MaxParamCount = IsTypeAware + MaxImplicitParameters;
3398+ if (isVariadic ())
3399+ return false ;
3400+
3401+ if (isTypeAwareOperatorNewOrDelete ()) {
3402+ bool IsDelete = getDeclName ().isOperatorDelete ();
3403+ unsigned RequiredParameterCount = IsDelete ? FunctionDecl::RequiredTypeAwareDeleteParameterCount : FunctionDecl::RequiredTypeAwareNewParameterCount;
3404+ if (AlignmentParam)
3405+ *AlignmentParam = /* type identity */ 1 + /* address */ IsDelete + /* size */ 1 ;
3406+ if (RequiredParameterCount == getNumParams ())
3407+ return true ;
3408+ if (getNumParams () > RequiredParameterCount + 1 )
3409+ return false ;
3410+ if (!getParamDecl (RequiredParameterCount)->getType ()->isNothrowT ())
3411+ return false ;
3412+
3413+ if (IsNothrow)
3414+ *IsNothrow = true ;
3415+ return true ;
3416+ }
3417+
34023418 const auto *FPT = getType ()->castAs <FunctionProtoType>();
3403- if (FPT->getNumParams () == 0 || FPT->getNumParams () > MaxParamCount ||
3404- FPT->isVariadic ())
3419+ if (FPT->getNumParams () == 0 || FPT->getNumParams () > 4 )
34053420 return false ;
34063421
3407- unsigned MinimumParamCount = IsTypeAware + 1 ;
34083422 // If this is a single-parameter function, it must be a replaceable global
34093423 // allocation or deallocation function.
3410- if (FPT->getNumParams () == MinimumParamCount )
3424+ if (FPT->getNumParams () == 1 )
34113425 return true ;
34123426
3413- unsigned Params = MinimumParamCount ;
3427+ unsigned Params = 1 ;
34143428 QualType Ty = FPT->getParamType (Params);
34153429 const ASTContext &Ctx = getASTContext ();
34163430
@@ -3421,7 +3435,7 @@ bool FunctionDecl::isUsableAsGlobalAllocationFunctionInConstantEvaluation(
34213435
34223436 // In C++14, the next parameter can be a 'std::size_t' for sized delete.
34233437 bool IsSizedDelete = false ;
3424- if ((IsTypeAware || Ctx.getLangOpts ().SizedDeallocation ) &&
3438+ if (Ctx.getLangOpts ().SizedDeallocation &&
34253439 (getDeclName ().getCXXOverloadedOperator () == OO_Delete ||
34263440 getDeclName ().getCXXOverloadedOperator () == OO_Array_Delete) &&
34273441 Ctx.hasSameType (Ty, Ctx.getSizeType ())) {
@@ -3431,8 +3445,7 @@ bool FunctionDecl::isUsableAsGlobalAllocationFunctionInConstantEvaluation(
34313445
34323446 // In C++17, the next parameter can be a 'std::align_val_t' for aligned
34333447 // new/delete.
3434- if ((IsTypeAware || Ctx.getLangOpts ().AlignedAllocation ) && !Ty.isNull () &&
3435- Ty->isAlignValT ()) {
3448+ if (Ctx.getLangOpts ().AlignedAllocation && !Ty.isNull () && Ty->isAlignValT ()) {
34363449 Consume ();
34373450 if (AlignmentParam)
34383451 *AlignmentParam = Params;
@@ -3505,9 +3518,7 @@ bool FunctionDecl::isDestroyingOperatorDelete() const {
35053518 if (isTypeAwareOperatorNewOrDelete ())
35063519 return false ;
35073520
3508- auto *RD = getParamDecl (1 )->getType ()->getAsCXXRecordDecl ();
3509- return RD && RD->isInStdNamespace () && RD->getIdentifier () &&
3510- RD->getIdentifier ()->isStr (" destroying_delete_t" );
3521+ return getParamDecl (1 )->getType ()->isDestroyingDeleteT ();
35113522}
35123523
35133524bool FunctionDecl::isTypeAwareOperatorNewOrDelete () const {
0 commit comments