Skip to content

Commit a75ae87

Browse files
committed
Incorporate last spec changes and remove qualifiers from allocated type
Also update tests for new semantics
1 parent 08fcf03 commit a75ae87

26 files changed

+554
-709
lines changed

clang/include/clang/AST/ExprCXX.h

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2261,21 +2261,19 @@ inline SizedDeallocationMode sizedDeallocationModeFromBool(bool IsSized) {
22612261
}
22622262

22632263
struct ImplicitAllocationParameters {
2264-
ImplicitAllocationParameters(QualType Type,
2264+
ImplicitAllocationParameters(QualType AllocType,
22652265
TypeAwareAllocationMode PassTypeIdentity,
22662266
AlignedAllocationMode PassAlignment)
2267-
: Type(Type.isNull() ? Type : Type.getUnqualifiedType()),
2268-
PassTypeIdentity(PassTypeIdentity), PassAlignment(PassAlignment) {
2269-
if (Type.isNull())
2270-
assert(!isTypeAwareAllocation(PassTypeIdentity));
2271-
assert(!Type.isNull());
2267+
: Type(AllocType), PassTypeIdentity(PassTypeIdentity),
2268+
PassAlignment(PassAlignment) {
2269+
if (!Type.isNull())
2270+
Type = Type.getUnqualifiedType();
2271+
assert(isValid());
22722272
}
22732273
explicit ImplicitAllocationParameters(AlignedAllocationMode PassAlignment)
22742274
: PassTypeIdentity(TypeAwareAllocationMode::No),
22752275
PassAlignment(PassAlignment) {}
2276-
QualType Type;
2277-
TypeAwareAllocationMode PassTypeIdentity;
2278-
AlignedAllocationMode PassAlignment;
2276+
22792277
unsigned getNumImplicitArgs() const {
22802278
unsigned Count = 1; // Size
22812279
if (isTypeAwareAllocation(PassTypeIdentity))
@@ -2285,33 +2283,35 @@ struct ImplicitAllocationParameters {
22852283
return Count;
22862284
}
22872285
bool isValid() const {
2286+
if (!Type.isNull() && Type.hasQualifiers())
2287+
return false;
22882288
if (!isTypeAwareAllocation(PassTypeIdentity))
22892289
return true;
22902290
return !Type.isNull();
22912291
}
2292+
2293+
QualType Type;
2294+
TypeAwareAllocationMode PassTypeIdentity;
2295+
AlignedAllocationMode PassAlignment;
22922296
};
22932297

22942298
struct ImplicitDeallocationParameters {
2295-
ImplicitDeallocationParameters(QualType Type,
2299+
ImplicitDeallocationParameters(QualType DeallocType,
22962300
TypeAwareAllocationMode PassTypeIdentity,
22972301
AlignedAllocationMode PassAlignment,
22982302
SizedDeallocationMode PassSize)
2299-
: Type(Type.isNull() ? Type : Type.getUnqualifiedType()),
2300-
PassTypeIdentity(PassTypeIdentity), PassAlignment(PassAlignment),
2301-
PassSize(PassSize) {
2302-
if (Type.isNull())
2303-
assert(!isTypeAwareAllocation(PassTypeIdentity));
2304-
assert(!Type.isNull());
2303+
: Type(DeallocType), PassTypeIdentity(PassTypeIdentity),
2304+
PassAlignment(PassAlignment), PassSize(PassSize) {
2305+
if (!Type.isNull())
2306+
Type = Type.getUnqualifiedType();
2307+
assert(isValid());
23052308
}
23062309

23072310
ImplicitDeallocationParameters(AlignedAllocationMode PassAlignment,
23082311
SizedDeallocationMode PassSize)
23092312
: PassTypeIdentity(TypeAwareAllocationMode::No),
23102313
PassAlignment(PassAlignment), PassSize(PassSize) {}
2311-
QualType Type;
2312-
TypeAwareAllocationMode PassTypeIdentity;
2313-
AlignedAllocationMode PassAlignment;
2314-
SizedDeallocationMode PassSize;
2314+
23152315
unsigned getNumImplicitArgs() const {
23162316
unsigned Count = 1; // Size
23172317
if (isTypeAwareAllocation(PassTypeIdentity))
@@ -2323,10 +2323,19 @@ struct ImplicitDeallocationParameters {
23232323
return Count;
23242324
}
23252325
bool isValid() const {
2326+
if (!Type.isNull()) {
2327+
assert(!Type.hasQualifiers());
2328+
return !Type.hasQualifiers();
2329+
}
23262330
if (!isTypeAwareAllocation(PassTypeIdentity))
23272331
return true;
23282332
return !Type.isNull();
23292333
}
2334+
2335+
QualType Type;
2336+
TypeAwareAllocationMode PassTypeIdentity;
2337+
AlignedAllocationMode PassAlignment;
2338+
SizedDeallocationMode PassSize;
23302339
};
23312340

23322341
/// Represents a new-expression for memory allocation and constructor

clang/include/clang/Basic/DiagnosticGroups.td

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -636,7 +636,6 @@ def Packed : DiagGroup<"packed", [PackedNonPod]>;
636636
def PaddedBitField : DiagGroup<"padded-bitfield">;
637637
def Padded : DiagGroup<"padded", [PaddedBitField]>;
638638
def UnalignedAccess : DiagGroup<"unaligned-access">;
639-
def StrictTypeAwareAllocators : DiagGroup<"strict-type-aware-allocators">;
640639

641640
def PessimizingMove : DiagGroup<"pessimizing-move">;
642641
def ReturnStdMove : DiagGroup<"return-std-move">;

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9768,40 +9768,40 @@ def err_operator_new_delete_invalid_result_type : Error<
97689768
def err_operator_new_delete_dependent_result_type : Error<
97699769
"%0 cannot have a dependent return type; use %1 instead">;
97709770
def err_operator_new_delete_too_few_parameters : Error<
9771-
"%select{|type aware }0%1 must have at least %select{|one|two|three|four}2 parameter%s2">;
9771+
"%select{|type aware }0%select{|destroying }1%2 must have at least %select{|one|two|three|four|five}3 parameter%s3">;
97729772
def err_operator_new_delete_template_too_few_parameters : Error<
97739773
"%0 template must have at least two parameters">;
97749774
def warn_operator_new_returns_null : Warning<
97759775
"%0 should not return a null pointer unless it is declared 'throw()'"
97769776
"%select{| or 'noexcept'}1">, InGroup<OperatorNewReturnsNull>;
97779777

97789778
def err_operator_new_dependent_param_type : Error<
9779-
"%select{|type aware }0%1 cannot take a dependent type as %select{first|second|third|fourth}2 parameter; "
9780-
"use %4 (%3) instead">;
9779+
"%select{|type aware }0%select{|destroying }1%2 cannot take a dependent type as its %select{first|second|third|fourth|fifth}3 parameter; "
9780+
"use %5 (%4) instead">;
97819781
def err_operator_new_param_type : Error<
9782-
"%select{|type aware }0%1 takes type %4 (%3) as %select{first|second|third|fourth}2 parameter">;
9782+
"%select{|type aware }0%select{|destroying }1%2 takes type %5 (%4) as %select{first|second|third|fourth|fifth}3 parameter">;
97839783
def err_operator_new_default_arg: Error<
97849784
"parameter of %0 cannot have a default argument">;
97859785
def err_operator_delete_dependent_param_type : Error<
9786-
"%select{|type aware }0%1 cannot take a dependent type as %select{first|second|third|fourth}2 parameter; "
9787-
"use %3 instead">;
9786+
"%select{|type aware }0%select{|destroying }1%2 cannot take a dependent type as its %select{first|second|third|fourth|fifth}3 parameter; "
9787+
"use %4 instead">;
97889788
def err_operator_delete_param_type : Error<
9789-
"%select{first|second|third|fourth}2 parameter of%select{| type aware}0 %1 must have type %3">;
9789+
"%select{first|second|third|fourth|fifth}3 parameter of%select{| type aware}0%select{| destroying}1 %2 must have type %4">;
97909790
def err_destroying_operator_delete_not_usual : Error<
97919791
"destroying operator delete can have only an optional size and optional "
97929792
"alignment parameter">;
97939793
def err_type_aware_destroying_operator_delete : Error<
97949794
"type aware destroying delete is not permitted, enable with '-fexperimental-cxx-type-aware-destroying-delete'">;
97959795
def err_unsupported_type_aware_allocator : Error<
97969796
"type aware allocation operators are disabled, enable with '-fexperimental-cxx-type-aware-allocators'">;
9797-
def warn_type_aware_cleanup_deallocator_context_mismatch : Warning<
9798-
"type aware %0 requires matching %1 in %2">,
9799-
InGroup<StrictTypeAwareAllocators>, DefaultError;
9797+
def err_no_type_aware_cleanup_operator_delete : Error<
9798+
"type aware %0 requires matching cleanup %1 in %2">;
9799+
def err_type_aware_cleanup_deallocator_context_mismatch : Error<
9800+
"type aware %0 requires matching %1 in %2">;
98009801
def note_type_aware_operator_found : Note<
98019802
"type aware %0 found in %1">;
9802-
def warn_mismatching_type_aware_cleanup_deallocator : Warning<
9803-
"mismatched type aware allocation operators for constructor cleanup">,
9804-
InGroup<StrictTypeAwareAllocators>;
9803+
def err_mismatching_type_aware_cleanup_deallocator : Error<
9804+
"mismatched type aware allocation operators for constructor cleanup">;
98059805
def note_type_aware_operator_declared : Note<
98069806
"%select{|non-}0type aware %1 declared here">;
98079807
def note_implicit_delete_this_in_destructor_here : Note<

clang/include/clang/Sema/Sema.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8239,10 +8239,9 @@ class Sema final : public SemaBase {
82398239

82408240
bool FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
82418241
DeclarationName Name, FunctionDecl *&Operator,
8242-
QualType DeallocType,
82438242
ImplicitDeallocationParameters,
82448243
bool Diagnose = true);
8245-
FunctionDecl *FindUsualDeallocationFunction(QualType, SourceLocation StartLoc,
8244+
FunctionDecl *FindUsualDeallocationFunction(SourceLocation StartLoc,
82468245
ImplicitDeallocationParameters,
82478246
DeclarationName Name);
82488247
FunctionDecl *FindDeallocationFunctionForDestructor(SourceLocation StartLoc,

clang/lib/AST/ByteCode/Interp.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1575,7 +1575,8 @@ bool InvalidNewDeleteExpr(InterpState &S, CodePtr OpPC, const Expr *E) {
15751575
return true;
15761576
S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_new_placement)
15771577
<< /*C++26 feature*/ 1 << E->getSourceRange();
1578-
} else if (!OperatorNew->isConstEvalSafeOrReplaceableGlobalAllocationFunction()) {
1578+
} else if (!OperatorNew
1579+
->isConstEvalSafeOrReplaceableGlobalAllocationFunction()) {
15791580
S.FFDiag(S.Current->getSource(OpPC),
15801581
diag::note_constexpr_new_non_replaceable)
15811582
<< isa<CXXMethodDecl>(OperatorNew) << OperatorNew;
@@ -1593,7 +1594,8 @@ bool InvalidNewDeleteExpr(InterpState &S, CodePtr OpPC, const Expr *E) {
15931594
} else {
15941595
const auto *DeleteExpr = cast<CXXDeleteExpr>(E);
15951596
const FunctionDecl *OperatorDelete = DeleteExpr->getOperatorDelete();
1596-
if (!OperatorDelete->isConstEvalSafeOrReplaceableGlobalAllocationFunction()) {
1597+
if (!OperatorDelete
1598+
->isConstEvalSafeOrReplaceableGlobalAllocationFunction()) {
15971599
S.FFDiag(S.Current->getSource(OpPC),
15981600
diag::note_constexpr_new_non_replaceable)
15991601
<< isa<CXXMethodDecl>(OperatorDelete) << OperatorDelete;

clang/lib/CodeGen/CGExprCXX.cpp

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1445,6 +1445,7 @@ namespace {
14451445
LLVM_PREFERRED_TYPE(TypeAwareAllocationMode)
14461446
unsigned PassTypeToPlacementDelete : 1;
14471447
const FunctionDecl *OperatorDelete;
1448+
RValueTy TypeIdentity;
14481449
ValueTy Ptr;
14491450
ValueTy AllocSize;
14501451
CharUnits AllocAlign;
@@ -1459,15 +1460,15 @@ namespace {
14591460
}
14601461

14611462
CallDeleteDuringNew(size_t NumPlacementArgs,
1462-
const FunctionDecl *OperatorDelete, ValueTy Ptr,
1463-
ValueTy AllocSize,
1463+
const FunctionDecl *OperatorDelete,
1464+
RValueTy TypeIdentity, ValueTy Ptr, ValueTy AllocSize,
14641465
const ImplicitAllocationParameters &IAP,
14651466
CharUnits AllocAlign)
14661467
: NumPlacementArgs(NumPlacementArgs),
14671468
PassAlignmentToPlacementDelete(
14681469
isAlignedAllocation(IAP.PassAlignment)),
1469-
OperatorDelete(OperatorDelete), Ptr(Ptr), AllocSize(AllocSize),
1470-
AllocAlign(AllocAlign) {}
1470+
OperatorDelete(OperatorDelete), TypeIdentity(TypeIdentity), Ptr(Ptr),
1471+
AllocSize(AllocSize), AllocAlign(AllocAlign) {}
14711472

14721473
void setPlacementArg(unsigned I, RValueTy Arg, QualType Type) {
14731474
assert(I < NumPlacementArgs && "index out of range");
@@ -1484,10 +1485,7 @@ namespace {
14841485
TypeAwareDeallocation = TypeAwareAllocationMode::Yes;
14851486
QualType SpecializedTypeIdentity = FPT->getParamType(0);
14861487
++FirstNonTypeArg;
1487-
CXXScalarValueInitExpr TypeIdentityParam(SpecializedTypeIdentity,
1488-
nullptr, SourceLocation());
1489-
DeleteArgs.add(CGF.EmitAnyExprToTemp(&TypeIdentityParam),
1490-
SpecializedTypeIdentity);
1488+
DeleteArgs.add(Traits::get(CGF, TypeIdentity), SpecializedTypeIdentity);
14911489
}
14921490
// The first non type tag argument is always a void* (or C* for a
14931491
// destroying operator delete for class type C).
@@ -1501,6 +1499,7 @@ namespace {
15011499
Params.Alignment =
15021500
alignedAllocationModeFromBool(PassAlignmentToPlacementDelete);
15031501
Params.TypeAwareDelete = TypeAwareDeallocation;
1502+
Params.Size = isTypeAwareAllocation(Params.TypeAwareDelete);
15041503
} else {
15051504
// For a non-placement new-expression, 'operator delete' can take a
15061505
// size and/or an alignment if it has the right parameters.
@@ -1538,11 +1537,9 @@ namespace {
15381537

15391538
/// Enter a cleanup to call 'operator delete' if the initializer in a
15401539
/// new-expression throws.
1541-
static void EnterNewDeleteCleanup(CodeGenFunction &CGF,
1542-
const CXXNewExpr *E,
1543-
Address NewPtr,
1544-
llvm::Value *AllocSize,
1545-
CharUnits AllocAlign,
1540+
static void EnterNewDeleteCleanup(CodeGenFunction &CGF, const CXXNewExpr *E,
1541+
RValue TypeIdentity, Address NewPtr,
1542+
llvm::Value *AllocSize, CharUnits AllocAlign,
15461543
const CallArgList &NewArgs) {
15471544
unsigned NumNonPlacementArgs = E->getNumImplicitArgs();
15481545

@@ -1560,7 +1557,7 @@ static void EnterNewDeleteCleanup(CodeGenFunction &CGF,
15601557

15611558
DirectCleanup *Cleanup = CGF.EHStack.pushCleanupWithExtra<DirectCleanup>(
15621559
EHCleanup, E->getNumPlacementArgs(), E->getOperatorDelete(),
1563-
NewPtr.emitRawPointer(CGF), AllocSize,
1560+
TypeIdentity, NewPtr.emitRawPointer(CGF), AllocSize,
15641561
E->implicitAllocationParameters(), AllocAlign);
15651562
for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I) {
15661563
auto &Arg = NewArgs[I + NumNonPlacementArgs];
@@ -1575,7 +1572,8 @@ static void EnterNewDeleteCleanup(CodeGenFunction &CGF,
15751572
DominatingValue<RValue>::save(CGF, RValue::get(NewPtr, CGF));
15761573
DominatingValue<RValue>::saved_type SavedAllocSize =
15771574
DominatingValue<RValue>::save(CGF, RValue::get(AllocSize));
1578-
1575+
DominatingValue<RValue>::saved_type SavedTypeIdentity =
1576+
DominatingValue<RValue>::save(CGF, TypeIdentity);
15791577
struct ConditionalCleanupTraits {
15801578
typedef DominatingValue<RValue>::saved_type ValueTy;
15811579
typedef DominatingValue<RValue>::saved_type RValueTy;
@@ -1588,8 +1586,8 @@ static void EnterNewDeleteCleanup(CodeGenFunction &CGF,
15881586
ConditionalCleanup *Cleanup =
15891587
CGF.EHStack.pushCleanupWithExtra<ConditionalCleanup>(
15901588
EHCleanup, E->getNumPlacementArgs(), E->getOperatorDelete(),
1591-
SavedNewPtr, SavedAllocSize, E->implicitAllocationParameters(),
1592-
AllocAlign);
1589+
SavedTypeIdentity, SavedNewPtr, SavedAllocSize,
1590+
E->implicitAllocationParameters(), AllocAlign);
15931591
for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I) {
15941592
auto &Arg = NewArgs[I + NumNonPlacementArgs];
15951593
Cleanup->setPlacementArg(
@@ -1636,6 +1634,7 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
16361634
// operator, just "inline" it directly.
16371635
Address allocation = Address::invalid();
16381636
CallArgList allocatorArgs;
1637+
RValue TypeIdentityArg;
16391638
if (allocator->isReservedGlobalPlacementOperator()) {
16401639
assert(E->getNumPlacementArgs() == 1);
16411640
const Expr *arg = *E->placement_arguments().begin();
@@ -1666,8 +1665,8 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
16661665
QualType SpecializedTypeIdentity = allocatorType->getParamType(0);
16671666
CXXScalarValueInitExpr TypeIdentityParam(SpecializedTypeIdentity, nullptr,
16681667
SourceLocation());
1669-
allocatorArgs.add(EmitAnyExprToTemp(&TypeIdentityParam),
1670-
SpecializedTypeIdentity);
1668+
TypeIdentityArg = EmitAnyExprToTemp(&TypeIdentityParam);
1669+
allocatorArgs.add(TypeIdentityArg, SpecializedTypeIdentity);
16711670
++ParamsToSkip;
16721671
++IndexOfAlignArg;
16731672
}
@@ -1762,8 +1761,8 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
17621761
llvm::Instruction *cleanupDominator = nullptr;
17631762
if (E->getOperatorDelete() &&
17641763
!E->getOperatorDelete()->isReservedGlobalPlacementOperator()) {
1765-
EnterNewDeleteCleanup(*this, E, allocation, allocSize, allocAlign,
1766-
allocatorArgs);
1764+
EnterNewDeleteCleanup(*this, E, TypeIdentityArg, allocation, allocSize,
1765+
allocAlign, allocatorArgs);
17671766
operatorDeleteCleanup = EHStack.stable_begin();
17681767
cleanupDominator = Builder.CreateUnreachable();
17691768
}

clang/lib/Sema/SemaCoroutine.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1141,7 +1141,7 @@ static bool findDeleteForPromise(Sema &S, SourceLocation Loc, QualType PromiseTy
11411141
ImplicitDeallocationParameters IDP = {
11421142
alignedAllocationModeFromBool(Overaligned), SizedDeallocationMode::Yes};
11431143
if (S.FindDeallocationFunction(Loc, PointeeRD, DeleteName, OperatorDelete,
1144-
PromiseType, IDP, /*Diagnose*/ true))
1144+
IDP, /*Diagnose*/ true))
11451145
return false;
11461146

11471147
// [dcl.fct.def.coroutine]p12
@@ -1157,8 +1157,7 @@ static bool findDeleteForPromise(Sema &S, SourceLocation Loc, QualType PromiseTy
11571157
// parameter if failed.
11581158
// Coroutines can always provide their required size.
11591159
IDP.PassSize = SizedDeallocationMode::Yes;
1160-
OperatorDelete =
1161-
S.FindUsualDeallocationFunction(PromiseType, Loc, IDP, DeleteName);
1160+
OperatorDelete = S.FindUsualDeallocationFunction(Loc, IDP, DeleteName);
11621161

11631162
if (!OperatorDelete)
11641163
return false;

0 commit comments

Comments
 (0)