forked from OSchip/llvm-project
Revert "PR45083: Mark statement expressions as being dependent if they contain"
This reverts commit 2669e41b7b
, which was
pushed by mistake.
This commit is contained in:
parent
51fab8f36f
commit
6333cc2a12
|
@ -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) { }
|
||||
|
|
|
@ -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<Stmt*, 16> 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<Expr>(S)) {
|
||||
addDependence(E->getDependence());
|
||||
continue;
|
||||
}
|
||||
|
||||
// FIXME: Need to properly compute whether DeclStmts contain unexpanded
|
||||
// parameter packs.
|
||||
if (DeclStmt *DS = dyn_cast<DeclStmt>(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<VarDecl>(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<Expr*> args,
|
||||
QualType Type, SourceLocation BLoc,
|
||||
SourceLocation RP)
|
||||
|
|
|
@ -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 <typename Iterator>
|
||||
|
@ -107,42 +108,3 @@ namespace PR18152 {
|
|||
};
|
||||
template struct A<0>;
|
||||
}
|
||||
|
||||
template<typename T> 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<typename> struct B : A {
|
||||
void f() {
|
||||
const int n = ({ if (x) {} 0; });
|
||||
}
|
||||
};
|
||||
|
||||
template void B<int>::f();
|
||||
|
||||
template<typename> void f() {
|
||||
decltype(({})) x; // expected-error {{incomplete type}}
|
||||
}
|
||||
template void f<int>();
|
||||
|
||||
template<typename> 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<int>()); // expected-note {{previous}}
|
||||
using U = float; // expected-error {{different types ('float' vs 'decltype(g<int>())' (aka 'void'))}}
|
||||
|
||||
void h(auto a, decltype(g<char>())*) {} // expected-note {{previous}}
|
||||
void h(auto a, void*) {} // expected-error {{redefinition}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue