Author: Richard Smith Date: 2020-10-08T17:00:22-07:00 New Revision: d1751d14a6b2787974a4d203be2b554de9fa613c
URL: https://github.com/llvm/llvm-project/commit/d1751d14a6b2787974a4d203be2b554de9fa613c DIFF: https://github.com/llvm/llvm-project/commit/d1751d14a6b2787974a4d203be2b554de9fa613c.diff LOG: PR47175: Ensure type-dependent function-style casts have dependent types. Previously, a type-dependent cast to a deduced class template specialization type would end up with a non-dependent class template specialization type, leading to confusion downstream. Added: Modified: clang/include/clang/AST/ExprCXX.h clang/lib/AST/ASTImporter.cpp clang/lib/AST/ComputeDependence.cpp clang/lib/AST/ExprCXX.cpp clang/lib/Sema/SemaExprCXX.cpp clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp Removed: ################################################################################ diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index 9658f37723e1..926021e9c6ed 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -3427,17 +3427,18 @@ class CXXUnresolvedConstructExpr final /// The location of the right parentheses (')'). SourceLocation RParenLoc; - CXXUnresolvedConstructExpr(TypeSourceInfo *TSI, SourceLocation LParenLoc, - ArrayRef<Expr *> Args, SourceLocation RParenLoc); + CXXUnresolvedConstructExpr(QualType T, TypeSourceInfo *TSI, + SourceLocation LParenLoc, ArrayRef<Expr *> Args, + SourceLocation RParenLoc); CXXUnresolvedConstructExpr(EmptyShell Empty, unsigned NumArgs) - : Expr(CXXUnresolvedConstructExprClass, Empty) { + : Expr(CXXUnresolvedConstructExprClass, Empty), TSI(nullptr) { CXXUnresolvedConstructExprBits.NumArgs = NumArgs; } public: static CXXUnresolvedConstructExpr *Create(const ASTContext &Context, - TypeSourceInfo *Type, + QualType T, TypeSourceInfo *TSI, SourceLocation LParenLoc, ArrayRef<Expr *> Args, SourceLocation RParenLoc); diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 60b6a9706d6a..05cc717581ef 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -7535,6 +7535,7 @@ ExpectedStmt ASTNodeImporter::VisitCXXUnresolvedConstructExpr( Error Err = Error::success(); auto ToLParenLoc = importChecked(Err, E->getLParenLoc()); auto ToRParenLoc = importChecked(Err, E->getRParenLoc()); + auto ToType = importChecked(Err, E->getType()); auto ToTypeSourceInfo = importChecked(Err, E->getTypeSourceInfo()); if (Err) return std::move(Err); @@ -7545,7 +7546,7 @@ ExpectedStmt ASTNodeImporter::VisitCXXUnresolvedConstructExpr( return std::move(Err); return CXXUnresolvedConstructExpr::Create( - Importer.getToContext(), ToTypeSourceInfo, ToLParenLoc, + Importer.getToContext(), ToType, ToTypeSourceInfo, ToLParenLoc, llvm::makeArrayRef(ToArgs), ToRParenLoc); } diff --git a/clang/lib/AST/ComputeDependence.cpp b/clang/lib/AST/ComputeDependence.cpp index f8dfeed0962e..d837ae29cb54 100644 --- a/clang/lib/AST/ComputeDependence.cpp +++ b/clang/lib/AST/ComputeDependence.cpp @@ -711,8 +711,6 @@ ExprDependence clang::computeDependence(LambdaExpr *E, ExprDependence clang::computeDependence(CXXUnresolvedConstructExpr *E) { auto D = ExprDependence::ValueInstantiation; D |= toExprDependence(E->getType()->getDependence()); - if (E->getType()->getContainedDeducedType()) - D |= ExprDependence::Type; for (auto *A : E->arguments()) D |= A->getDependence() & (ExprDependence::UnexpandedPack | ExprDependence::Error); diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp index fe2de4b8cbce..4a421f03e589 100644 --- a/clang/lib/AST/ExprCXX.cpp +++ b/clang/lib/AST/ExprCXX.cpp @@ -1316,12 +1316,12 @@ ExprWithCleanups *ExprWithCleanups::Create(const ASTContext &C, return new (buffer) ExprWithCleanups(empty, numObjects); } -CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(TypeSourceInfo *TSI, +CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(QualType T, + TypeSourceInfo *TSI, SourceLocation LParenLoc, ArrayRef<Expr *> Args, SourceLocation RParenLoc) - : Expr(CXXUnresolvedConstructExprClass, - TSI->getType().getNonReferenceType(), + : Expr(CXXUnresolvedConstructExprClass, T, (TSI->getType()->isLValueReferenceType() ? VK_LValue : TSI->getType()->isRValueReferenceType() ? VK_XValue @@ -1336,10 +1336,11 @@ CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(TypeSourceInfo *TSI, } CXXUnresolvedConstructExpr *CXXUnresolvedConstructExpr::Create( - const ASTContext &Context, TypeSourceInfo *TSI, SourceLocation LParenLoc, + const ASTContext &Context, QualType T, TypeSourceInfo *TSI, SourceLocation LParenLoc, ArrayRef<Expr *> Args, SourceLocation RParenLoc) { void *Mem = Context.Allocate(totalSizeToAlloc<Expr *>(Args.size())); - return new (Mem) CXXUnresolvedConstructExpr(TSI, LParenLoc, Args, RParenLoc); + return new (Mem) + CXXUnresolvedConstructExpr(T, TSI, LParenLoc, Args, RParenLoc); } CXXUnresolvedConstructExpr * diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 5f4afb38bc25..ed57772cd237 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1413,16 +1413,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."); @@ -1451,6 +1441,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 diff --git a/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp b/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp index e992c7c916f3..2412c9d4db74 100644 --- a/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp +++ b/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp @@ -526,6 +526,12 @@ namespace PR45124 { __thread b g; } +namespace PR47175 { + template<typename T> struct A { A(T); T x; }; + template<typename T> int &&n = A(T()).x; + int m = n<int>; +} + #else // expected-no-diagnostics _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits