[c++1z] Most of N4268 (allow constant evaluation for non-type template arguments).

We don't yet support pointer-to-member template arguments that have undergone
pointer-to-member conversions, mostly because we don't have a mangling for them yet.

llvm-svn: 222807
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 5e02647..d33f126 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -4894,41 +4894,51 @@
   // conversions are fine.
   switch (SCS.Second) {
   case ICK_Identity:
+  case ICK_NoReturn_Adjustment:
   case ICK_Integral_Promotion:
-  case ICK_Integral_Conversion:
-  case ICK_Zero_Event_Conversion:
+  case ICK_Integral_Conversion: // Narrowing conversions are checked elsewhere.
     return true;
 
   case ICK_Boolean_Conversion:
     // Conversion from an integral or unscoped enumeration type to bool is
-    // classified as ICK_Boolean_Conversion, but it's also an integral
-    // conversion, so it's permitted in a converted constant expression.
+    // classified as ICK_Boolean_Conversion, but it's also arguably an integral
+    // conversion, so we allow it in a converted constant expression.
+    //
+    // FIXME: Per core issue 1407, we should not allow this, but that breaks
+    // a lot of popular code. We should at least add a warning for this
+    // (non-conforming) extension.
     return SCS.getFromType()->isIntegralOrUnscopedEnumerationType() &&
            SCS.getToType(2)->isBooleanType();
 
+  case ICK_Pointer_Conversion:
+  case ICK_Pointer_Member:
+    // C++1z: null pointer conversions and null member pointer conversions are
+    // only permitted if the source type is std::nullptr_t.
+    return SCS.getFromType()->isNullPtrType();
+
+  case ICK_Floating_Promotion:
+  case ICK_Complex_Promotion:
+  case ICK_Floating_Conversion:
+  case ICK_Complex_Conversion:
   case ICK_Floating_Integral:
+  case ICK_Compatible_Conversion:
+  case ICK_Derived_To_Base:
+  case ICK_Vector_Conversion:
+  case ICK_Vector_Splat:
   case ICK_Complex_Real:
+  case ICK_Block_Pointer_Conversion:
+  case ICK_TransparentUnionConversion:
+  case ICK_Writeback_Conversion:
+  case ICK_Zero_Event_Conversion:
     return false;
 
   case ICK_Lvalue_To_Rvalue:
   case ICK_Array_To_Pointer:
   case ICK_Function_To_Pointer:
-  case ICK_NoReturn_Adjustment:
+    llvm_unreachable("found a first conversion kind in Second");
+
   case ICK_Qualification:
-  case ICK_Compatible_Conversion:
-  case ICK_Vector_Conversion:
-  case ICK_Vector_Splat:
-  case ICK_Derived_To_Base:
-  case ICK_Pointer_Conversion:
-  case ICK_Pointer_Member:
-  case ICK_Block_Pointer_Conversion:
-  case ICK_Writeback_Conversion:
-  case ICK_Floating_Promotion:
-  case ICK_Complex_Promotion:
-  case ICK_Complex_Conversion:
-  case ICK_Floating_Conversion:
-  case ICK_TransparentUnionConversion:
-    llvm_unreachable("unexpected second conversion kind");
+    llvm_unreachable("found a third conversion kind in Second");
 
   case ICK_Num_Conversion_Kinds:
     break;
@@ -4940,67 +4950,71 @@
 /// CheckConvertedConstantExpression - Check that the expression From is a
 /// converted constant expression of type T, perform the conversion and produce
 /// the converted expression, per C++11 [expr.const]p3.
-ExprResult Sema::CheckConvertedConstantExpression(Expr *From, QualType T,
-                                                  llvm::APSInt &Value,
-                                                  CCEKind CCE) {
-  assert(LangOpts.CPlusPlus11 && "converted constant expression outside C++11");
-  assert(T->isIntegralOrEnumerationType() && "unexpected converted const type");
+static ExprResult CheckConvertedConstantExpression(Sema &S, Expr *From,
+                                                   QualType T, APValue &Value,
+                                                   Sema::CCEKind CCE,
+                                                   bool RequireInt) {
+  assert(S.getLangOpts().CPlusPlus11 &&
+         "converted constant expression outside C++11");
 
-  if (checkPlaceholderForOverload(*this, From))
+  if (checkPlaceholderForOverload(S, From))
     return ExprError();
 
-  // C++11 [expr.const]p3 with proposed wording fixes:
-  //  A converted constant expression of type T is a core constant expression,
-  //  implicitly converted to a prvalue of type T, where the converted
-  //  expression is a literal constant expression and the implicit conversion
-  //  sequence contains only user-defined conversions, lvalue-to-rvalue
-  //  conversions, integral promotions, and integral conversions other than
-  //  narrowing conversions.
+  // C++1z [expr.const]p3:
+  //  A converted constant expression of type T is an expression,
+  //  implicitly converted to type T, where the converted
+  //  expression is a constant expression and the implicit conversion
+  //  sequence contains only [... list of conversions ...].
   ImplicitConversionSequence ICS =
-    TryImplicitConversion(From, T,
+    TryCopyInitialization(S, From, T,
                           /*SuppressUserConversions=*/false,
-                          /*AllowExplicit=*/false,
                           /*InOverloadResolution=*/false,
-                          /*CStyle=*/false,
-                          /*AllowObjcWritebackConversion=*/false);
+                          /*AllowObjcWritebackConversion=*/false,
+                          /*AllowExplicit=*/false);
   StandardConversionSequence *SCS = nullptr;
   switch (ICS.getKind()) {
   case ImplicitConversionSequence::StandardConversion:
-    if (!CheckConvertedConstantConversions(*this, ICS.Standard))
-      return Diag(From->getLocStart(),
-                  diag::err_typecheck_converted_constant_expression_disallowed)
-               << From->getType() << From->getSourceRange() << T;
     SCS = &ICS.Standard;
     break;
   case ImplicitConversionSequence::UserDefinedConversion:
-    // We are converting from class type to an integral or enumeration type, so
-    // the Before sequence must be trivial.
-    if (!CheckConvertedConstantConversions(*this, ICS.UserDefined.After))
-      return Diag(From->getLocStart(),
-                  diag::err_typecheck_converted_constant_expression_disallowed)
-               << From->getType() << From->getSourceRange() << T;
+    // We are converting to a non-class type, so the Before sequence
+    // must be trivial.
     SCS = &ICS.UserDefined.After;
     break;
   case ImplicitConversionSequence::AmbiguousConversion:
   case ImplicitConversionSequence::BadConversion:
-    if (!DiagnoseMultipleUserDefinedConversion(From, T))
-      return Diag(From->getLocStart(),
-                  diag::err_typecheck_converted_constant_expression)
-                    << From->getType() << From->getSourceRange() << T;
+    if (!S.DiagnoseMultipleUserDefinedConversion(From, T))
+      return S.Diag(From->getLocStart(),
+                    diag::err_typecheck_converted_constant_expression)
+                << From->getType() << From->getSourceRange() << T;
     return ExprError();
 
   case ImplicitConversionSequence::EllipsisConversion:
     llvm_unreachable("ellipsis conversion in converted constant expression");
   }
 
-  ExprResult Result = PerformImplicitConversion(From, T, ICS, AA_Converting);
+  // Check that we would only use permitted conversions.
+  if (!CheckConvertedConstantConversions(S, *SCS)) {
+    return S.Diag(From->getLocStart(),
+                  diag::err_typecheck_converted_constant_expression_disallowed)
+             << From->getType() << From->getSourceRange() << T;
+  }
+  // [...] and where the reference binding (if any) binds directly.
+  if (SCS->ReferenceBinding && !SCS->DirectBinding) {
+    return S.Diag(From->getLocStart(),
+                  diag::err_typecheck_converted_constant_expression_indirect)
+             << From->getType() << From->getSourceRange() << T;
+  }
+
+  ExprResult Result =
+      S.PerformImplicitConversion(From, T, ICS, Sema::AA_Converting);
   if (Result.isInvalid())
     return Result;
 
   // Check for a narrowing implicit conversion.
   APValue PreNarrowingValue;
   QualType PreNarrowingType;
-  switch (SCS->getNarrowingKind(Context, Result.get(), PreNarrowingValue,
+  switch (SCS->getNarrowingKind(S.Context, Result.get(), PreNarrowingValue,
                                 PreNarrowingType)) {
   case NK_Variable_Narrowing:
     // Implicit conversion to a narrower type, and the value is not a constant
@@ -5009,13 +5023,13 @@
     break;
 
   case NK_Constant_Narrowing:
-    Diag(From->getLocStart(), diag::ext_cce_narrowing)
+    S.Diag(From->getLocStart(), diag::ext_cce_narrowing)
       << CCE << /*Constant*/1
-      << PreNarrowingValue.getAsString(Context, PreNarrowingType) << T;
+      << PreNarrowingValue.getAsString(S.Context, PreNarrowingType) << T;
     break;
 
   case NK_Type_Narrowing:
-    Diag(From->getLocStart(), diag::ext_cce_narrowing)
+    S.Diag(From->getLocStart(), diag::ext_cce_narrowing)
       << CCE << /*Constant*/0 << From->getType() << T;
     break;
   }
@@ -5025,12 +5039,15 @@
   Expr::EvalResult Eval;
   Eval.Diag = &Notes;
 
-  if (!Result.get()->EvaluateAsRValue(Eval, Context) || !Eval.Val.isInt()) {
+  if ((T->isReferenceType()
+           ? !Result.get()->EvaluateAsLValue(Eval, S.Context)
+           : !Result.get()->EvaluateAsRValue(Eval, S.Context)) ||
+      (RequireInt && !Eval.Val.isInt())) {
     // The expression can't be folded, so we can't keep it at this position in
     // the AST.
     Result = ExprError();
   } else {
-    Value = Eval.Val.getInt();
+    Value = Eval.Val;
 
     if (Notes.empty()) {
       // It's a constant expression.
@@ -5041,16 +5058,34 @@
   // It's not a constant expression. Produce an appropriate diagnostic.
   if (Notes.size() == 1 &&
       Notes[0].second.getDiagID() == diag::note_invalid_subexpr_in_const_expr)
-    Diag(Notes[0].first, diag::err_expr_not_cce) << CCE;
+    S.Diag(Notes[0].first, diag::err_expr_not_cce) << CCE;
   else {
-    Diag(From->getLocStart(), diag::err_expr_not_cce)
+    S.Diag(From->getLocStart(), diag::err_expr_not_cce)
       << CCE << From->getSourceRange();
     for (unsigned I = 0; I < Notes.size(); ++I)
-      Diag(Notes[I].first, Notes[I].second);
+      S.Diag(Notes[I].first, Notes[I].second);
   }
-  return Result;
+  return ExprError();
 }
 
+ExprResult Sema::CheckConvertedConstantExpression(Expr *From, QualType T,
+                                                  APValue &Value, CCEKind CCE) {
+  return ::CheckConvertedConstantExpression(*this, From, T, Value, CCE, false);
+}
+
+ExprResult Sema::CheckConvertedConstantExpression(Expr *From, QualType T,
+                                                  llvm::APSInt &Value,
+                                                  CCEKind CCE) {
+  assert(T->isIntegralOrEnumerationType() && "unexpected converted const type");
+
+  APValue V;
+  auto R = ::CheckConvertedConstantExpression(*this, From, T, V, CCE, true);
+  if (!R.isInvalid())
+    Value = V.getInt();
+  return R;
+}
+
+
 /// dropPointerConversions - If the given standard conversion sequence
 /// involves any pointer conversions, remove them.  This may change
 /// the result type of the conversion sequence.