Author: Richard Smith Date: 2020-03-04T13:19:49-08:00 New Revision: f545ede91c9d9f271e7504282cab7bf509607ead
URL: https://github.com/llvm/llvm-project/commit/f545ede91c9d9f271e7504282cab7bf509607ead DIFF: https://github.com/llvm/llvm-project/commit/f545ede91c9d9f271e7504282cab7bf509607ead.diff LOG: Fix regression in bdad0a1: force rebuilding of StmtExpr nodes in TreeTransform if the 'dependent' flag would change. Added: Modified: clang/include/clang/Sema/Sema.h clang/lib/Sema/SemaExpr.cpp clang/lib/Sema/TreeTransform.h clang/test/SemaTemplate/dependent-expr.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 5739808753e3..8e4d0828e2d0 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -4965,7 +4965,9 @@ class Sema final { void ActOnStartStmtExpr(); ExprResult ActOnStmtExpr(Scope *S, SourceLocation LPLoc, Stmt *SubStmt, - SourceLocation RPLoc); // "({..})" + SourceLocation RPLoc); + ExprResult BuildStmtExpr(SourceLocation LPLoc, Stmt *SubStmt, + SourceLocation RPLoc, bool IsDependent); // Handle the final expression in a statement expression. ExprResult ActOnStmtExprResult(ExprResult E); void ActOnStmtExprError(); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 1870e440199d..291c38ab20b4 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -13912,7 +13912,13 @@ void Sema::ActOnStmtExprError() { } ExprResult Sema::ActOnStmtExpr(Scope *S, SourceLocation LPLoc, Stmt *SubStmt, - SourceLocation RPLoc) { // "({..})" + SourceLocation RPLoc) { + return BuildStmtExpr(LPLoc, SubStmt, RPLoc, + S->getTemplateParamParent() != nullptr); +} + +ExprResult Sema::BuildStmtExpr(SourceLocation LPLoc, Stmt *SubStmt, + SourceLocation RPLoc, bool IsDependent) { assert(SubStmt && isa<CompoundStmt>(SubStmt) && "Invalid action invocation!"); CompoundStmt *Compound = cast<CompoundStmt>(SubStmt); @@ -13941,18 +13947,10 @@ ExprResult Sema::ActOnStmtExpr(Scope *S, SourceLocation LPLoc, Stmt *SubStmt, } } - bool IsDependentContext = false; - if (S) - IsDependentContext = S->getTemplateParamParent() != nullptr; - else - // FIXME: This is not correct when substituting inside a templated - // context that isn't a DeclContext (such as a variable template). - IsDependentContext = CurContext->isDependentContext(); - // FIXME: Check that expression type is complete/non-abstract; statement // expressions are not lvalues. Expr *ResStmtExpr = - new (Context) StmtExpr(Compound, Ty, LPLoc, RPLoc, IsDependentContext); + new (Context) StmtExpr(Compound, Ty, LPLoc, RPLoc, IsDependent); if (StmtExprMayBindToTemp) return MaybeBindToTemporary(ResStmtExpr); return ResStmtExpr; diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 05b41aa53da6..382496dad3d5 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -2550,8 +2550,8 @@ class TreeTransform { /// By default, performs semantic analysis to build the new expression. /// Subclasses may override this routine to provide diff erent behavior. ExprResult RebuildStmtExpr(SourceLocation LParenLoc, Stmt *SubStmt, - SourceLocation RParenLoc) { - return getSema().ActOnStmtExpr(nullptr, LParenLoc, SubStmt, RParenLoc); + SourceLocation RParenLoc, bool IsDependent) { + return getSema().BuildStmtExpr(LParenLoc, SubStmt, RParenLoc, IsDependent); } /// Build a new __builtin_choose_expr expression. @@ -10432,16 +10432,20 @@ TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) { return ExprError(); } + // FIXME: This is not correct when substituting inside a templated + // context that isn't a DeclContext (such as a variable template). + bool IsDependent = getSema().CurContext->isDependentContext(); + if (!getDerived().AlwaysRebuild() && + IsDependent == E->isInstantiationDependent() && SubStmt.get() == E->getSubStmt()) { // Calling this an 'error' is unintuitive, but it does the right thing. SemaRef.ActOnStmtExprError(); return SemaRef.MaybeBindToTemporary(E); } - return getDerived().RebuildStmtExpr(E->getLParenLoc(), - SubStmt.get(), - E->getRParenLoc()); + return getDerived().RebuildStmtExpr(E->getLParenLoc(), SubStmt.get(), + E->getRParenLoc(), IsDependent); } template<typename Derived> diff --git a/clang/test/SemaTemplate/dependent-expr.cpp b/clang/test/SemaTemplate/dependent-expr.cpp index e333ed927b9e..97d157f86424 100644 --- a/clang/test/SemaTemplate/dependent-expr.cpp +++ b/clang/test/SemaTemplate/dependent-expr.cpp @@ -125,4 +125,11 @@ namespace PR45083 { }; template void B<int>::f(); + + // Make sure we properly rebuild statement expression AST nodes even if the + // only thing that changes is the "is dependent" flag. + template<typename> void f() { + decltype(({})) x; // expected-error {{incomplete type}} + } + template void f<int>(); // expected-note {{instantiation of}} } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits