Index: include/clang/Parse/Parser.h =================================================================== --- include/clang/Parse/Parser.h +++ include/clang/Parse/Parser.h @@ -1685,7 +1685,8 @@ DSC_trailing, // C++11 trailing-type-specifier in a trailing return type DSC_alias_declaration, // C++11 type-specifier-seq in an alias-declaration DSC_top_level, // top-level/namespace declaration context - DSC_template_type_arg // template type argument context + DSC_template_type_arg, // template type argument context + DSC_constexpr // constexpr declaration context }; /// Is this a context in which we are parsing just a type-specifier (or @@ -1695,6 +1696,7 @@ case DSC_normal: case DSC_class: case DSC_top_level: + case DSC_constexpr: return false; case DSC_template_type_arg: Index: lib/Parse/ParseDecl.cpp =================================================================== --- lib/Parse/ParseDecl.cpp +++ lib/Parse/ParseDecl.cpp @@ -2143,7 +2143,7 @@ } // Issue diagnostic and remove constexpr specfier if present. - if (DS.isConstexprSpecified()) { + if (DS.isConstexprSpecified() && DSC != DSC_constexpr) { 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,7 @@ // type-specifier-seq DeclSpec DS(AttrFactory); DS.takeAttributesFrom(attrs); - ParseSpecifierQualifierList(DS); + ParseSpecifierQualifierList(DS, AS_none, DSC_constexpr); // declarator Declarator DeclaratorInfo(DS, Declarator::ConditionContext); Index: lib/Sema/SemaExprCXX.cpp =================================================================== --- lib/Sema/SemaExprCXX.cpp +++ lib/Sema/SemaExprCXX.cpp @@ -2583,7 +2583,10 @@ return ExprError(); } - return Condition; + return ActOnFinishFullExpr(Condition.get(), + Condition.get()->getExprLoc(), + false, /* DiscardedValue */ + Condition.get()->isCXX11ConstantExpr(Context)); } /// CheckCXXBooleanCondition - Returns true if a conversion to bool is invalid. Index: test/CXX/drs/dr9xx.cpp =================================================================== --- test/CXX/drs/dr9xx.cpp +++ test/CXX/drs/dr9xx.cpp @@ -44,3 +44,35 @@ D d{}; #endif } + +namespace dr948 { +#if __cplusplus >= 201103L + // This test verifies the functionality specified by DR948: + // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#948 + + class A { + public: + constexpr A(int v) : v(v) { } + constexpr operator int() const { return v; } + private: + int v; + }; + + 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)) { } + + if (constexpr A i = 101) { } + switch (constexpr A i = 2) { default: break; case 2: break; } + for (; constexpr A i = 0; ) { } + while (constexpr A i = 0) { } + } +#endif +}