[clang] f545ede - Fix regression in bdad0a1: force rebuilding of StmtExpr nodes in
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Wed Mar 4 13:20:05 PST 2020
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}}
}
More information about the cfe-commits
mailing list