diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp | 176 |
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; } |