Index: lib/Parse/ParseExprCXX.cpp =================================================================== --- lib/Parse/ParseExprCXX.cpp +++ lib/Parse/ParseExprCXX.cpp @@ -1740,11 +1740,25 @@ ParsedAttributesWithRange attrs(AttrFactory); MaybeParseCXX11Attributes(attrs); + const auto WarnOnInit = [this, &CK] { + Diag(Tok.getLocation(), getLangOpts().CPlusPlus1z + ? diag::warn_cxx14_compat_init_statement + : diag::ext_init_statement) + << (CK == Sema::ConditionKind::Switch); + }; + // Determine what kind of thing we have. switch (isCXXConditionDeclarationOrInitStatement(InitStmt)) { case ConditionOrInitStatement::Expression: { ProhibitAttributes(attrs); + // We can have an empty expression here. + // if (; true); + if (InitStmt && TryConsumeToken(tok::semi)) { + WarnOnInit(); + return ParseCXXCondition(nullptr, Loc, CK); + } + // Parse the expression. ExprResult Expr = ParseExpression(); // expression if (Expr.isInvalid()) @@ -1760,10 +1774,7 @@ } case ConditionOrInitStatement::InitStmtDecl: { - Diag(Tok.getLocation(), getLangOpts().CPlusPlus1z - ? diag::warn_cxx14_compat_init_statement - : diag::ext_init_statement) - << (CK == Sema::ConditionKind::Switch); + WarnOnInit(); SourceLocation DeclStart = Tok.getLocation(), DeclEnd; DeclGroupPtrTy DG = ParseSimpleDeclaration( Declarator::InitStmtContext, DeclEnd, attrs, /*RequireSemi=*/true); Index: test/CXX/stmt.stmt/stmt.select/p3.cpp =================================================================== --- test/CXX/stmt.stmt/stmt.select/p3.cpp +++ test/CXX/stmt.stmt/stmt.select/p3.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -std=c++1z -verify %s -DCXX17 int f(); @@ -10,10 +11,52 @@ } } - void h() { if (int x = f()) // expected-note 2{{previous definition}} int x; // expected-error{{redefinition of 'x'}} else int x; // expected-error{{redefinition of 'x'}} } + +#ifdef CXX17 +int ifInitStatement() { + if (int I = 0; ++I == 1) + return I; + + int Var = 0; + if (Var + Var; Var == 0) + return Var; + + if (; true) + return 1; +} + +int switchInitStatement() { + switch (int I = 1; I) { + case 1: + return I; + } + + int Var = 0; + switch (Var + Var; Var) { + case 0: + return Var; + } + + switch (; 0) { + case 0: + return 0; + } +} +#endif + +int whileInitStatement() { + while (int I = 10; I--); // expected-error{{expected ')'}} + // expected-note@-1{{to match this '('}} + // expected-error@-2{{use of undeclared identifier 'I'}} + + int Var = 10; + while (; Var--); // expected-error{{expected expression}} + // expected-error@-1{{extraneous ')' before ';'}} +} +