<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Nov 26, 2014 at 6:19 AM, Aaron Ballman <span dir="ltr"><<a href="mailto:aaron@aaronballman.com" target="_blank">aaron@aaronballman.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">This appears to have broken one of the bots:<br>
<a href="http://bb.pgr.jp/builders/ninja-x64-msvc-RA-centos6/builds/8280" target="_blank">http://bb.pgr.jp/builders/ninja-x64-msvc-RA-centos6/builds/8280</a></blockquote><div><br></div><div>Thanks, should be fixed in r222848.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span class=""><font color="#888888"><br>
~Aaron<br>
</font></span><div class=""><div class="h5"><br>
On Tue, Nov 25, 2014 at 10:26 PM, Richard Smith<br>
<<a href="mailto:richard-llvm@metafoo.co.uk">richard-llvm@metafoo.co.uk</a>> wrote:<br>
> Author: rsmith<br>
> Date: Tue Nov 25 21:26:53 2014<br>
> New Revision: 222807<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=222807&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=222807&view=rev</a><br>
> Log:<br>
> [c++1z] Most of N4268 (allow constant evaluation for non-type template arguments).<br>
><br>
> We don't yet support pointer-to-member template arguments that have undergone<br>
> pointer-to-member conversions, mostly because we don't have a mangling for them yet.<br>
><br>
> Added:<br>
>     cfe/trunk/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp<br>
> Modified:<br>
>     cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
>     cfe/trunk/include/clang/Sema/Sema.h<br>
>     cfe/trunk/lib/Sema/SemaExprCXX.cpp<br>
>     cfe/trunk/lib/Sema/SemaOverload.cpp<br>
>     cfe/trunk/lib/Sema/SemaTemplate.cpp<br>
>     cfe/trunk/test/CXX/drs/dr0xx.cpp<br>
>     cfe/trunk/test/CXX/drs/dr1xx.cpp<br>
>     cfe/trunk/test/CXX/drs/dr2xx.cpp<br>
>     cfe/trunk/test/CXX/drs/dr3xx.cpp<br>
>     cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp<br>
>     cfe/trunk/www/cxx_status.html<br>
><br>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=222807&r1=222806&r2=222807&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=222807&r1=222806&r2=222807&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)<br>
> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Nov 25 21:26:53 2014<br>
> @@ -64,6 +64,9 @@ def err_typecheck_converted_constant_exp<br>
>    "value of type %0 is not implicitly convertible to %1">;<br>
>  def err_typecheck_converted_constant_expression_disallowed : Error<<br>
>    "conversion from %0 to %1 is not allowed in a converted constant expression">;<br>
> +def err_typecheck_converted_constant_expression_indirect : Error<<br>
> +  "conversion from %0 to %1 in converted constant expression would "<br>
> +  "bind reference to a temporary">;<br>
>  def err_expr_not_cce : Error<<br>
>    "%select{case value|enumerator value|non-type template argument|array size}0 "<br>
>    "is not a constant expression">;<br>
> @@ -3293,6 +3296,10 @@ def err_template_arg_wrongtype_null_cons<br>
>  def err_deduced_non_type_template_arg_type_mismatch : Error<<br>
>    "deduced non-type template argument does not have the same type as the "<br>
>    "its corresponding template parameter%diff{ ($ vs $)|}0,1">;<br>
> +def err_non_type_template_arg_subobject : Error<<br>
> +  "non-type template argument refers to subobject '%0'">;<br>
> +def err_non_type_template_arg_addr_label_diff : Error<<br>
> +  "template argument / label address difference / what did you expect?">;<br>
>  def err_template_arg_not_convertible : Error<<br>
>    "non-type template argument of type %0 cannot be converted to a value "<br>
>    "of type %1">;<br>
> @@ -3344,6 +3351,9 @@ def err_template_arg_not_object_or_func<br>
>    "non-type template argument does not refer to an object or function">;<br>
>  def err_template_arg_not_pointer_to_member_form : Error<<br>
>    "non-type template argument is not a pointer to member constant">;<br>
> +def err_template_arg_member_ptr_base_derived_not_supported : Error<<br>
> +  "sorry, non-type template argument of pointer-to-member type %1 that refers "<br>
> +  "to member %q0 of a different class is not supported yet">;<br>
>  def ext_template_arg_extra_parens : ExtWarn<<br>
>    "address non-type template argument cannot be surrounded by parentheses">;<br>
>  def warn_cxx98_compat_template_arg_extra_parens : Warning<<br>
><br>
> Modified: cfe/trunk/include/clang/Sema/Sema.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=222807&r1=222806&r2=222807&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=222807&r1=222806&r2=222807&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/include/clang/Sema/Sema.h (original)<br>
> +++ cfe/trunk/include/clang/Sema/Sema.h Tue Nov 25 21:26:53 2014<br>
> @@ -2148,6 +2148,8 @@ public:<br>
>    };<br>
>    ExprResult CheckConvertedConstantExpression(Expr *From, QualType T,<br>
>                                                llvm::APSInt &Value, CCEKind CCE);<br>
> +  ExprResult CheckConvertedConstantExpression(Expr *From, QualType T,<br>
> +                                              APValue &Value, CCEKind CCE);<br>
><br>
>    /// \brief Abstract base class used to perform a contextual implicit<br>
>    /// conversion from an expression to any type passing a filter.<br>
><br>
> Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=222807&r1=222806&r2=222807&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=222807&r1=222806&r2=222807&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)<br>
> +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Tue Nov 25 21:26:53 2014<br>
> @@ -2780,10 +2780,29 @@ Sema::PerformImplicitConversion(Expr *Fr<br>
>    // Perform the second implicit conversion<br>
>    switch (SCS.Second) {<br>
>    case ICK_Identity:<br>
> -    // If both sides are functions (or pointers/references to them), there could<br>
> -    // be incompatible exception declarations.<br>
> -    if (CheckExceptionSpecCompatibility(From, ToType))<br>
> -      return ExprError();<br>
> +    // C++ [except.spec]p5:<br>
> +    //   [For] assignment to and initialization of pointers to functions,<br>
> +    //   pointers to member functions, and references to functions: the<br>
> +    //   target entity shall allow at least the exceptions allowed by the<br>
> +    //   source value in the assignment or initialization.<br>
> +    switch (Action) {<br>
> +    case AA_Assigning:<br>
> +    case AA_Initializing:<br>
> +      // Note, function argument passing and returning are initialization.<br>
> +    case AA_Passing:<br>
> +    case AA_Returning:<br>
> +    case AA_Sending:<br>
> +    case AA_Passing_CFAudited:<br>
> +      if (CheckExceptionSpecCompatibility(From, ToType))<br>
> +        return ExprError();<br>
> +      break;<br>
> +<br>
> +    case AA_Casting:<br>
> +    case AA_Converting:<br>
> +      // Casts and implicit conversions are not initialization, so are not<br>
> +      // checked for exception specification mismatches.<br>
> +      break;<br>
> +    }<br>
>      // Nothing else to do.<br>
>      break;<br>
><br>
><br>
> Modified: cfe/trunk/lib/Sema/SemaOverload.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=222807&r1=222806&r2=222807&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=222807&r1=222806&r2=222807&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/lib/Sema/SemaOverload.cpp (original)<br>
> +++ cfe/trunk/lib/Sema/SemaOverload.cpp Tue Nov 25 21:26:53 2014<br>
> @@ -4894,41 +4894,51 @@ static bool CheckConvertedConstantConver<br>
>    // conversions are fine.<br>
>    switch (SCS.Second) {<br>
>    case ICK_Identity:<br>
> +  case ICK_NoReturn_Adjustment:<br>
>    case ICK_Integral_Promotion:<br>
> -  case ICK_Integral_Conversion:<br>
> -  case ICK_Zero_Event_Conversion:<br>
> +  case ICK_Integral_Conversion: // Narrowing conversions are checked elsewhere.<br>
>      return true;<br>
><br>
>    case ICK_Boolean_Conversion:<br>
>      // Conversion from an integral or unscoped enumeration type to bool is<br>
> -    // classified as ICK_Boolean_Conversion, but it's also an integral<br>
> -    // conversion, so it's permitted in a converted constant expression.<br>
> +    // classified as ICK_Boolean_Conversion, but it's also arguably an integral<br>
> +    // conversion, so we allow it in a converted constant expression.<br>
> +    //<br>
> +    // FIXME: Per core issue 1407, we should not allow this, but that breaks<br>
> +    // a lot of popular code. We should at least add a warning for this<br>
> +    // (non-conforming) extension.<br>
>      return SCS.getFromType()->isIntegralOrUnscopedEnumerationType() &&<br>
>             SCS.getToType(2)->isBooleanType();<br>
><br>
> +  case ICK_Pointer_Conversion:<br>
> +  case ICK_Pointer_Member:<br>
> +    // C++1z: null pointer conversions and null member pointer conversions are<br>
> +    // only permitted if the source type is std::nullptr_t.<br>
> +    return SCS.getFromType()->isNullPtrType();<br>
> +<br>
> +  case ICK_Floating_Promotion:<br>
> +  case ICK_Complex_Promotion:<br>
> +  case ICK_Floating_Conversion:<br>
> +  case ICK_Complex_Conversion:<br>
>    case ICK_Floating_Integral:<br>
> +  case ICK_Compatible_Conversion:<br>
> +  case ICK_Derived_To_Base:<br>
> +  case ICK_Vector_Conversion:<br>
> +  case ICK_Vector_Splat:<br>
>    case ICK_Complex_Real:<br>
> +  case ICK_Block_Pointer_Conversion:<br>
> +  case ICK_TransparentUnionConversion:<br>
> +  case ICK_Writeback_Conversion:<br>
> +  case ICK_Zero_Event_Conversion:<br>
>      return false;<br>
><br>
>    case ICK_Lvalue_To_Rvalue:<br>
>    case ICK_Array_To_Pointer:<br>
>    case ICK_Function_To_Pointer:<br>
> -  case ICK_NoReturn_Adjustment:<br>
> +    llvm_unreachable("found a first conversion kind in Second");<br>
> +<br>
>    case ICK_Qualification:<br>
> -  case ICK_Compatible_Conversion:<br>
> -  case ICK_Vector_Conversion:<br>
> -  case ICK_Vector_Splat:<br>
> -  case ICK_Derived_To_Base:<br>
> -  case ICK_Pointer_Conversion:<br>
> -  case ICK_Pointer_Member:<br>
> -  case ICK_Block_Pointer_Conversion:<br>
> -  case ICK_Writeback_Conversion:<br>
> -  case ICK_Floating_Promotion:<br>
> -  case ICK_Complex_Promotion:<br>
> -  case ICK_Complex_Conversion:<br>
> -  case ICK_Floating_Conversion:<br>
> -  case ICK_TransparentUnionConversion:<br>
> -    llvm_unreachable("unexpected second conversion kind");<br>
> +    llvm_unreachable("found a third conversion kind in Second");<br>
><br>
>    case ICK_Num_Conversion_Kinds:<br>
>      break;<br>
> @@ -4940,67 +4950,71 @@ static bool CheckConvertedConstantConver<br>
>  /// CheckConvertedConstantExpression - Check that the expression From is a<br>
>  /// converted constant expression of type T, perform the conversion and produce<br>
>  /// the converted expression, per C++11 [expr.const]p3.<br>
> -ExprResult Sema::CheckConvertedConstantExpression(Expr *From, QualType T,<br>
> -                                                  llvm::APSInt &Value,<br>
> -                                                  CCEKind CCE) {<br>
> -  assert(LangOpts.CPlusPlus11 && "converted constant expression outside C++11");<br>
> -  assert(T->isIntegralOrEnumerationType() && "unexpected converted const type");<br>
> +static ExprResult CheckConvertedConstantExpression(Sema &S, Expr *From,<br>
> +                                                   QualType T, APValue &Value,<br>
> +                                                   Sema::CCEKind CCE,<br>
> +                                                   bool RequireInt) {<br>
> +  assert(S.getLangOpts().CPlusPlus11 &&<br>
> +         "converted constant expression outside C++11");<br>
><br>
> -  if (checkPlaceholderForOverload(*this, From))<br>
> +  if (checkPlaceholderForOverload(S, From))<br>
>      return ExprError();<br>
><br>
> -  // C++11 [expr.const]p3 with proposed wording fixes:<br>
> -  //  A converted constant expression of type T is a core constant expression,<br>
> -  //  implicitly converted to a prvalue of type T, where the converted<br>
> -  //  expression is a literal constant expression and the implicit conversion<br>
> -  //  sequence contains only user-defined conversions, lvalue-to-rvalue<br>
> -  //  conversions, integral promotions, and integral conversions other than<br>
> -  //  narrowing conversions.<br>
> +  // C++1z [expr.const]p3:<br>
> +  //  A converted constant expression of type T is an expression,<br>
> +  //  implicitly converted to type T, where the converted<br>
> +  //  expression is a constant expression and the implicit conversion<br>
> +  //  sequence contains only [... list of conversions ...].<br>
>    ImplicitConversionSequence ICS =<br>
> -    TryImplicitConversion(From, T,<br>
> +    TryCopyInitialization(S, From, T,<br>
>                            /*SuppressUserConversions=*/false,<br>
> -                          /*AllowExplicit=*/false,<br>
>                            /*InOverloadResolution=*/false,<br>
> -                          /*CStyle=*/false,<br>
> -                          /*AllowObjcWritebackConversion=*/false);<br>
> +                          /*AllowObjcWritebackConversion=*/false,<br>
> +                          /*AllowExplicit=*/false);<br>
>    StandardConversionSequence *SCS = nullptr;<br>
>    switch (ICS.getKind()) {<br>
>    case ImplicitConversionSequence::StandardConversion:<br>
> -    if (!CheckConvertedConstantConversions(*this, ICS.Standard))<br>
> -      return Diag(From->getLocStart(),<br>
> -                  diag::err_typecheck_converted_constant_expression_disallowed)<br>
> -               << From->getType() << From->getSourceRange() << T;<br>
>      SCS = &ICS.Standard;<br>
>      break;<br>
>    case ImplicitConversionSequence::UserDefinedConversion:<br>
> -    // We are converting from class type to an integral or enumeration type, so<br>
> -    // the Before sequence must be trivial.<br>
> -    if (!CheckConvertedConstantConversions(*this, ICS.UserDefined.After))<br>
> -      return Diag(From->getLocStart(),<br>
> -                  diag::err_typecheck_converted_constant_expression_disallowed)<br>
> -               << From->getType() << From->getSourceRange() << T;<br>
> +    // We are converting to a non-class type, so the Before sequence<br>
> +    // must be trivial.<br>
>      SCS = &ICS.UserDefined.After;<br>
>      break;<br>
>    case ImplicitConversionSequence::AmbiguousConversion:<br>
>    case ImplicitConversionSequence::BadConversion:<br>
> -    if (!DiagnoseMultipleUserDefinedConversion(From, T))<br>
> -      return Diag(From->getLocStart(),<br>
> -                  diag::err_typecheck_converted_constant_expression)<br>
> -                    << From->getType() << From->getSourceRange() << T;<br>
> +    if (!S.DiagnoseMultipleUserDefinedConversion(From, T))<br>
> +      return S.Diag(From->getLocStart(),<br>
> +                    diag::err_typecheck_converted_constant_expression)<br>
> +                << From->getType() << From->getSourceRange() << T;<br>
>      return ExprError();<br>
><br>
>    case ImplicitConversionSequence::EllipsisConversion:<br>
>      llvm_unreachable("ellipsis conversion in converted constant expression");<br>
>    }<br>
><br>
> -  ExprResult Result = PerformImplicitConversion(From, T, ICS, AA_Converting);<br>
> +  // Check that we would only use permitted conversions.<br>
> +  if (!CheckConvertedConstantConversions(S, *SCS)) {<br>
> +    return S.Diag(From->getLocStart(),<br>
> +                  diag::err_typecheck_converted_constant_expression_disallowed)<br>
> +             << From->getType() << From->getSourceRange() << T;<br>
> +  }<br>
> +  // [...] and where the reference binding (if any) binds directly.<br>
> +  if (SCS->ReferenceBinding && !SCS->DirectBinding) {<br>
> +    return S.Diag(From->getLocStart(),<br>
> +                  diag::err_typecheck_converted_constant_expression_indirect)<br>
> +             << From->getType() << From->getSourceRange() << T;<br>
> +  }<br>
> +<br>
> +  ExprResult Result =<br>
> +      S.PerformImplicitConversion(From, T, ICS, Sema::AA_Converting);<br>
>    if (Result.isInvalid())<br>
>      return Result;<br>
><br>
>    // Check for a narrowing implicit conversion.<br>
>    APValue PreNarrowingValue;<br>
>    QualType PreNarrowingType;<br>
> -  switch (SCS->getNarrowingKind(Context, Result.get(), PreNarrowingValue,<br>
> +  switch (SCS->getNarrowingKind(S.Context, Result.get(), PreNarrowingValue,<br>
>                                  PreNarrowingType)) {<br>
>    case NK_Variable_Narrowing:<br>
>      // Implicit conversion to a narrower type, and the value is not a constant<br>
> @@ -5009,13 +5023,13 @@ ExprResult Sema::CheckConvertedConstantE<br>
>      break;<br>
><br>
>    case NK_Constant_Narrowing:<br>
> -    Diag(From->getLocStart(), diag::ext_cce_narrowing)<br>
> +    S.Diag(From->getLocStart(), diag::ext_cce_narrowing)<br>
>        << CCE << /*Constant*/1<br>
> -      << PreNarrowingValue.getAsString(Context, PreNarrowingType) << T;<br>
> +      << PreNarrowingValue.getAsString(S.Context, PreNarrowingType) << T;<br>
>      break;<br>
><br>
>    case NK_Type_Narrowing:<br>
> -    Diag(From->getLocStart(), diag::ext_cce_narrowing)<br>
> +    S.Diag(From->getLocStart(), diag::ext_cce_narrowing)<br>
>        << CCE << /*Constant*/0 << From->getType() << T;<br>
>      break;<br>
>    }<br>
> @@ -5025,12 +5039,15 @@ ExprResult Sema::CheckConvertedConstantE<br>
>    Expr::EvalResult Eval;<br>
>    Eval.Diag = &Notes;<br>
><br>
> -  if (!Result.get()->EvaluateAsRValue(Eval, Context) || !Eval.Val.isInt()) {<br>
> +  if ((T->isReferenceType()<br>
> +           ? !Result.get()->EvaluateAsLValue(Eval, S.Context)<br>
> +           : !Result.get()->EvaluateAsRValue(Eval, S.Context)) ||<br>
> +      (RequireInt && !Eval.Val.isInt())) {<br>
>      // The expression can't be folded, so we can't keep it at this position in<br>
>      // the AST.<br>
>      Result = ExprError();<br>
>    } else {<br>
> -    Value = Eval.Val.getInt();<br>
> +    Value = Eval.Val;<br>
><br>
>      if (Notes.empty()) {<br>
>        // It's a constant expression.<br>
> @@ -5041,16 +5058,34 @@ ExprResult Sema::CheckConvertedConstantE<br>
>    // It's not a constant expression. Produce an appropriate diagnostic.<br>
>    if (Notes.size() == 1 &&<br>
>        Notes[0].second.getDiagID() == diag::note_invalid_subexpr_in_const_expr)<br>
> -    Diag(Notes[0].first, diag::err_expr_not_cce) << CCE;<br>
> +    S.Diag(Notes[0].first, diag::err_expr_not_cce) << CCE;<br>
>    else {<br>
> -    Diag(From->getLocStart(), diag::err_expr_not_cce)<br>
> +    S.Diag(From->getLocStart(), diag::err_expr_not_cce)<br>
>        << CCE << From->getSourceRange();<br>
>      for (unsigned I = 0; I < Notes.size(); ++I)<br>
> -      Diag(Notes[I].first, Notes[I].second);<br>
> +      S.Diag(Notes[I].first, Notes[I].second);<br>
>    }<br>
> -  return Result;<br>
> +  return ExprError();<br>
>  }<br>
><br>
> +ExprResult Sema::CheckConvertedConstantExpression(Expr *From, QualType T,<br>
> +                                                  APValue &Value, CCEKind CCE) {<br>
> +  return ::CheckConvertedConstantExpression(*this, From, T, Value, CCE, false);<br>
> +}<br>
> +<br>
> +ExprResult Sema::CheckConvertedConstantExpression(Expr *From, QualType T,<br>
> +                                                  llvm::APSInt &Value,<br>
> +                                                  CCEKind CCE) {<br>
> +  assert(T->isIntegralOrEnumerationType() && "unexpected converted const type");<br>
> +<br>
> +  APValue V;<br>
> +  auto R = ::CheckConvertedConstantExpression(*this, From, T, V, CCE, true);<br>
> +  if (!R.isInvalid())<br>
> +    Value = V.getInt();<br>
> +  return R;<br>
> +}<br>
> +<br>
> +<br>
>  /// dropPointerConversions - If the given standard conversion sequence<br>
>  /// involves any pointer conversions, remove them.  This may change<br>
>  /// the result type of the conversion sequence.<br>
><br>
> Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=222807&r1=222806&r2=222807&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=222807&r1=222806&r2=222807&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)<br>
> +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Tue Nov 25 21:26:53 2014<br>
> @@ -4759,13 +4759,111 @@ ExprResult Sema::CheckTemplateArgument(N<br>
>      return Arg;<br>
>    }<br>
><br>
> +  QualType ParamType = InstantiatedParamType;<br>
> +  if (getLangOpts().CPlusPlus1z) {<br>
> +    // FIXME: We can do some limited checking for a value-dependent but not<br>
> +    // type-dependent argument.<br>
> +    if (Arg->isValueDependent()) {<br>
> +      Converted = TemplateArgument(Arg);<br>
> +      return Arg;<br>
> +    }<br>
> +<br>
> +    // C++1z [temp.arg.nontype]p1:<br>
> +    //   A template-argument for a non-type template parameter shall be<br>
> +    //   a converted constant expression of the type of the template-parameter.<br>
> +    APValue Value;<br>
> +    ExprResult ArgResult = CheckConvertedConstantExpression(<br>
> +        Arg, ParamType, Value, CCEK_TemplateArg);<br>
> +    if (ArgResult.isInvalid())<br>
> +      return ExprError();<br>
> +<br>
> +    // Convert the APValue to a TemplateArgument.<br>
> +    switch (Value.getKind()) {<br>
> +    case APValue::Uninitialized:<br>
> +      assert(ParamType->isNullPtrType());<br>
> +      Converted = TemplateArgument(ParamType, /*isNullPtr*/true);<br>
> +      break;<br>
> +    case APValue::Int:<br>
> +      assert(ParamType->isIntegralOrEnumerationType());<br>
> +      Converted = TemplateArgument(Context, Value.getInt(), ParamType);<br>
> +      break;<br>
> +    case APValue::MemberPointer: {<br>
> +      assert(ParamType->isMemberPointerType());<br>
> +<br>
> +      // FIXME: We need TemplateArgument representation and mangling for these.<br>
> +      if (!Value.getMemberPointerPath().empty()) {<br>
> +        Diag(Arg->getLocStart(),<br>
> +             diag::err_template_arg_member_ptr_base_derived_not_supported)<br>
> +            << Value.getMemberPointerDecl() << ParamType<br>
> +            << Arg->getSourceRange();<br>
> +        return ExprError();<br>
> +      }<br>
> +<br>
> +      auto *VD = const_cast<ValueDecl*>(Value.getMemberPointerDecl());<br>
> +      Converted = VD ? TemplateArgument(VD, ParamType)<br>
> +                     : TemplateArgument(ParamType, /*isNullPtr*/true);<br>
> +      break;<br>
> +    }<br>
> +    case APValue::LValue: {<br>
> +      //   For a non-type template-parameter of pointer or reference type,<br>
> +      //   the value of the constant expression shall not refer to<br>
> +      assert(ParamType->isPointerType() || ParamType->isReferenceType());<br>
> +      // -- a temporary object<br>
> +      // -- a string literal<br>
> +      // -- the result of a typeid expression, or<br>
> +      // -- a predefind __func__ variable<br>
> +      if (auto *E = Value.getLValueBase().dyn_cast<const Expr*>()) {<br>
> +        if (isa<CXXUuidofExpr>(E)) {<br>
> +          Converted = TemplateArgument(const_cast<Expr*>(E));<br>
> +          break;<br>
> +        }<br>
> +        Diag(Arg->getLocStart(), diag::err_template_arg_not_decl_ref)<br>
> +          << Arg->getSourceRange();<br>
> +        return ExprError();<br>
> +      }<br>
> +      auto *VD = const_cast<ValueDecl *>(<br>
> +          Value.getLValueBase().dyn_cast<const ValueDecl *>());<br>
> +      // -- a subobject<br>
> +      if (Value.hasLValuePath() && Value.getLValuePath().size() == 1 &&<br>
> +          VD && VD->getType()->isArrayType() &&<br>
> +          Value.getLValuePath()[0].ArrayIndex == 0 &&<br>
> +          !Value.isLValueOnePastTheEnd() && ParamType->isPointerType()) {<br>
> +        // Per defect report (no number yet):<br>
> +        //   ... other than a pointer to the first element of a complete array<br>
> +        //       object.<br>
> +      } else if (!Value.hasLValuePath() || Value.getLValuePath().size() ||<br>
> +                 Value.isLValueOnePastTheEnd()) {<br>
> +        Diag(StartLoc, diag::err_non_type_template_arg_subobject)<br>
> +          << Value.getAsString(Context, ParamType);<br>
> +        return ExprError();<br>
> +      }<br>
> +      assert((VD || ParamType->isPointerType()) &&<br>
> +             "null reference should not be a constant expression");<br>
> +      Converted = VD ? TemplateArgument(VD, ParamType)<br>
> +                     : TemplateArgument(ParamType, /*isNullPtr*/true);<br>
> +      break;<br>
> +    }<br>
> +    case APValue::AddrLabelDiff:<br>
> +      return Diag(StartLoc, diag::err_non_type_template_arg_addr_label_diff);<br>
> +    case APValue::Float:<br>
> +    case APValue::ComplexInt:<br>
> +    case APValue::ComplexFloat:<br>
> +    case APValue::Vector:<br>
> +    case APValue::Array:<br>
> +    case APValue::Struct:<br>
> +    case APValue::Union:<br>
> +      llvm_unreachable("invalid kind for template argument");<br>
> +    }<br>
> +<br>
> +    return ArgResult.get();<br>
> +  }<br>
> +<br>
>    // C++ [temp.arg.nontype]p5:<br>
>    //   The following conversions are performed on each expression used<br>
>    //   as a non-type template-argument. If a non-type<br>
>    //   template-argument cannot be converted to the type of the<br>
>    //   corresponding template-parameter then the program is<br>
>    //   ill-formed.<br>
> -  QualType ParamType = InstantiatedParamType;<br>
>    if (ParamType->isIntegralOrEnumerationType()) {<br>
>      // C++11:<br>
>      //   -- for a non-type template-parameter of integral or<br>
><br>
> Modified: cfe/trunk/test/CXX/drs/dr0xx.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr0xx.cpp?rev=222807&r1=222806&r2=222807&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr0xx.cpp?rev=222807&r1=222806&r2=222807&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/test/CXX/drs/dr0xx.cpp (original)<br>
> +++ cfe/trunk/test/CXX/drs/dr0xx.cpp Tue Nov 25 21:26:53 2014<br>
> @@ -521,17 +521,28 @@ namespace dr48 { // dr48: yes<br>
>  }<br>
><br>
>  namespace dr49 { // dr49: yes<br>
> -  template<int*> struct A {}; // expected-note {{here}}<br>
> +  template<int*> struct A {}; // expected-note 0-2{{here}}<br>
>    int k;<br>
>  #if __has_feature(cxx_constexpr)<br>
>    constexpr<br>
>  #endif<br>
> -  int *const p = &k;<br>
> +  int *const p = &k; // expected-note 0-2{{here}}<br>
>    A<&k> a;<br>
> -  A<p> b; // expected-error {{must have its address taken}}<br>
> +  A<p> b;<br>
> +#if __cplusplus <= 201402L<br>
> +  // expected-error@-2 {{must have its address taken}}<br>
> +#endif<br>
> +#if __cplusplus < 201103L<br>
> +  // expected-error@-5 {{internal linkage}}<br>
> +#endif<br>
> +  int *q = &k;<br>
> +  A<q> c;<br>
>  #if __cplusplus < 201103L<br>
> -  // expected-error@-2 {{internal linkage}}<br>
> -  // expected-note@-5 {{here}}<br>
> +  // expected-error@-2 {{must have its address taken}}<br>
> +#else<br>
> +  // expected-error@-4 {{constant expression}}<br>
> +  // expected-note@-5 {{read of non-constexpr}}<br>
> +  // expected-note@-7 {{declared here}}<br>
>  #endif<br>
>  }<br>
><br>
> @@ -995,6 +1006,10 @@ namespace dr92 { // dr92: yes<br>
>      g(q); // expected-error {{is not superset}}<br>
>    }<br>
><br>
> +  // Prior to C++17, this is OK because the exception specification is not<br>
> +  // considered in this context. In C++17, we *do* perform an implicit<br>
> +  // conversion (which performs initialization), but we convert to the type of<br>
> +  // the template parameter, which does not include the exception specification.<br>
>    template<void() throw()> struct X {};<br>
>    X<&f> xp; // ok<br>
>  }<br>
><br>
> Modified: cfe/trunk/test/CXX/drs/dr1xx.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr1xx.cpp?rev=222807&r1=222806&r2=222807&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr1xx.cpp?rev=222807&r1=222806&r2=222807&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/test/CXX/drs/dr1xx.cpp (original)<br>
> +++ cfe/trunk/test/CXX/drs/dr1xx.cpp Tue Nov 25 21:26:53 2014<br>
> @@ -4,8 +4,8 @@<br>
>  // RUN: %clang_cc1 -std=c++1z -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors<br>
><br>
>  namespace dr100 { // dr100: yes<br>
> -  template<const char *> struct A {}; // expected-note {{declared here}}<br>
> -  template<const char (&)[4]> struct B {}; // expected-note {{declared here}}<br>
> +  template<const char *> struct A {}; // expected-note 0-1{{declared here}}<br>
> +  template<const char (&)[4]> struct B {}; // expected-note 0-1{{declared here}}<br>
>    A<"foo"> a; // expected-error {{does not refer to any declaration}}<br>
>    B<"bar"> b; // expected-error {{does not refer to any declaration}}<br>
>  }<br>
><br>
> Modified: cfe/trunk/test/CXX/drs/dr2xx.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr2xx.cpp?rev=222807&r1=222806&r2=222807&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr2xx.cpp?rev=222807&r1=222806&r2=222807&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/test/CXX/drs/dr2xx.cpp (original)<br>
> +++ cfe/trunk/test/CXX/drs/dr2xx.cpp Tue Nov 25 21:26:53 2014<br>
> @@ -991,12 +991,11 @@ namespace dr289 { // dr289: yes<br>
>  namespace dr294 { // dr294: no<br>
>    void f() throw(int);<br>
>    int main() {<br>
> -    // FIXME: we reject this for the wrong reason, because we don't implement<br>
> -    // dr87 yet.<br>
> -    (void)static_cast<void (*)() throw()>(f); // expected-error {{not superset}}<br>
> -    void (*p)() throw() = f; // expected-error {{not superset}}<br>
> -<br>
> +    (void)static_cast<void (*)() throw()>(f); // FIXME: ill-formed<br>
>      (void)static_cast<void (*)() throw(int)>(f); // FIXME: ill-formed<br>
> +<br>
> +    void (*p)() throw() = f; // expected-error {{not superset}}<br>
> +    void (*q)() throw(int) = f;<br>
>    }<br>
>  }<br>
><br>
><br>
> Modified: cfe/trunk/test/CXX/drs/dr3xx.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr3xx.cpp?rev=222807&r1=222806&r2=222807&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr3xx.cpp?rev=222807&r1=222806&r2=222807&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/test/CXX/drs/dr3xx.cpp (original)<br>
> +++ cfe/trunk/test/CXX/drs/dr3xx.cpp Tue Nov 25 21:26:53 2014<br>
> @@ -705,7 +705,7 @@ namespace dr354 { // dr354: yes c++11<br>
>    // FIXME: Should we allow this in C++98 too?<br>
>    struct S {};<br>
><br>
> -  template<int*> struct ptr {}; // expected-note +{{here}}<br>
> +  template<int*> struct ptr {}; // expected-note 0-4{{here}}<br>
>    ptr<0> p0;<br>
>    ptr<(int*)0> p1;<br>
>    ptr<(float*)0> p2;<br>
> @@ -715,11 +715,16 @@ namespace dr354 { // dr354: yes c++11<br>
>    // expected-error@-5 {{does not refer to any decl}}<br>
>    // expected-error@-5 {{does not refer to any decl}}<br>
>    // expected-error@-5 {{does not refer to any decl}}<br>
> -#else<br>
> +#elif __cplusplus <= 201402L<br>
>    // expected-error@-10 {{must be cast}}<br>
>    // ok<br>
>    // expected-error@-10 {{does not match}}<br>
>    // expected-error@-10 {{does not match}}<br>
> +#else<br>
> +  // expected-error@-15 {{conversion from 'int' to 'int *' is not allowed}}<br>
> +  // ok<br>
> +  // expected-error@-15 {{'float *' is not implicitly convertible to 'int *'}}<br>
> +  // expected-error@-15 {{'int dr354::S::*' is not implicitly convertible to 'int *'}}<br>
>  #endif<br>
><br>
>    template<int*> int both();<br>
> @@ -732,7 +737,7 @@ namespace dr354 { // dr354: yes c++11<br>
>    // expected-note@-6 {{candidate}}<br>
>  #endif<br>
><br>
> -  template<int S::*> struct ptr_mem {}; // expected-note +{{here}}<br>
> +  template<int S::*> struct ptr_mem {}; // expected-note 0-4{{here}}<br>
>    ptr_mem<0> m0;<br>
>    ptr_mem<(int S::*)0> m1;<br>
>    ptr_mem<(float S::*)0> m2;<br>
> @@ -742,11 +747,16 @@ namespace dr354 { // dr354: yes c++11<br>
>    // expected-error@-5 {{is not a pointer to member constant}}<br>
>    // expected-error@-5 {{cannot be converted}}<br>
>    // expected-error@-5 {{cannot be converted}}<br>
> -#else<br>
> +#elif __cplusplus <= 201402L<br>
>    // expected-error@-10 {{must be cast}}<br>
>    // ok<br>
>    // expected-error@-10 {{does not match}}<br>
>    // expected-error@-10 {{does not match}}<br>
> +#else<br>
> +  // expected-error@-15 {{conversion from 'int' to 'int dr354::S::*' is not allowed}}<br>
> +  // ok<br>
> +  // expected-error@-15 {{'float dr354::S::*' is not implicitly convertible to 'int dr354::S::*'}}<br>
> +  // expected-error@-15 {{'int *' is not implicitly convertible to 'int dr354::S::*'}}<br>
>  #endif<br>
>  }<br>
><br>
><br>
> Modified: cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp?rev=222807&r1=222806&r2=222807&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp?rev=222807&r1=222806&r2=222807&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp (original)<br>
> +++ cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp Tue Nov 25 21:26:53 2014<br>
> @@ -131,14 +131,14 @@ namespace IncompleteClassTypeAddr {<br>
>  namespace UndefinedBehavior {<br>
>    void f(int n) {<br>
>      switch (n) {<br>
> -    case (int)4.4e9: // expected-error {{constant expression}} expected-note {{value 4.4E+9 is outside the range of representable values of type 'int'}} expected-note {{previous case defined here}}<br>
> +    case (int)4.4e9: // expected-error {{constant expression}} expected-note {{value 4.4E+9 is outside the range of representable values of type 'int'}}<br>
>      case (int)0x80000000u: // ok<br>
>      case (int)10000000000ll: // expected-note {{here}}<br>
>      case (unsigned int)10000000000ll: // expected-error {{duplicate case value}}<br>
>      case (int)(unsigned)(long long)4.4e9: // ok<br>
> -    case (int)(float)1e300: // expected-error {{constant expression}} expected-note {{value 1.0E+300 is outside the range of representable values of type 'float'}} expected-error {{duplicate case value '2147483647'}} expected-note {{previous case defined here}}<br>
> +    case (int)(float)1e300: // expected-error {{constant expression}} expected-note {{value 1.0E+300 is outside the range of representable values of type 'float'}}<br>
>      case (int)((float)1e37 / 1e30): // ok<br>
> -    case (int)(__fp16)65536: // expected-error {{constant expression}} expected-note {{value 65536 is outside the range of representable values of type '__fp16'}} expected-error {{duplicate case value '2147483647'}}<br>
> +    case (int)(__fp16)65536: // expected-error {{constant expression}} expected-note {{value 65536 is outside the range of representable values of type '__fp16'}}<br>
>        break;<br>
>      }<br>
>    }<br>
><br>
> Added: cfe/trunk/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp?rev=222807&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp?rev=222807&view=auto</a><br>
> ==============================================================================<br>
> --- cfe/trunk/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp (added)<br>
> +++ cfe/trunk/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp Tue Nov 25 21:26:53 2014<br>
> @@ -0,0 +1,112 @@<br>
> +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z %s<br>
> +<br>
> +template<typename T, T val> struct A {};<br>
> +<br>
> +template<typename T, typename U> constexpr bool is_same = false; // expected-note +{{here}}<br>
> +template<typename T> constexpr bool is_same<T, T> = true;<br>
> +<br>
> +namespace String {<br>
> +  A<const char*, "test"> a; // expected-error {{does not refer to any declaration}}<br>
> +  A<const char (&)[5], "test"> b; // expected-error {{does not refer to any declaration}}<br>
> +}<br>
> +<br>
> +namespace Array {<br>
> +  char arr[3];<br>
> +  char x;<br>
> +  A<const char*, arr> a;<br>
> +  A<const char(&)[3], arr> b;<br>
> +  A<const char*, &arr[0]> c;<br>
> +  A<const char*, &arr[1]> d; // expected-error {{refers to subobject '&arr[1]'}}<br>
> +  A<const char*, (&arr)[0]> e;<br>
> +  A<const char*, &x> f;<br>
> +  A<const char*, &(&x)[0]> g;<br>
> +  A<const char*, &(&x)[1]> h; // expected-error {{refers to subobject '&x + 1'}}<br>
> +  A<const char*, 0> i; // expected-error {{not allowed in a converted constant}}<br>
> +  A<const char*, nullptr> j;<br>
> +}<br>
> +<br>
> +namespace Function {<br>
> +  void f();<br>
> +  void g() noexcept;<br>
> +  void h();<br>
> +  void h(int);<br>
> +  template<typename...T> void i(T...);<br>
> +  typedef A<void (*)(), f> a;<br>
> +  typedef A<void (*)(), &f> a;<br>
> +  typedef A<void (*)(), g> b;<br>
> +  typedef A<void (*)(), &g> b;<br>
> +  typedef A<void (*)(), h> c;<br>
> +  typedef A<void (*)(), &h> c;<br>
> +  typedef A<void (*)(), i> d;<br>
> +  typedef A<void (*)(), &i> d;<br>
> +  typedef A<void (*)(), i<>> d;<br>
> +  typedef A<void (*)(), i<int>> e; // expected-error {{is not implicitly convertible}}<br>
> +<br>
> +  typedef A<void (*)(), 0> x; // expected-error {{not allowed in a converted constant}}<br>
> +  typedef A<void (*)(), nullptr> y;<br>
> +}<br>
> +<br>
> +void Func() {<br>
> +  A<const char*, __func__> a; // expected-error {{does not refer to any declaration}}<br>
> +}<br>
> +<br>
> +namespace LabelAddrDiff {<br>
> +  void f() {<br>
> +    a: b: A<int, __builtin_constant_p(true) ? (long)&&b - (long)&&a : 0> s; // expected-error {{label address difference}}<br>
> +  };<br>
> +}<br>
> +<br>
> +namespace Temp {<br>
> +  struct S { int n; };<br>
> +  constexpr S &addr(S &&s) { return s; }<br>
> +  A<S &, addr({})> a; // expected-error {{constant}} expected-note 2{{temporary}}<br>
> +  A<S *, &addr({})> b; // expected-error {{constant}} expected-note 2{{temporary}}<br>
> +  A<int &, addr({}).n> c; // expected-error {{constant}} expected-note 2{{temporary}}<br>
> +  A<int *, &addr({}).n> d; // expected-error {{constant}} expected-note 2{{temporary}}<br>
> +}<br>
> +<br>
> +namespace std { struct type_info; }<br>
> +<br>
> +namespace RTTI {<br>
> +  A<const std::type_info&, typeid(int)> a; // expected-error {{does not refer to any declaration}}<br>
> +  A<const std::type_info*, &typeid(int)> b; // expected-error {{does not refer to any declaration}}<br>
> +}<br>
> +<br>
> +namespace PtrMem {<br>
> +  struct B { int b; };<br>
> +  struct C : B {};<br>
> +  struct D : B {};<br>
> +  struct E : C, D { int e; };<br>
> +<br>
> +  constexpr int B::*b = &B::b;<br>
> +  constexpr int C::*cb = b;<br>
> +  constexpr int D::*db = b;<br>
> +  constexpr int E::*ecb = cb; // expected-note +{{here}}<br>
> +  constexpr int E::*edb = db; // expected-note +{{here}}<br>
> +<br>
> +  constexpr int E::*e = &E::e;<br>
> +  constexpr int D::*de = (int D::*)e;<br>
> +  constexpr int C::*ce = (int C::*)e;<br>
> +  constexpr int B::*bde = (int B::*)de; // expected-note +{{here}}<br>
> +  constexpr int B::*bce = (int B::*)ce; // expected-note +{{here}}<br>
> +<br>
> +  // FIXME: This should all be accepted, but we don't yet have a representation<br>
> +  // nor mangling for this form of template argument.<br>
> +  using Ab = A<int B::*, b>;<br>
> +  using Ab = A<int B::*, &B::b>;<br>
> +  using Abce = A<int B::*, bce>; // expected-error {{not supported}}<br>
> +  using Abde = A<int B::*, bde>; // expected-error {{not supported}}<br>
> +  static_assert(!is_same<Ab, Abce>, ""); // expected-error {{undeclared}} expected-error {{must be a type}}<br>
> +  static_assert(!is_same<Ab, Abde>, ""); // expected-error {{undeclared}} expected-error {{must be a type}}<br>
> +  static_assert(!is_same<Abce, Abde>, ""); // expected-error 2{{undeclared}} expected-error {{must be a type}}<br>
> +  static_assert(is_same<Abce, A<int B::*, (int B::*)(int C::*)&E::e>, ""); // expected-error {{undeclared}} expected-error {{not supported}}<br>
> +<br>
> +  using Ae = A<int E::*, e>;<br>
> +  using Ae = A<int E::*, &E::e>;<br>
> +  using Aecb = A<int E::*, ecb>; // expected-error {{not supported}}<br>
> +  using Aedb = A<int E::*, edb>; // expected-error {{not supported}}<br>
> +  static_assert(!is_same<Ae, Aecb>, ""); // expected-error {{undeclared}} expected-error {{must be a type}}<br>
> +  static_assert(!is_same<Ae, Aedb>, ""); // expected-error {{undeclared}} expected-error {{must be a type}}<br>
> +  static_assert(!is_same<Aecb, Aedb>, ""); // expected-error 2{{undeclared}} expected-error {{must be a type}}<br>
> +  static_assert(is_same<Aecb, A<int E::*, (int E::*)(int C::*)&B::b>, ""); // expected-error {{undeclared}} expected-error {{not supported}}<br>
> +}<br>
><br>
> Modified: cfe/trunk/www/cxx_status.html<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_status.html?rev=222807&r1=222806&r2=222807&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_status.html?rev=222807&r1=222806&r2=222807&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/www/cxx_status.html (original)<br>
> +++ cfe/trunk/www/cxx_status.html Tue Nov 25 21:26:53 2014<br>
> @@ -533,7 +533,7 @@ as the draft C++1z standard evolves.</p><br>
>      <!-- Rapperswil papers --><br>
>      <tr><br>
>        <td>Disabling trigraph expansion by default</td><br>
> -      <td><a href="<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3981.html" target="_blank">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3981.html</a>">N3981</a></td><br>
> +      <td><a href="<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4086.html" target="_blank">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4086.html</a>">N4086</a></td><br>
>        <td class="full" align="center">Clang 3.5</td><br>
>      </tr><br>
>      <tr><br>
> @@ -546,6 +546,11 @@ as the draft C++1z standard evolves.</p><br>
>        <td><a href="<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4051.html" target="_blank">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4051.html</a>">N4051</a></td><br>
>        <td class="full" align="center">Clang 3.5</td><br>
>      </tr><br>
> +    <tr><br>
> +      <td>New <tt>auto</tt> rules for direct-list-initialization<br>
> +      <td><a href="<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3922.html" target="_blank">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3922.html</a>">N3922</a></td><br>
> +      <td class="no" align="center">No</td><br>
> +    </tr><br>
>      <!-- Urbana papers --><br>
>      <tr><br>
>        <td>Fold expressions</td><br>
> @@ -567,6 +572,11 @@ as the draft C++1z standard evolves.</p><br>
>        <td><!--<a href="<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4266.html" target="_blank">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4266.html</a>">-->N4266<!--</a>--></td><br>
>        <td class="svn" align="center">SVN</td><br>
>      </tr><br>
> +    <tr><br>
> +      <td>Allow constant evaluation for all non-type template arguments</td><br>
> +      <td><!--<a href="<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4268.html" target="_blank">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4268.html</a>">-->N4268<!--</a>--></td><br>
> +      <td class="svn" align="center">SVN</td><br>
> +    </tr><br>
>  </table><br>
><br>
>  <h2 id="ts">Technical specifications and standing documents</h2><br>
><br>
><br>
> _______________________________________________<br>
> cfe-commits mailing list<br>
> <a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</div></div></blockquote></div><br></div></div>