Index: include/clang/Parse/Parser.h =================================================================== --- include/clang/Parse/Parser.h +++ include/clang/Parse/Parser.h @@ -1756,7 +1756,8 @@ LateParsedAttrList *LateAttrs = nullptr); void ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS = AS_none, - DeclSpecContext DSC = DSC_normal); + DeclSpecContext DSC = DSC_normal, + bool AllowConstexprs = false); void ParseObjCTypeQualifierList(ObjCDeclSpec &DS, Declarator::TheContext Context); Index: lib/Parse/ParseDecl.cpp =================================================================== --- lib/Parse/ParseDecl.cpp +++ lib/Parse/ParseDecl.cpp @@ -2063,7 +2063,8 @@ /// [GNU] attributes specifier-qualifier-list[opt] /// void Parser::ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS, - DeclSpecContext DSC) { + DeclSpecContext DSC, + bool AllowConstexprs) { /// specifier-qualifier-list is a subset of declaration-specifiers. Just /// parse declaration-specifiers and complain about extra stuff. /// TODO: diagnose attribute-specifiers and alignment-specifiers. @@ -2103,7 +2104,7 @@ } // Issue diagnostic and remove constexpr specfier if present. - if (DS.isConstexprSpecified()) { + if (DS.isConstexprSpecified() && !AllowConstexprs) { Diag(DS.getConstexprSpecLoc(), diag::err_typename_invalid_constexpr); DS.ClearConstexprSpec(); } Index: lib/Parse/ParseExprCXX.cpp =================================================================== --- lib/Parse/ParseExprCXX.cpp +++ lib/Parse/ParseExprCXX.cpp @@ -1688,7 +1688,8 @@ // type-specifier-seq DeclSpec DS(AttrFactory); DS.takeAttributesFrom(attrs); - ParseSpecifierQualifierList(DS); + ParseSpecifierQualifierList(DS, AS_none, DSC_normal, + /*AllowConstexprs=*/true); // declarator Declarator DeclaratorInfo(DS, Declarator::ConditionContext); Index: lib/Sema/SemaExprCXX.cpp =================================================================== --- lib/Sema/SemaExprCXX.cpp +++ lib/Sema/SemaExprCXX.cpp @@ -2582,6 +2582,8 @@ return ExprError(); } + Condition = MaybeCreateExprWithCleanups(Condition.get()); + return Condition; } Index: test/CXX/stmt.stmt/stmt.select/p6.cpp =================================================================== --- /dev/null +++ test/CXX/stmt.stmt/stmt.select/p6.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -std=c++11 %s -verify +// expected-no-diagnostics + +// This test verifies the functionality specified by DR948: +// http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#948 + +constexpr int id(int x) +{ + return x; +} + +void f() { + if (constexpr int i = id(101)) { } + switch (constexpr int i = id(2)) { default: break; case 2: break; } + for (; constexpr int i = id(0); ) { } + while (constexpr int i = id(0)) { } +}