aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp176
1 files changed, 131 insertions, 45 deletions
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp b/contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp
index 77bd1ab360b2..d91db60f17a0 100644
--- a/contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp
+++ b/contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp
@@ -172,7 +172,7 @@ ParsedType Sema::getDestructorName(SourceLocation TildeLoc,
bool Failed = false;
llvm::SmallVector<NamedDecl*, 8> FoundDecls;
- llvm::SmallSet<CanonicalDeclPtr<Decl>, 8> FoundDeclSet;
+ llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 8> FoundDeclSet;
// If we have an object type, it's because we are in a
// pseudo-destructor-expression or a member access expression, and
@@ -663,7 +663,16 @@ Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
}
// The operand is an expression.
- return BuildCXXTypeId(TypeInfoType, OpLoc, (Expr*)TyOrExpr, RParenLoc);
+ ExprResult Result =
+ BuildCXXTypeId(TypeInfoType, OpLoc, (Expr *)TyOrExpr, RParenLoc);
+
+ if (!getLangOpts().RTTIData && !Result.isInvalid())
+ if (auto *CTE = dyn_cast<CXXTypeidExpr>(Result.get()))
+ if (CTE->isPotentiallyEvaluated() && !CTE->isMostDerived(Context))
+ Diag(OpLoc, diag::warn_no_typeid_with_rtti_disabled)
+ << (getDiagnostics().getDiagnosticOptions().getFormat() ==
+ DiagnosticOptions::MSVC);
+ return Result;
}
/// Grabs __declspec(uuid()) off a type, or returns 0 if we cannot resolve to
@@ -875,6 +884,10 @@ ExprResult Sema::BuildCXXThrow(SourceLocation OpLoc, Expr *Ex,
Ex = Res.get();
}
+ // PPC MMA non-pointer types are not allowed as throw expr types.
+ if (Ex && Context.getTargetInfo().getTriple().isPPC64())
+ CheckPPCMMAType(Ex->getType(), Ex->getBeginLoc());
+
return new (Context)
CXXThrowExpr(Ex, Context.VoidTy, OpLoc, IsThrownVarInScope);
}
@@ -1389,6 +1402,9 @@ Sema::ActOnCXXTypeConstructExpr(ParsedType TypeRep,
if (!Result.isInvalid() && Result.get()->isInstantiationDependent() &&
!Result.get()->isTypeDependent())
Result = CorrectDelayedTyposInExpr(Result.get());
+ else if (Result.isInvalid())
+ Result = CreateRecoveryExpr(TInfo->getTypeLoc().getBeginLoc(),
+ RParenOrBraceLoc, exprs, Ty);
return Result;
}
@@ -1401,16 +1417,6 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo,
QualType Ty = TInfo->getType();
SourceLocation TyBeginLoc = TInfo->getTypeLoc().getBeginLoc();
- if (Ty->isDependentType() || CallExpr::hasAnyTypeDependentArguments(Exprs)) {
- // FIXME: CXXUnresolvedConstructExpr does not model list-initialization
- // directly. We work around this by dropping the locations of the braces.
- SourceRange Locs = ListInitialization
- ? SourceRange()
- : SourceRange(LParenOrBraceLoc, RParenOrBraceLoc);
- return CXXUnresolvedConstructExpr::Create(Context, TInfo, Locs.getBegin(),
- Exprs, Locs.getEnd());
- }
-
assert((!ListInitialization ||
(Exprs.size() == 1 && isa<InitListExpr>(Exprs[0]))) &&
"List initialization must have initializer list as expression.");
@@ -1439,6 +1445,17 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo,
Entity = InitializedEntity::InitializeTemporary(TInfo, Ty);
}
+ if (Ty->isDependentType() || CallExpr::hasAnyTypeDependentArguments(Exprs)) {
+ // FIXME: CXXUnresolvedConstructExpr does not model list-initialization
+ // directly. We work around this by dropping the locations of the braces.
+ SourceRange Locs = ListInitialization
+ ? SourceRange()
+ : SourceRange(LParenOrBraceLoc, RParenOrBraceLoc);
+ return CXXUnresolvedConstructExpr::Create(Context, Ty.getNonReferenceType(),
+ TInfo, Locs.getBegin(), Exprs,
+ Locs.getEnd());
+ }
+
// C++ [expr.type.conv]p1:
// If the expression list is a parenthesized single expression, the type
// conversion expression is equivalent (in definedness, and if defined in
@@ -1500,7 +1517,8 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo,
: SourceRange(LParenOrBraceLoc, RParenOrBraceLoc);
Result = CXXFunctionalCastExpr::Create(
Context, ResultType, Expr::getValueKindForType(Ty), TInfo, CK_NoOp,
- Result.get(), /*Path=*/nullptr, Locs.getBegin(), Locs.getEnd());
+ Result.get(), /*Path=*/nullptr, CurFPFeatureOverrides(),
+ Locs.getBegin(), Locs.getEnd());
}
return Result;
@@ -1509,9 +1527,24 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo,
bool Sema::isUsualDeallocationFunction(const CXXMethodDecl *Method) {
// [CUDA] Ignore this function, if we can't call it.
const FunctionDecl *Caller = dyn_cast<FunctionDecl>(CurContext);
- if (getLangOpts().CUDA &&
- IdentifyCUDAPreference(Caller, Method) <= CFP_WrongSide)
- return false;
+ if (getLangOpts().CUDA) {
+ auto CallPreference = IdentifyCUDAPreference(Caller, Method);
+ // If it's not callable at all, it's not the right function.
+ if (CallPreference < CFP_WrongSide)
+ return false;
+ if (CallPreference == CFP_WrongSide) {
+ // Maybe. We have to check if there are better alternatives.
+ DeclContext::lookup_result R =
+ Method->getDeclContext()->lookup(Method->getDeclName());
+ for (const auto *D : R) {
+ if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
+ if (IdentifyCUDAPreference(Caller, FD) > CFP_WrongSide)
+ return false;
+ }
+ }
+ // We've found no better variants.
+ }
+ }
SmallVector<const FunctionDecl*, 4> PreventedBy;
bool Result = Method->isUsualDeallocationFunction(PreventedBy);
@@ -1753,22 +1786,22 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
DeclaratorChunk::ArrayTypeInfo &Array = D.getTypeObject(I).Arr;
if (Expr *NumElts = (Expr *)Array.NumElts) {
if (!NumElts->isTypeDependent() && !NumElts->isValueDependent()) {
+ // FIXME: GCC permits constant folding here. We should either do so consistently
+ // or not do so at all, rather than changing behavior in C++14 onwards.
if (getLangOpts().CPlusPlus14) {
// C++1y [expr.new]p6: Every constant-expression in a noptr-new-declarator
// shall be a converted constant expression (5.19) of type std::size_t
// and shall evaluate to a strictly positive value.
- unsigned IntWidth = Context.getTargetInfo().getIntWidth();
- assert(IntWidth && "Builtin type of size 0?");
- llvm::APSInt Value(IntWidth);
+ llvm::APSInt Value(Context.getIntWidth(Context.getSizeType()));
Array.NumElts
= CheckConvertedConstantExpression(NumElts, Context.getSizeType(), Value,
- CCEK_NewExpr)
+ CCEK_ArrayBound)
.get();
} else {
- Array.NumElts
- = VerifyIntegerConstantExpression(NumElts, nullptr,
- diag::err_new_array_nonconst)
- .get();
+ Array.NumElts =
+ VerifyIntegerConstantExpression(
+ NumElts, nullptr, diag::err_new_array_nonconst, AllowFold)
+ .get();
}
if (!Array.NumElts)
return ExprError();
@@ -1832,12 +1865,13 @@ void Sema::diagnoseUnavailableAlignedAllocation(const FunctionDecl &FD,
const llvm::Triple &T = getASTContext().getTargetInfo().getTriple();
StringRef OSName = AvailabilityAttr::getPlatformNameSourceSpelling(
getASTContext().getTargetInfo().getPlatformName());
+ VersionTuple OSVersion = alignedAllocMinVersion(T.getOS());
OverloadedOperatorKind Kind = FD.getDeclName().getCXXOverloadedOperator();
bool IsDelete = Kind == OO_Delete || Kind == OO_Array_Delete;
Diag(Loc, diag::err_aligned_allocation_unavailable)
<< IsDelete << FD.getType().getAsString() << OSName
- << alignedAllocMinVersion(T.getOS()).getAsString();
+ << OSVersion.getAsString() << OSVersion.empty();
Diag(Loc, diag::note_silence_aligned_allocation_unavailable);
}
}
@@ -2073,29 +2107,29 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
// per CWG1464. Otherwise, if it's not a constant, we must have an
// unparenthesized array type.
if (!(*ArraySize)->isValueDependent()) {
- llvm::APSInt Value;
// We've already performed any required implicit conversion to integer or
// unscoped enumeration type.
// 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!
- if ((*ArraySize)->isIntegerConstantExpr(Value, Context)) {
- if (Value.isSigned() && Value.isNegative()) {
+ if (Optional<llvm::APSInt> Value =
+ (*ArraySize)->getIntegerConstantExpr(Context)) {
+ if (Value->isSigned() && Value->isNegative()) {
return ExprError(Diag((*ArraySize)->getBeginLoc(),
diag::err_typecheck_negative_array_size)
<< (*ArraySize)->getSourceRange());
}
if (!AllocType->isDependentType()) {
- unsigned ActiveSizeBits =
- ConstantArrayType::getNumAddressingBits(Context, AllocType, Value);
+ unsigned ActiveSizeBits = ConstantArrayType::getNumAddressingBits(
+ Context, AllocType, *Value);
if (ActiveSizeBits > ConstantArrayType::getMaxSizeBits(Context))
return ExprError(
Diag((*ArraySize)->getBeginLoc(), diag::err_array_too_large)
- << Value.toString(10) << (*ArraySize)->getSourceRange());
+ << Value->toString(10) << (*ArraySize)->getSourceRange());
}
- KnownArraySize = Value.getZExtValue();
+ 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)
@@ -2203,7 +2237,7 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
SizeTy, SourceLocation());
ImplicitCastExpr DesiredAlignment(ImplicitCastExpr::OnStack, AlignValT,
CK_IntegralCast, &AlignmentLiteral,
- VK_RValue);
+ VK_RValue, FPOptionsOverride());
// Adjust placement args by prepending conjured size and alignment exprs.
llvm::SmallVector<Expr *, 8> CallArgs;
@@ -2611,8 +2645,24 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
if (FoundDelete.isAmbiguous())
return true; // FIXME: clean up expressions?
+ // Filter out any destroying operator deletes. We can't possibly call such a
+ // function in this context, because we're handling the case where the object
+ // was not successfully constructed.
+ // FIXME: This is not covered by the language rules yet.
+ {
+ LookupResult::Filter Filter = FoundDelete.makeFilter();
+ while (Filter.hasNext()) {
+ auto *FD = dyn_cast<FunctionDecl>(Filter.next()->getUnderlyingDecl());
+ if (FD && FD->isDestroyingOperatorDelete())
+ Filter.erase();
+ }
+ Filter.done();
+ }
+
bool FoundGlobalDelete = FoundDelete.empty();
if (FoundDelete.empty()) {
+ FoundDelete.clear(LookupOrdinaryName);
+
if (DeleteScope == AFS_Class)
return true;
@@ -3914,7 +3964,8 @@ static ExprResult BuildCXXCastArgument(Sema &S,
// Record usage of conversion in an implicit cast.
Result = ImplicitCastExpr::Create(S.Context, Result.get()->getType(),
CK_UserDefinedConversion, Result.get(),
- nullptr, Result.get()->getValueKind());
+ nullptr, Result.get()->getValueKind(),
+ S.CurFPFeatureOverrides());
return S.MaybeBindToTemporary(Result.get());
}
@@ -4095,7 +4146,8 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
if (const AtomicType *FromAtomic = FromType->getAs<AtomicType>()) {
FromType = FromAtomic->getValueType().getUnqualifiedType();
From = ImplicitCastExpr::Create(Context, FromType, CK_AtomicToNonAtomic,
- From, /*BasePath=*/nullptr, VK_RValue);
+ From, /*BasePath=*/nullptr, VK_RValue,
+ FPOptionsOverride());
}
break;
@@ -4322,6 +4374,12 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
VK_RValue, /*BasePath=*/nullptr, CCK).get();
break;
+ case ICK_SVE_Vector_Conversion:
+ From = ImpCastExprToType(From, ToType, CK_BitCast, VK_RValue,
+ /*BasePath=*/nullptr, CCK)
+ .get();
+ break;
+
case ICK_Vector_Splat: {
// Vector splat from any arithmetic type to a vector.
Expr *Elem = prepareVectorSplat(ToType, From).get();
@@ -5465,9 +5523,9 @@ static uint64_t EvaluateArrayTypeTrait(Sema &Self, ArrayTypeTrait ATT,
case ATT_ArrayExtent: {
llvm::APSInt Value;
uint64_t Dim;
- if (Self.VerifyIntegerConstantExpression(DimExpr, &Value,
- diag::err_dimension_expr_not_constant_integer,
- false).isInvalid())
+ if (Self.VerifyIntegerConstantExpression(
+ DimExpr, &Value, diag::err_dimension_expr_not_constant_integer)
+ .isInvalid())
return 0;
if (Value.isSigned() && Value.isNegative()) {
Self.Diag(KeyLoc, diag::err_dimension_expr_not_constant_integer)
@@ -6304,6 +6362,8 @@ QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
// Similarly, attempt to find composite type of two objective-c pointers.
Composite = FindCompositeObjCPointerType(LHS, RHS, QuestionLoc);
+ if (LHS.isInvalid() || RHS.isInvalid())
+ return QualType();
if (!Composite.isNull())
return Composite;
@@ -6529,12 +6589,16 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc,
// FIXME: In C, we merge __strong and none to __strong at the top level.
if (Q1.getObjCGCAttr() == Q2.getObjCGCAttr())
Quals.setObjCGCAttr(Q1.getObjCGCAttr());
+ else if (T1->isVoidPointerType() || T2->isVoidPointerType())
+ assert(Steps.size() == 1);
else
return QualType();
// Mismatched lifetime qualifiers never compatibly include each other.
if (Q1.getObjCLifetime() == Q2.getObjCLifetime())
Quals.setObjCLifetime(Q1.getObjCLifetime());
+ else if (T1->isVoidPointerType() || T2->isVoidPointerType())
+ assert(Steps.size() == 1);
else
return QualType();
@@ -6833,7 +6897,7 @@ ExprResult Sema::MaybeBindToTemporary(Expr *E) {
CastKind ck = (ReturnsRetained ? CK_ARCConsumeObject
: CK_ARCReclaimReturnedObject);
return ImplicitCastExpr::Create(Context, E->getType(), ck, E, nullptr,
- VK_RValue);
+ VK_RValue, FPOptionsOverride());
}
if (E->getType().isDestructedType() == QualType::DK_nontrivial_c_struct)
@@ -7226,8 +7290,8 @@ ExprResult Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base,
return Base;
}
-static bool CheckArrow(Sema& S, QualType& ObjectType, Expr *&Base,
- tok::TokenKind& OpKind, SourceLocation OpLoc) {
+static bool CheckArrow(Sema &S, QualType &ObjectType, Expr *&Base,
+ tok::TokenKind &OpKind, SourceLocation OpLoc) {
if (Base->hasPlaceholderType()) {
ExprResult result = S.CheckPlaceholderExpr(Base);
if (result.isInvalid()) return true;
@@ -7242,6 +7306,18 @@ static bool CheckArrow(Sema& S, QualType& ObjectType, Expr *&Base,
// Note that this is rather different from the normal handling for the
// arrow operator.
if (OpKind == tok::arrow) {
+ // The operator requires a prvalue, so perform lvalue conversions.
+ // Only do this if we might plausibly end with a pointer, as otherwise
+ // this was likely to be intended to be a '.'.
+ if (ObjectType->isPointerType() || ObjectType->isArrayType() ||
+ ObjectType->isFunctionType()) {
+ ExprResult BaseResult = S.DefaultFunctionArrayLvalueConversion(Base);
+ if (BaseResult.isInvalid())
+ return true;
+ Base = BaseResult.get();
+ ObjectType = Base->getType();
+ }
+
if (const PointerType *Ptr = ObjectType->getAs<PointerType>()) {
ObjectType = Ptr->getPointeeType();
} else if (!Base->isTypeDependent()) {
@@ -7550,6 +7626,11 @@ ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base,
if (CheckArrow(*this, ObjectType, Base, OpKind, OpLoc))
return ExprError();
+ if (DS.getTypeSpecType() == DeclSpec::TST_decltype_auto) {
+ Diag(DS.getTypeSpecTypeLoc(), diag::err_decltype_auto_invalid);
+ return true;
+ }
+
QualType T = BuildDecltypeType(DS.getRepAsExpr(), DS.getTypeSpecTypeLoc(),
false);
@@ -7616,7 +7697,8 @@ ExprResult Sema::BuildCXXMemberCallExpr(Expr *E, NamedDecl *FoundDecl,
ResultType = ResultType.getNonLValueExprType(Context);
CXXMemberCallExpr *CE = CXXMemberCallExpr::Create(
- Context, ME, /*Args=*/{}, ResultType, VK, Exp.get()->getEndLoc());
+ Context, ME, /*Args=*/{}, ResultType, VK, Exp.get()->getEndLoc(),
+ CurFPFeatureOverrides());
if (CheckFunctionCall(Method, CE,
Method->getType()->castAs<FunctionProtoType>()))
@@ -7640,7 +7722,8 @@ ExprResult Sema::BuildCXXNoexceptExpr(SourceLocation KeyLoc, Expr *Operand,
Operand = R.get();
- if (!inTemplateInstantiation() && Operand->HasSideEffects(Context, false)) {
+ if (!inTemplateInstantiation() && !Operand->isInstantiationDependent() &&
+ Operand->HasSideEffects(Context, false)) {
// The expression operand for noexcept is in an unevaluated expression
// context, so side effects could result in unintended consequences.
Diag(Operand->getExprLoc(), diag::warn_side_effects_unevaluated_context);
@@ -8646,6 +8729,9 @@ Sema::ActOnRequiresExpr(SourceLocation RequiresKWLoc,
ArrayRef<ParmVarDecl *> LocalParameters,
ArrayRef<concepts::Requirement *> Requirements,
SourceLocation ClosingBraceLoc) {
- return RequiresExpr::Create(Context, RequiresKWLoc, Body, LocalParameters,
- Requirements, ClosingBraceLoc);
+ auto *RE = RequiresExpr::Create(Context, RequiresKWLoc, Body, LocalParameters,
+ Requirements, ClosingBraceLoc);
+ if (DiagnoseUnexpandedParameterPackInRequiresExpr(RE))
+ return ExprError();
+ return RE;
}