llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Younan Zhang (zyn0217) <details> <summary>Changes</summary> This removes the workaround introduced in 3e1a9cf3b8 and 1ba7dc38d. The workaround overwrote the right parenthesis location of the sub expression, which could be wrong when a CXXTemporaryObjectExpr occurs within a nested expression, e.g. `A(A(1, 2))`. To completely take it down, we now propagate the left parenthesis source location throughout SemaCast, such that the ParenOrBraceRange can be properly set at the point of its creation. Fixes https://github.com/llvm/llvm-project/issues/143711 --- Patch is 21.50 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/145260.diff 4 Files Affected: - (modified) clang/docs/ReleaseNotes.rst (+1) - (modified) clang/include/clang/Sema/Initialization.h (+4-3) - (modified) clang/lib/Sema/SemaCast.cpp (+110-83) - (modified) clang/test/AST/ast-dump-expr.cpp (+10) ``````````diff diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 96477ef6ddc9a..7822a9a6c3cc6 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -877,6 +877,7 @@ Bug Fixes to AST Handling - Fixed a malformed printout of ``CXXParenListInitExpr`` in certain contexts. - Fixed a malformed printout of certain calling convention function attributes. (#GH143160) - Fixed dependency calculation for TypedefTypes (#GH89774) +- Fixed the right parenthesis source location of ``CXXTemporaryObjectExpr``. (#GH143711) Miscellaneous Bug Fixes ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/include/clang/Sema/Initialization.h b/clang/include/clang/Sema/Initialization.h index 0455e1fa5016b..a1c156eed5394 100644 --- a/clang/include/clang/Sema/Initialization.h +++ b/clang/include/clang/Sema/Initialization.h @@ -676,11 +676,12 @@ class InitializationKind { } /// Create a direct initialization for a functional cast. - static InitializationKind CreateFunctionalCast(SourceRange TypeRange, + static InitializationKind CreateFunctionalCast(SourceLocation StartLoc, + SourceRange ParenRange, bool InitList) { return InitializationKind(InitList ? IK_DirectList : IK_Direct, - IC_FunctionalCast, TypeRange.getBegin(), - TypeRange.getBegin(), TypeRange.getEnd()); + IC_FunctionalCast, StartLoc, + ParenRange.getBegin(), ParenRange.getEnd()); } /// Create a copy initialization. diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp index e15a43c116516..c092902c688ad 100644 --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/lib/Sema/SemaCast.cpp @@ -98,7 +98,36 @@ namespace { CXXCastPath BasePath; bool IsARCUnbridgedCast; - SourceRange OpRange; + struct OpRangeType { + SourceLocation Ranges[3]; + + OpRangeType(SourceLocation Begin, SourceLocation LParen, + SourceLocation RParen) + : Ranges{Begin, LParen, RParen} {} + + OpRangeType() = default; + + SourceLocation getBegin() const { return Ranges[0]; } + + SourceLocation getLParenLoc() const { return Ranges[1]; } + + SourceLocation getRParenLoc() const { return Ranges[2]; } + + friend const StreamingDiagnostic & + operator<<(const StreamingDiagnostic &DB, OpRangeType Op) { + return DB << SourceRange(Op); + } + + SourceRange getParenRange() const { + return SourceRange(getLParenLoc(), getRParenLoc()); + } + + operator SourceRange() const { + return SourceRange(getBegin(), getRParenLoc()); + } + }; + + OpRangeType OpRange; SourceRange DestRange; // Top-level semantics-checking routines. @@ -237,49 +266,46 @@ static TryCastResult TryLValueToRValueCast(Sema &Self, Expr *SrcExpr, CastKind &Kind, CXXCastPath &BasePath, unsigned &msg); -static TryCastResult TryStaticReferenceDowncast(Sema &Self, Expr *SrcExpr, - QualType DestType, bool CStyle, - SourceRange OpRange, - unsigned &msg, - CastKind &Kind, - CXXCastPath &BasePath); -static TryCastResult TryStaticPointerDowncast(Sema &Self, QualType SrcType, - QualType DestType, bool CStyle, - SourceRange OpRange, - unsigned &msg, - CastKind &Kind, - CXXCastPath &BasePath); +static TryCastResult +TryStaticReferenceDowncast(Sema &Self, Expr *SrcExpr, QualType DestType, + bool CStyle, CastOperation::OpRangeType OpRange, + unsigned &msg, CastKind &Kind, + CXXCastPath &BasePath); +static TryCastResult +TryStaticPointerDowncast(Sema &Self, QualType SrcType, QualType DestType, + bool CStyle, CastOperation::OpRangeType OpRange, + unsigned &msg, CastKind &Kind, CXXCastPath &BasePath); static TryCastResult TryStaticDowncast(Sema &Self, CanQualType SrcType, CanQualType DestType, bool CStyle, - SourceRange OpRange, + CastOperation::OpRangeType OpRange, QualType OrigSrcType, QualType OrigDestType, unsigned &msg, - CastKind &Kind, - CXXCastPath &BasePath); -static TryCastResult TryStaticMemberPointerUpcast(Sema &Self, ExprResult &SrcExpr, - QualType SrcType, - QualType DestType,bool CStyle, - SourceRange OpRange, - unsigned &msg, - CastKind &Kind, - CXXCastPath &BasePath); - + CastKind &Kind, CXXCastPath &BasePath); static TryCastResult -TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, - CheckedConversionKind CCK, SourceRange OpRange, - unsigned &msg, CastKind &Kind, bool ListInitialization); +TryStaticMemberPointerUpcast(Sema &Self, ExprResult &SrcExpr, QualType SrcType, + QualType DestType, bool CStyle, + CastOperation::OpRangeType OpRange, unsigned &msg, + CastKind &Kind, CXXCastPath &BasePath); + +static TryCastResult TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr, + QualType DestType, + CheckedConversionKind CCK, + CastOperation::OpRangeType OpRange, + unsigned &msg, CastKind &Kind, + bool ListInitialization); static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, CheckedConversionKind CCK, - SourceRange OpRange, unsigned &msg, - CastKind &Kind, CXXCastPath &BasePath, + CastOperation::OpRangeType OpRange, + unsigned &msg, CastKind &Kind, + CXXCastPath &BasePath, bool ListInitialization); static TryCastResult TryConstCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, bool CStyle, unsigned &msg); static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, bool CStyle, - SourceRange OpRange, unsigned &msg, - CastKind &Kind); + CastOperation::OpRangeType OpRange, + unsigned &msg, CastKind &Kind); static TryCastResult TryAddressSpaceCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, bool CStyle, unsigned &msg, CastKind &Kind); @@ -319,7 +345,8 @@ Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, DestType->isDependentType() || Ex.get()->isTypeDependent(); CastOperation Op(*this, DestType, E); - Op.OpRange = SourceRange(OpLoc, Parens.getEnd()); + Op.OpRange = + CastOperation::OpRangeType(OpLoc, Parens.getBegin(), Parens.getEnd()); Op.DestRange = AngleBrackets; Op.checkQualifiedDestType(); @@ -412,7 +439,7 @@ ExprResult Sema::BuildBuiltinBitCastExpr(SourceLocation KWLoc, TypeSourceInfo *TSI, Expr *Operand, SourceLocation RParenLoc) { CastOperation Op(*this, TSI->getType(), Operand); - Op.OpRange = SourceRange(KWLoc, RParenLoc); + Op.OpRange = CastOperation::OpRangeType(KWLoc, KWLoc, RParenLoc); TypeLoc TL = TSI->getTypeLoc(); Op.DestRange = SourceRange(TL.getBeginLoc(), TL.getEndLoc()); @@ -431,8 +458,8 @@ ExprResult Sema::BuildBuiltinBitCastExpr(SourceLocation KWLoc, /// Try to diagnose a failed overloaded cast. Returns true if /// diagnostics were emitted. static bool tryDiagnoseOverloadedCast(Sema &S, CastType CT, - SourceRange range, Expr *src, - QualType destType, + CastOperation::OpRangeType range, + Expr *src, QualType destType, bool listInitialization) { switch (CT) { // These cast kinds don't consider user-defined conversions. @@ -454,12 +481,13 @@ static bool tryDiagnoseOverloadedCast(Sema &S, CastType CT, return false; InitializedEntity entity = InitializedEntity::InitializeTemporary(destType); - InitializationKind initKind - = (CT == CT_CStyle)? InitializationKind::CreateCStyleCast(range.getBegin(), - range, listInitialization) - : (CT == CT_Functional)? InitializationKind::CreateFunctionalCast(range, - listInitialization) - : InitializationKind::CreateCast(/*type range?*/ range); + InitializationKind initKind = + (CT == CT_CStyle) ? InitializationKind::CreateCStyleCast( + range.getBegin(), range, listInitialization) + : (CT == CT_Functional) + ? InitializationKind::CreateFunctionalCast( + range.getBegin(), range.getParenRange(), listInitialization) + : InitializationKind::CreateCast(/*type range?*/ range); InitializationSequence sequence(S, entity, initKind, src); // It could happen that a constructor failed to be used because @@ -544,8 +572,8 @@ static bool tryDiagnoseOverloadedCast(Sema &S, CastType CT, /// Diagnose a failed cast. static void diagnoseBadCast(Sema &S, unsigned msg, CastType castType, - SourceRange opRange, Expr *src, QualType destType, - bool listInitialization) { + CastOperation::OpRangeType opRange, Expr *src, + QualType destType, bool listInitialization) { if (msg == diag::err_bad_cxx_cast_generic && tryDiagnoseOverloadedCast(S, castType, opRange, src, destType, listInitialization)) @@ -1018,7 +1046,7 @@ void CastOperation::CheckAddrspaceCast() { /// or downcast between respective pointers or references. static void DiagnoseReinterpretUpDownCast(Sema &Self, const Expr *SrcExpr, QualType DestType, - SourceRange OpRange) { + CastOperation::OpRangeType OpRange) { QualType SrcType = SrcExpr->getType(); // When casting from pointer or reference, get pointee type; use original // type otherwise. @@ -1361,8 +1389,9 @@ static bool IsAddressSpaceConversion(QualType SrcType, QualType DestType) { /// and casting away constness. static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, CheckedConversionKind CCK, - SourceRange OpRange, unsigned &msg, - CastKind &Kind, CXXCastPath &BasePath, + CastOperation::OpRangeType OpRange, + unsigned &msg, CastKind &Kind, + CXXCastPath &BasePath, bool ListInitialization) { // Determine whether we have the semantics of a C-style cast. bool CStyle = (CCK == CheckedConversionKind::CStyleCast || @@ -1625,11 +1654,11 @@ TryCastResult TryLValueToRValueCast(Sema &Self, Expr *SrcExpr, } /// Tests whether a conversion according to C++ 5.2.9p5 is valid. -TryCastResult -TryStaticReferenceDowncast(Sema &Self, Expr *SrcExpr, QualType DestType, - bool CStyle, SourceRange OpRange, - unsigned &msg, CastKind &Kind, - CXXCastPath &BasePath) { +TryCastResult TryStaticReferenceDowncast(Sema &Self, Expr *SrcExpr, + QualType DestType, bool CStyle, + CastOperation::OpRangeType OpRange, + unsigned &msg, CastKind &Kind, + CXXCastPath &BasePath) { // C++ 5.2.9p5: An lvalue of type "cv1 B", where B is a class type, can be // cast to type "reference to cv2 D", where D is a class derived from B, // if a valid standard conversion from "pointer to D" to "pointer to B" @@ -1663,11 +1692,11 @@ TryStaticReferenceDowncast(Sema &Self, Expr *SrcExpr, QualType DestType, } /// Tests whether a conversion according to C++ 5.2.9p8 is valid. -TryCastResult -TryStaticPointerDowncast(Sema &Self, QualType SrcType, QualType DestType, - bool CStyle, SourceRange OpRange, - unsigned &msg, CastKind &Kind, - CXXCastPath &BasePath) { +TryCastResult TryStaticPointerDowncast(Sema &Self, QualType SrcType, + QualType DestType, bool CStyle, + CastOperation::OpRangeType OpRange, + unsigned &msg, CastKind &Kind, + CXXCastPath &BasePath) { // C++ 5.2.9p8: An rvalue of type "pointer to cv1 B", where B is a class // type, can be converted to an rvalue of type "pointer to cv2 D", where D // is a class derived from B, if a valid standard conversion from "pointer @@ -1697,11 +1726,12 @@ TryStaticPointerDowncast(Sema &Self, QualType SrcType, QualType DestType, /// TryStaticDowncast - Common functionality of TryStaticReferenceDowncast and /// TryStaticPointerDowncast. Tests whether a static downcast from SrcType to /// DestType is possible and allowed. -TryCastResult -TryStaticDowncast(Sema &Self, CanQualType SrcType, CanQualType DestType, - bool CStyle, SourceRange OpRange, QualType OrigSrcType, - QualType OrigDestType, unsigned &msg, - CastKind &Kind, CXXCastPath &BasePath) { +TryCastResult TryStaticDowncast(Sema &Self, CanQualType SrcType, + CanQualType DestType, bool CStyle, + CastOperation::OpRangeType OpRange, + QualType OrigSrcType, QualType OrigDestType, + unsigned &msg, CastKind &Kind, + CXXCastPath &BasePath) { // We can only work with complete types. But don't complain if it doesn't work if (!Self.isCompleteType(OpRange.getBegin(), SrcType) || !Self.isCompleteType(OpRange.getBegin(), DestType)) @@ -1810,12 +1840,12 @@ TryStaticDowncast(Sema &Self, CanQualType SrcType, CanQualType DestType, /// converted to an rvalue of type "pointer to member of B of type cv2 T", /// where B is a base class of D [...]. /// -TryCastResult -TryStaticMemberPointerUpcast(Sema &Self, ExprResult &SrcExpr, QualType SrcType, - QualType DestType, bool CStyle, - SourceRange OpRange, - unsigned &msg, CastKind &Kind, - CXXCastPath &BasePath) { +TryCastResult TryStaticMemberPointerUpcast(Sema &Self, ExprResult &SrcExpr, + QualType SrcType, QualType DestType, + bool CStyle, + CastOperation::OpRangeType OpRange, + unsigned &msg, CastKind &Kind, + CXXCastPath &BasePath) { const MemberPointerType *DestMemPtr = DestType->getAs<MemberPointerType>(); if (!DestMemPtr) return TC_NotApplicable; @@ -1881,8 +1911,9 @@ TryStaticMemberPointerUpcast(Sema &Self, ExprResult &SrcExpr, QualType SrcType, TryCastResult TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, CheckedConversionKind CCK, - SourceRange OpRange, unsigned &msg, - CastKind &Kind, bool ListInitialization) { + CastOperation::OpRangeType OpRange, + unsigned &msg, CastKind &Kind, + bool ListInitialization) { if (DestType->isRecordType()) { if (Self.RequireCompleteType(OpRange.getBegin(), DestType, diag::err_bad_cast_incomplete) || @@ -1899,8 +1930,8 @@ TryCastResult TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr, ? InitializationKind::CreateCStyleCast(OpRange.getBegin(), OpRange, ListInitialization) : (CCK == CheckedConversionKind::FunctionalCast) - ? InitializationKind::CreateFunctionalCast(OpRange, - ListInitialization) + ? InitializationKind::CreateFunctionalCast( + OpRange.getBegin(), OpRange.getParenRange(), ListInitialization) : InitializationKind::CreateCast(OpRange); Expr *SrcExprRaw = SrcExpr.get(); // FIXME: Per DR242, we should check for an implicit conversion sequence @@ -2112,7 +2143,8 @@ static void DiagnoseCastOfObjCSEL(Sema &Self, const ExprResult &SrcExpr, /// Diagnose casts that change the calling convention of a pointer to a function /// defined in the current TU. static void DiagnoseCallingConvCast(Sema &Self, const ExprResult &SrcExpr, - QualType DstType, SourceRange OpRange) { + QualType DstType, + CastOperation::OpRangeType OpRange) { // Check if this cast would change the calling convention of a function // pointer type. QualType SrcType = SrcExpr.get()->getType(); @@ -2255,9 +2287,8 @@ static bool fixOverloadedReinterpretCastExpr(Sema &Self, QualType DestType, static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, bool CStyle, - SourceRange OpRange, - unsigned &msg, - CastKind &Kind) { + CastOperation::OpRangeType OpRange, + unsigned &msg, CastKind &Kind) { bool IsLValueCast = false; DestType = Self.Context.getCanonicalType(DestType); @@ -3413,7 +3444,8 @@ ExprResult Sema::BuildCStyleCastExpr(SourceLocation LPLoc, Expr *CastExpr) { CastOperation Op(*this, CastTypeInfo->getType(), CastExpr); Op.DestRange = CastTypeInfo->getTypeLoc().getSourceRange(); - Op.OpRange = SourceRange(LPLoc, CastExpr->getEndLoc()); + Op.OpRange = CastOperation::OpRangeType(Op.DestRange.getBegin(), LPLoc, + CastExpr->getEndLoc()); if (getLangOpts().CPlusPlus) { Op.CheckCXXCStyleCast(/*FunctionalCast=*/ fa... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/145260 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits