From 6333cc2a12dc72d0cfaaac5ade00e9a1b9d6dbce Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Mon, 9 Mar 2020 17:03:56 -0700 Subject: [PATCH] Revert "PR45083: Mark statement expressions as being dependent if they contain" This reverts commit 2669e41b7b9c1561a01048d5ed0aba3c62432dfc, which was pushed by mistake. --- clang/include/clang/AST/Expr.h | 10 ++++- clang/lib/AST/Expr.cpp | 47 ---------------------- clang/test/SemaTemplate/dependent-expr.cpp | 42 +------------------ 3 files changed, 10 insertions(+), 89 deletions(-) diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 75b7a5f6ecd3..7271dbb830a2 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -3959,8 +3959,14 @@ class StmtExpr : public Expr { Stmt *SubStmt; SourceLocation LParenLoc, RParenLoc; public: - StmtExpr(CompoundStmt *SubStmt, QualType T, - SourceLocation LParen, SourceLocation RParen); + // FIXME: Does type-dependence need to be computed differently? + // FIXME: Do we need to compute instantiation instantiation-dependence for + // statements? (ugh!) + StmtExpr(CompoundStmt *substmt, QualType T, + SourceLocation lp, SourceLocation rp) : + Expr(StmtExprClass, T, VK_RValue, OK_Ordinary, + T->isDependentType(), false, false, false), + SubStmt(substmt), LParenLoc(lp), RParenLoc(rp) { } /// Build an empty statement expression. explicit StmtExpr(EmptyShell Empty) : Expr(StmtExprClass, Empty) { } diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index feaa9e01f8eb..4eb7a177de00 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -4101,53 +4101,6 @@ void ExtVectorElementExpr::getEncodedElementAccess( } } -StmtExpr::StmtExpr(CompoundStmt *SubStmt, QualType T, SourceLocation LParen, - SourceLocation RParen) - : Expr(StmtExprClass, T, VK_RValue, OK_Ordinary, T->isDependentType(), - false, false, false), - SubStmt(SubStmt), LParenLoc(LParen), RParenLoc(RParen) { - llvm::SmallVector Queue(1, SubStmt); - while (!Queue.empty()) { - Stmt *S = Queue.pop_back_val(); - if (!S) - continue; - - // If any subexpression is dependent, the statement expression is dependent - // in the same way. - if (Expr *E = dyn_cast(S)) { - addDependence(E->getDependence()); - continue; - } - - // FIXME: Need to properly compute whether DeclStmts contain unexpanded - // parameter packs. - if (DeclStmt *DS = dyn_cast(S)) { - for (Decl *D : DS->decls()) { - // If any contained declaration is in a dependent context, then it - // needs to be instantiated, so the statement expression itself is - // instantiation-dependent. - // - // Note that we don't need to worry about the case where the context is - // non-dependent but contains dependent entities here (eg, inside a - // variable template or alias template): that can only happen at file - // scope, where statement expressions are prohibited. - if (D->getLexicalDeclContext()->isDependentContext()) - addDependence(ExprDependence::Instantiation); - - // If any contained variable declaration has a dependent type, we can't - // evaluate that declaration. - if (auto *VD = dyn_cast(D)) - if (VD->getType()->isDependentType()) - addDependence(ExprDependence::Value); - } - } - - // Recurse to substatements. - // FIXME: Should we skip the unchosen side of 'if constexpr' if known? - Queue.insert(Queue.end(), S->child_begin(), S->child_end()); - } -} - ShuffleVectorExpr::ShuffleVectorExpr(const ASTContext &C, ArrayRef args, QualType Type, SourceLocation BLoc, SourceLocation RP) diff --git a/clang/test/SemaTemplate/dependent-expr.cpp b/clang/test/SemaTemplate/dependent-expr.cpp index 12a99acc21cd..bb1e239c3490 100644 --- a/clang/test/SemaTemplate/dependent-expr.cpp +++ b/clang/test/SemaTemplate/dependent-expr.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++2a %s +// RUN: %clang_cc1 -fsyntax-only -verify %s +// expected-no-diagnostics // PR5908 template @@ -107,42 +108,3 @@ namespace PR18152 { }; template struct A<0>; } - -template void stmt_expr_1() { - // GCC doesn't check this: it appears to treat statement-expressions as being - // value-dependent if they appear in a dependent context, regardless of their - // contents. - static_assert( ({ false; }), "" ); // expected-error {{failed}} -} -void stmt_expr_2() { - static_assert( ({ false; }), "" ); // expected-error {{failed}} -} - -namespace PR45083 { - struct A { bool x; }; - - template struct B : A { - void f() { - const int n = ({ if (x) {} 0; }); - } - }; - - template void B::f(); - - template void f() { - decltype(({})) x; // expected-error {{incomplete type}} - } - template void f(); - - template auto g() { - auto c = [](auto, int) -> decltype(({})) {}; - using T = decltype(c(0.0, 0)); - using T = void; - return c(0, 0); - } - using U = decltype(g()); // expected-note {{previous}} - using U = float; // expected-error {{different types ('float' vs 'decltype(g())' (aka 'void'))}} - - void h(auto a, decltype(g())*) {} // expected-note {{previous}} - void h(auto a, void*) {} // expected-error {{redefinition}} -}