https://github.com/rturrado updated https://github.com/llvm/llvm-project/pull/186617
>From 51fdc97ed9af90f1b801e614c667bf95eb4cb210 Mon Sep 17 00:00:00 2001 From: rturrado <[email protected]> Date: Fri, 13 Mar 2026 16:12:29 +0100 Subject: [PATCH 1/3] Initial commit --- clang/lib/Sema/SemaExprCXX.cpp | 56 +++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 5a5bbf4d900dc..3b9e2f3d16e0f 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -2146,6 +2146,7 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, SourceRange DirectInitRange, Expr *Initializer) { SourceRange TypeRange = AllocTypeInfo->getTypeLoc().getSourceRange(); SourceLocation StartLoc = Range.getBegin(); + Expr *ArraySizeExprPtr = ArraySize.value_or(nullptr); CXXNewInitializationStyle InitStyle; if (DirectInitRange.isValid()) { @@ -2199,12 +2200,16 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, auto *Deduced = AllocType->getContainedDeducedType(); if (Deduced && !Deduced->isDeduced() && isa<DeducedTemplateSpecializationType>(Deduced)) { - if (ArraySize) + if (ArraySize) { + SourceLocation ArraySizeExprLoc = ArraySizeExprPtr + ? ArraySizeExprPtr->getExprLoc() : TypeRange.getBegin(); + SourceRange ArraySizeExprRange = ArraySizeExprPtr + ? ArraySizeExprPtr->getSourceRange() : TypeRange; return ExprError( - Diag(*ArraySize ? (*ArraySize)->getExprLoc() : TypeRange.getBegin(), - diag::err_deduced_class_template_compound_type) - << /*array*/ 2 - << (*ArraySize ? (*ArraySize)->getSourceRange() : TypeRange)); + Diag(ArraySizeExprLoc, diag::err_deduced_class_template_compound_type) + << /*array*/ 2 + << ArraySizeExprRange); + } InitializedEntity Entity = InitializedEntity::InitializeNew(StartLoc, AllocType, @@ -2263,6 +2268,7 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, ArraySize = IntegerLiteral::Create(Context, Array->getSize(), Context.getSizeType(), TypeRange.getEnd()); + ArraySizeExprPtr = ArraySize.value_or(nullptr); AllocType = Array->getElementType(); } } @@ -2283,11 +2289,12 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, QualType ResultType = Context.getPointerType(AllocType); - if (ArraySize && *ArraySize && - (*ArraySize)->getType()->isNonOverloadPlaceholderType()) { - ExprResult result = CheckPlaceholderExpr(*ArraySize); + if (ArraySizeExprPtr && + ArraySizeExprPtr->getType()->isNonOverloadPlaceholderType()) { + ExprResult result = CheckPlaceholderExpr(ArraySizeExprPtr); if (result.isInvalid()) return ExprError(); ArraySize = result.get(); + ArraySizeExprPtr = ArraySize.value_or(nullptr); } // C++98 5.3.4p6: "The expression in a direct-new-declarator shall have // integral or enumeration type with a non-negative value." @@ -2297,18 +2304,18 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, // C++1y [expr.new]p6: The expression [...] is implicitly converted to // std::size_t. std::optional<uint64_t> KnownArraySize; - if (ArraySize && *ArraySize && !(*ArraySize)->isTypeDependent()) { + if (ArraySizeExprPtr && !ArraySizeExprPtr->isTypeDependent()) { ExprResult ConvertedSize; if (getLangOpts().CPlusPlus14) { assert(Context.getTargetInfo().getIntWidth() && "Builtin type of size 0?"); ConvertedSize = PerformImplicitConversion( - *ArraySize, Context.getSizeType(), AssignmentAction::Converting); + ArraySizeExprPtr, Context.getSizeType(), AssignmentAction::Converting); - if (!ConvertedSize.isInvalid() && (*ArraySize)->getType()->isRecordType()) + if (!ConvertedSize.isInvalid() && ArraySizeExprPtr->getType()->isRecordType()) // Diagnose the compatibility of this conversion. Diag(StartLoc, diag::warn_cxx98_compat_array_size_conversion) - << (*ArraySize)->getType() << 0 << "'size_t'"; + << ArraySizeExprPtr->getType() << 0 << "'size_t'"; } else { class SizeConvertDiagnoser : public ICEConvertDiagnoser { protected: @@ -2362,16 +2369,17 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, : diag::ext_array_size_conversion) << T << ConvTy->isEnumeralType() << ConvTy; } - } SizeDiagnoser(*ArraySize); + } SizeDiagnoser(ArraySizeExprPtr); - ConvertedSize = PerformContextualImplicitConversion(StartLoc, *ArraySize, + ConvertedSize = PerformContextualImplicitConversion(StartLoc, ArraySizeExprPtr, SizeDiagnoser); } if (ConvertedSize.isInvalid()) return ExprError(); ArraySize = ConvertedSize.get(); - QualType SizeType = (*ArraySize)->getType(); + ArraySizeExprPtr = ArraySize.value(); + QualType SizeType = ArraySizeExprPtr->getType(); if (!SizeType->isIntegralOrUnscopedEnumerationType()) return ExprError(); @@ -2390,11 +2398,11 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, // converting to size_t. This will never find a negative array size in // C++14 onwards, because Value is always unsigned here! if (std::optional<llvm::APSInt> Value = - (*ArraySize)->getIntegerConstantExpr(Context)) { + ArraySizeExprPtr->getIntegerConstantExpr(Context)) { if (Value->isSigned() && Value->isNegative()) { - return ExprError(Diag((*ArraySize)->getBeginLoc(), + return ExprError(Diag(ArraySizeExprPtr->getBeginLoc(), diag::err_typecheck_negative_array_size) - << (*ArraySize)->getSourceRange()); + << ArraySizeExprPtr->getSourceRange()); } if (!AllocType->isDependentType()) { @@ -2402,18 +2410,18 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, ConstantArrayType::getNumAddressingBits(Context, AllocType, *Value); if (ActiveSizeBits > ConstantArrayType::getMaxSizeBits(Context)) return ExprError( - Diag((*ArraySize)->getBeginLoc(), diag::err_array_too_large) + Diag(ArraySizeExprPtr->getBeginLoc(), diag::err_array_too_large) << toString(*Value, 10, Value->isSigned(), /*formatAsCLiteral=*/false, /*UpperCase=*/false, /*InsertSeparators=*/true) - << (*ArraySize)->getSourceRange()); + << ArraySizeExprPtr->getSourceRange()); } KnownArraySize = Value->getZExtValue(); } else if (TypeIdParens.isValid()) { // Can't have dynamic array size when the type-id is in parentheses. - Diag((*ArraySize)->getBeginLoc(), diag::ext_new_paren_array_nonconst) - << (*ArraySize)->getSourceRange() + Diag(ArraySizeExprPtr->getBeginLoc(), diag::ext_new_paren_array_nonconst) + << ArraySizeExprPtr->getSourceRange() << FixItHint::CreateRemoval(TypeIdParens.getBegin()) << FixItHint::CreateRemoval(TypeIdParens.getEnd()); @@ -2583,7 +2591,7 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, AllocType, llvm::APInt(Context.getTypeSize(Context.getSizeType()), *KnownArraySize), - *ArraySize, ArraySizeModifier::Normal, 0); + ArraySizeExprPtr, ArraySizeModifier::Normal, 0); else if (ArraySize) InitType = Context.getIncompleteArrayType(AllocType, ArraySizeModifier::Normal, 0); @@ -2610,7 +2618,7 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, // FIXME: If we have a KnownArraySize, check that the array bound of the // initializer is no greater than that constant value. - if (ArraySize && !*ArraySize) { + if (ArraySize && !ArraySizeExprPtr) { auto *CAT = Context.getAsConstantArrayType(Initializer->getType()); if (CAT) { // FIXME: Track that the array size was inferred rather than explicitly >From 259e4f62842c1fa6885eee7dcf152c18b4ad1d78 Mon Sep 17 00:00:00 2001 From: rturrado <[email protected]> Date: Tue, 17 Mar 2026 19:33:45 +0100 Subject: [PATCH 2/3] Refactor using a few bool variables --- clang/lib/Sema/SemaExprCXX.cpp | 86 +++++++++++++++++----------------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 3b9e2f3d16e0f..12cc1730cf869 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -2146,7 +2146,6 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, SourceRange DirectInitRange, Expr *Initializer) { SourceRange TypeRange = AllocTypeInfo->getTypeLoc().getSourceRange(); SourceLocation StartLoc = Range.getBegin(); - Expr *ArraySizeExprPtr = ArraySize.value_or(nullptr); CXXNewInitializationStyle InitStyle; if (DirectInitRange.isValid()) { @@ -2201,14 +2200,13 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, if (Deduced && !Deduced->isDeduced() && isa<DeducedTemplateSpecializationType>(Deduced)) { if (ArraySize) { - SourceLocation ArraySizeExprLoc = ArraySizeExprPtr - ? ArraySizeExprPtr->getExprLoc() : TypeRange.getBegin(); - SourceRange ArraySizeExprRange = ArraySizeExprPtr - ? ArraySizeExprPtr->getSourceRange() : TypeRange; + SourceLocation ArraySizeExprLoc = + *ArraySize ? (*ArraySize)->getExprLoc() : TypeRange.getBegin(); + SourceRange ArraySizeSourceRange = + *ArraySize ? (*ArraySize)->getSourceRange() : TypeRange; return ExprError( - Diag(ArraySizeExprLoc, diag::err_deduced_class_template_compound_type) - << /*array*/ 2 - << ArraySizeExprRange); + Diag(ArraySizeExprLoc, diag::err_deduced_class_template_compound_type) + << /*array*/ 2 << ArraySizeSourceRange); } InitializedEntity Entity = @@ -2265,10 +2263,8 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, if (!ArraySize && !AllocType->isDependentType()) { if (const ConstantArrayType *Array = Context.getAsConstantArrayType(AllocType)) { - ArraySize = IntegerLiteral::Create(Context, Array->getSize(), - Context.getSizeType(), - TypeRange.getEnd()); - ArraySizeExprPtr = ArraySize.value_or(nullptr); + ArraySize = IntegerLiteral::Create( + Context, Array->getSize(), Context.getSizeType(), TypeRange.getEnd()); AllocType = Array->getElementType(); } } @@ -2289,12 +2285,12 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, QualType ResultType = Context.getPointerType(AllocType); - if (ArraySizeExprPtr && - ArraySizeExprPtr->getType()->isNonOverloadPlaceholderType()) { - ExprResult result = CheckPlaceholderExpr(ArraySizeExprPtr); - if (result.isInvalid()) return ExprError(); - ArraySize = result.get(); - ArraySizeExprPtr = ArraySize.value_or(nullptr); + bool IsArraySizeNonOverloadPlaceholderType = + *ArraySize && (*ArraySize)->getType()->isNonOverloadPlaceholderType(); + if (IsArraySizeNonOverloadPlaceholderType) { + ExprResult result = CheckPlaceholderExpr(*ArraySize); + if (result.isInvalid()) + return ExprError(); } // C++98 5.3.4p6: "The expression in a direct-new-declarator shall have // integral or enumeration type with a non-negative value." @@ -2304,18 +2300,20 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, // C++1y [expr.new]p6: The expression [...] is implicitly converted to // std::size_t. std::optional<uint64_t> KnownArraySize; - if (ArraySizeExprPtr && !ArraySizeExprPtr->isTypeDependent()) { + bool IsArraySizeNotTypeDependent = + *ArraySize && !(*ArraySize)->isTypeDependent(); + if (IsArraySizeNotTypeDependent) { ExprResult ConvertedSize; if (getLangOpts().CPlusPlus14) { assert(Context.getTargetInfo().getIntWidth() && "Builtin type of size 0?"); ConvertedSize = PerformImplicitConversion( - ArraySizeExprPtr, Context.getSizeType(), AssignmentAction::Converting); + *ArraySize, Context.getSizeType(), AssignmentAction::Converting); - if (!ConvertedSize.isInvalid() && ArraySizeExprPtr->getType()->isRecordType()) + if (!ConvertedSize.isInvalid() && (*ArraySize)->getType()->isRecordType()) // Diagnose the compatibility of this conversion. Diag(StartLoc, diag::warn_cxx98_compat_array_size_conversion) - << ArraySizeExprPtr->getType() << 0 << "'size_t'"; + << (*ArraySize)->getType() << 0 << "'size_t'"; } else { class SizeConvertDiagnoser : public ICEConvertDiagnoser { protected: @@ -2369,19 +2367,17 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, : diag::ext_array_size_conversion) << T << ConvTy->isEnumeralType() << ConvTy; } - } SizeDiagnoser(ArraySizeExprPtr); + } SizeDiagnoser(*ArraySize); - ConvertedSize = PerformContextualImplicitConversion(StartLoc, ArraySizeExprPtr, + ConvertedSize = PerformContextualImplicitConversion(StartLoc, *ArraySize, SizeDiagnoser); } if (ConvertedSize.isInvalid()) return ExprError(); ArraySize = ConvertedSize.get(); - ArraySizeExprPtr = ArraySize.value(); - QualType SizeType = ArraySizeExprPtr->getType(); - - if (!SizeType->isIntegralOrUnscopedEnumerationType()) + QualType ArraySizeType = (*ArraySize)->getType(); + if (!ArraySizeType->isIntegralOrUnscopedEnumerationType()) return ExprError(); // C++98 [expr.new]p7: @@ -2397,31 +2393,33 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, // FIXME: Per CWG1464, we are required to check the value prior to // converting to size_t. This will never find a negative array size in // C++14 onwards, because Value is always unsigned here! + SourceLocation ArraySizeBeginLoc = (*ArraySize)->getBeginLoc(); + SourceRange ArraySizeSourceRange = (*ArraySize)->getSourceRange(); if (std::optional<llvm::APSInt> Value = - ArraySizeExprPtr->getIntegerConstantExpr(Context)) { + (*ArraySize)->getIntegerConstantExpr(Context)) { if (Value->isSigned() && Value->isNegative()) { - return ExprError(Diag(ArraySizeExprPtr->getBeginLoc(), - diag::err_typecheck_negative_array_size) - << ArraySizeExprPtr->getSourceRange()); + return ExprError( + Diag(ArraySizeBeginLoc, diag::err_typecheck_negative_array_size) + << ArraySizeSourceRange); } if (!AllocType->isDependentType()) { unsigned ActiveSizeBits = ConstantArrayType::getNumAddressingBits(Context, AllocType, *Value); if (ActiveSizeBits > ConstantArrayType::getMaxSizeBits(Context)) - return ExprError( - Diag(ArraySizeExprPtr->getBeginLoc(), diag::err_array_too_large) - << toString(*Value, 10, Value->isSigned(), - /*formatAsCLiteral=*/false, /*UpperCase=*/false, - /*InsertSeparators=*/true) - << ArraySizeExprPtr->getSourceRange()); + return ExprError(Diag(ArraySizeBeginLoc, diag::err_array_too_large) + << toString(*Value, 10, Value->isSigned(), + /*formatAsCLiteral=*/false, + /*UpperCase=*/false, + /*InsertSeparators=*/true) + << ArraySizeSourceRange); } KnownArraySize = Value->getZExtValue(); } else if (TypeIdParens.isValid()) { // Can't have dynamic array size when the type-id is in parentheses. - Diag(ArraySizeExprPtr->getBeginLoc(), diag::ext_new_paren_array_nonconst) - << ArraySizeExprPtr->getSourceRange() + Diag(ArraySizeBeginLoc, diag::ext_new_paren_array_nonconst) + << ArraySizeSourceRange << FixItHint::CreateRemoval(TypeIdParens.getBegin()) << FixItHint::CreateRemoval(TypeIdParens.getEnd()); @@ -2591,14 +2589,15 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, AllocType, llvm::APInt(Context.getTypeSize(Context.getSizeType()), *KnownArraySize), - ArraySizeExprPtr, ArraySizeModifier::Normal, 0); + *ArraySize, ArraySizeModifier::Normal, 0); else if (ArraySize) InitType = Context.getIncompleteArrayType(AllocType, ArraySizeModifier::Normal, 0); else InitType = AllocType; - bool VariableLengthArrayNew = ArraySize && *ArraySize && !KnownArraySize; + bool IsArraySizeExprNotNull = ArraySize && *ArraySize; + bool VariableLengthArrayNew = IsArraySizeExprNotNull && !KnownArraySize; InitializedEntity Entity = InitializedEntity::InitializeNew( StartLoc, InitType, VariableLengthArrayNew); InitializationSequence InitSeq(*this, Entity, Kind, Exprs); @@ -2618,7 +2617,8 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, // FIXME: If we have a KnownArraySize, check that the array bound of the // initializer is no greater than that constant value. - if (ArraySize && !ArraySizeExprPtr) { + bool IsArraySizeExprNull = ArraySize && !*ArraySize; + if (IsArraySizeExprNull) { auto *CAT = Context.getAsConstantArrayType(Initializer->getType()); if (CAT) { // FIXME: Track that the array size was inferred rather than explicitly >From 9a72ce31537c4ee40991f64e8f8aae1f9a21227c Mon Sep 17 00:00:00 2001 From: rturrado <[email protected]> Date: Thu, 19 Mar 2026 18:55:15 +0100 Subject: [PATCH 3/3] Refactor using UpdateArraySize --- clang/lib/Sema/SemaExprCXX.cpp | 68 +++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 29 deletions(-) diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 12cc1730cf869..de9b97e3a578a 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -2142,11 +2142,18 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, SourceLocation PlacementRParen, SourceRange TypeIdParens, QualType AllocType, TypeSourceInfo *AllocTypeInfo, - std::optional<Expr *> ArraySize, + std::optional<Expr *> OptArraySize, SourceRange DirectInitRange, Expr *Initializer) { SourceRange TypeRange = AllocTypeInfo->getTypeLoc().getSourceRange(); SourceLocation StartLoc = Range.getBegin(); + Expr *ArraySize = OptArraySize.value_or(nullptr); + + auto UpdateArraySize = [&](Expr *NewSize) { + OptArraySize = NewSize; + ArraySize = NewSize; + }; + CXXNewInitializationStyle InitStyle; if (DirectInitRange.isValid()) { assert(Initializer && "Have parens but no initializer."); @@ -2199,11 +2206,11 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, auto *Deduced = AllocType->getContainedDeducedType(); if (Deduced && !Deduced->isDeduced() && isa<DeducedTemplateSpecializationType>(Deduced)) { - if (ArraySize) { + if (OptArraySize) { SourceLocation ArraySizeExprLoc = - *ArraySize ? (*ArraySize)->getExprLoc() : TypeRange.getBegin(); + ArraySize ? ArraySize->getExprLoc() : TypeRange.getBegin(); SourceRange ArraySizeSourceRange = - *ArraySize ? (*ArraySize)->getSourceRange() : TypeRange; + ArraySize ? ArraySize->getSourceRange() : TypeRange; return ExprError( Diag(ArraySizeExprLoc, diag::err_deduced_class_template_compound_type) << /*array*/ 2 << ArraySizeSourceRange); @@ -2260,11 +2267,12 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, // Per C++0x [expr.new]p5, the type being constructed may be a // typedef of an array type. // Dependent case will be handled separately. - if (!ArraySize && !AllocType->isDependentType()) { + if (!OptArraySize && !AllocType->isDependentType()) { if (const ConstantArrayType *Array = Context.getAsConstantArrayType(AllocType)) { - ArraySize = IntegerLiteral::Create( + Expr *NewSize = IntegerLiteral::Create( Context, Array->getSize(), Context.getSizeType(), TypeRange.getEnd()); + UpdateArraySize(NewSize); AllocType = Array->getElementType(); } } @@ -2272,7 +2280,8 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, if (CheckAllocatedType(AllocType, TypeRange.getBegin(), TypeRange)) return ExprError(); - if (ArraySize && !checkArrayElementAlignment(AllocType, TypeRange.getBegin())) + if (OptArraySize && + !checkArrayElementAlignment(AllocType, TypeRange.getBegin())) return ExprError(); // In ARC, infer 'retaining' for the allocated @@ -2286,9 +2295,9 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, QualType ResultType = Context.getPointerType(AllocType); bool IsArraySizeNonOverloadPlaceholderType = - *ArraySize && (*ArraySize)->getType()->isNonOverloadPlaceholderType(); + ArraySize && ArraySize->getType()->isNonOverloadPlaceholderType(); if (IsArraySizeNonOverloadPlaceholderType) { - ExprResult result = CheckPlaceholderExpr(*ArraySize); + ExprResult result = CheckPlaceholderExpr(ArraySize); if (result.isInvalid()) return ExprError(); } @@ -2300,20 +2309,19 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, // C++1y [expr.new]p6: The expression [...] is implicitly converted to // std::size_t. std::optional<uint64_t> KnownArraySize; - bool IsArraySizeNotTypeDependent = - *ArraySize && !(*ArraySize)->isTypeDependent(); + bool IsArraySizeNotTypeDependent = ArraySize && !ArraySize->isTypeDependent(); if (IsArraySizeNotTypeDependent) { ExprResult ConvertedSize; if (getLangOpts().CPlusPlus14) { assert(Context.getTargetInfo().getIntWidth() && "Builtin type of size 0?"); ConvertedSize = PerformImplicitConversion( - *ArraySize, Context.getSizeType(), AssignmentAction::Converting); + ArraySize, Context.getSizeType(), AssignmentAction::Converting); - if (!ConvertedSize.isInvalid() && (*ArraySize)->getType()->isRecordType()) + if (!ConvertedSize.isInvalid() && ArraySize->getType()->isRecordType()) // Diagnose the compatibility of this conversion. Diag(StartLoc, diag::warn_cxx98_compat_array_size_conversion) - << (*ArraySize)->getType() << 0 << "'size_t'"; + << ArraySize->getType() << 0 << "'size_t'"; } else { class SizeConvertDiagnoser : public ICEConvertDiagnoser { protected: @@ -2367,16 +2375,17 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, : diag::ext_array_size_conversion) << T << ConvTy->isEnumeralType() << ConvTy; } - } SizeDiagnoser(*ArraySize); + } SizeDiagnoser(ArraySize); - ConvertedSize = PerformContextualImplicitConversion(StartLoc, *ArraySize, + ConvertedSize = PerformContextualImplicitConversion(StartLoc, ArraySize, SizeDiagnoser); } if (ConvertedSize.isInvalid()) return ExprError(); - ArraySize = ConvertedSize.get(); - QualType ArraySizeType = (*ArraySize)->getType(); + UpdateArraySize(ConvertedSize.get()); + QualType ArraySizeType = ArraySize->getType(); + if (!ArraySizeType->isIntegralOrUnscopedEnumerationType()) return ExprError(); @@ -2393,10 +2402,10 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, // FIXME: Per CWG1464, we are required to check the value prior to // converting to size_t. This will never find a negative array size in // C++14 onwards, because Value is always unsigned here! - SourceLocation ArraySizeBeginLoc = (*ArraySize)->getBeginLoc(); - SourceRange ArraySizeSourceRange = (*ArraySize)->getSourceRange(); + SourceLocation ArraySizeBeginLoc = ArraySize->getBeginLoc(); + SourceRange ArraySizeSourceRange = ArraySize->getSourceRange(); if (std::optional<llvm::APSInt> Value = - (*ArraySize)->getIntegerConstantExpr(Context)) { + ArraySize->getIntegerConstantExpr(Context)) { if (Value->isSigned() && Value->isNegative()) { return ExprError( Diag(ArraySizeBeginLoc, diag::err_typecheck_negative_array_size) @@ -2451,7 +2460,7 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, if (!AllocType->isDependentType() && !Expr::hasAnyTypeDependentArguments(PlacementArgs) && FindAllocationFunctions(StartLoc, AllocationParameterRange, Scope, Scope, - AllocType, ArraySize.has_value(), IAP, + AllocType, OptArraySize.has_value(), IAP, PlacementArgs, OperatorNew, OperatorDelete)) return ExprError(); @@ -2589,14 +2598,14 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, AllocType, llvm::APInt(Context.getTypeSize(Context.getSizeType()), *KnownArraySize), - *ArraySize, ArraySizeModifier::Normal, 0); - else if (ArraySize) + ArraySize, ArraySizeModifier::Normal, 0); + else if (OptArraySize) InitType = Context.getIncompleteArrayType(AllocType, ArraySizeModifier::Normal, 0); else InitType = AllocType; - bool IsArraySizeExprNotNull = ArraySize && *ArraySize; + bool IsArraySizeExprNotNull = OptArraySize && ArraySize; bool VariableLengthArrayNew = IsArraySizeExprNotNull && !KnownArraySize; InitializedEntity Entity = InitializedEntity::InitializeNew( StartLoc, InitType, VariableLengthArrayNew); @@ -2617,14 +2626,15 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, // FIXME: If we have a KnownArraySize, check that the array bound of the // initializer is no greater than that constant value. - bool IsArraySizeExprNull = ArraySize && !*ArraySize; + bool IsArraySizeExprNull = OptArraySize && !ArraySize; if (IsArraySizeExprNull) { auto *CAT = Context.getAsConstantArrayType(Initializer->getType()); if (CAT) { // FIXME: Track that the array size was inferred rather than explicitly // specified. - ArraySize = IntegerLiteral::Create( + Expr *NewSize = IntegerLiteral::Create( Context, CAT->getSize(), Context.getSizeType(), TypeRange.getEnd()); + UpdateArraySize(NewSize); } else { Diag(TypeRange.getEnd(), diag::err_new_array_size_unknown_from_init) << Initializer->getSourceRange(); @@ -2652,14 +2662,14 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, // for compatibility. if (const CXXConstructExpr *CCE = dyn_cast_or_null<CXXConstructExpr>(Initializer); - CCE && ArraySize) { + CCE && OptArraySize) { Context.setClassNeedsVectorDeletingDestructor( CCE->getConstructor()->getParent()); } return CXXNewExpr::Create(Context, UseGlobal, OperatorNew, OperatorDelete, IAP, UsualArrayDeleteWantsSize, PlacementArgs, - TypeIdParens, ArraySize, InitStyle, Initializer, + TypeIdParens, OptArraySize, InitStyle, Initializer, ResultType, AllocTypeInfo, Range, DirectInitRange); } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
