Move narrowing conversion detection code from SemaInit to SemaOverload, ready
for it to be used in converted constant expression checking, and fix a couple
of issues:
 - Conversion operators implicitly invoked prior to the narrowing conversion
   were not being correctly handled when determining whether a constant value
   was narrowed.
 - For conversions from floating-point to integral types, the diagnostic text
   incorrectly always claimed that the source expression was not a constant
   expression.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148381 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index fc3c5aa..5d61406 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -1756,18 +1756,16 @@
   if (!CD->isTrivial() || !CD->isDefaultConstructor())
     return false;
 
-  if (!CD->isConstexpr()) {
+  // Value-initialization does not call a trivial default constructor, so such a
+  // call is a core constant expression whether or not the constructor is
+  // constexpr.
+  if (!CD->isConstexpr() && !IsValueInitialization) {
     if (Info.getLangOpts().CPlusPlus0x) {
-      // Value-initialization does not call a trivial default constructor, so
-      // such a call is a core constant expression whether or not the
-      // constructor is constexpr.
-      if (!IsValueInitialization) {
-        // FIXME: If DiagDecl is an implicitly-declared special member function,
-        // we should be much more explicit about why it's not constexpr.
-        Info.CCEDiag(Loc, diag::note_constexpr_invalid_function, 1)
-          << /*IsConstexpr*/0 << /*IsConstructor*/1 << CD;
-        Info.Note(CD->getLocation(), diag::note_declared_at);
-      }
+      // FIXME: If DiagDecl is an implicitly-declared special member function,
+      // we should be much more explicit about why it's not constexpr.
+      Info.CCEDiag(Loc, diag::note_constexpr_invalid_function, 1)
+        << /*IsConstexpr*/0 << /*IsConstructor*/1 << CD;
+      Info.Note(CD->getLocation(), diag::note_declared_at);
     } else {
       Info.CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
     }
@@ -5944,24 +5942,12 @@
     return false;
   }
 
-  Expr::EvalResult Result;
-  llvm::SmallVector<PartialDiagnosticAt, 8> Diags;
-  Result.Diag = &Diags;
-  EvalInfo Info(Ctx, Result);
-
-  bool IsICE = EvaluateAsRValue(Info, E, Result.Val);
-  if (!Diags.empty()) {
-    IsICE = false;
-    if (Loc) *Loc = Diags[0].first;
-  } else if (!IsICE && Loc) {
-    *Loc = E->getExprLoc();
-  }
-
-  if (!IsICE)
+  APValue Result;
+  if (!E->isCXX11ConstantExpr(Ctx, &Result, Loc))
     return false;
 
-  assert(Result.Val.isInt() && "pointer cast to int is not an ICE");
-  if (Value) *Value = Result.Val.getInt();
+  assert(Result.isInt() && "pointer cast to int is not an ICE");
+  if (Value) *Value = Result.getInt();
   return true;
 }
 
@@ -5988,3 +5974,28 @@
     llvm_unreachable("ICE cannot be evaluated!");
   return true;
 }
+
+bool Expr::isCXX11ConstantExpr(ASTContext &Ctx, APValue *Result,
+                               SourceLocation *Loc) const {
+  // We support this checking in C++98 mode in order to diagnose compatibility
+  // issues.
+  assert(Ctx.getLangOptions().CPlusPlus);
+
+  Expr::EvalStatus Status;
+  llvm::SmallVector<PartialDiagnosticAt, 8> Diags;
+  Status.Diag = &Diags;
+  EvalInfo Info(Ctx, Status);
+
+  APValue Scratch;
+  bool IsConstExpr = ::EvaluateAsRValue(Info, this, Result ? *Result : Scratch);
+
+  if (!Diags.empty()) {
+    IsConstExpr = false;
+    if (Loc) *Loc = Diags[0].first;
+  } else if (!IsConstExpr) {
+    // FIXME: This shouldn't happen.
+    if (Loc) *Loc = getExprLoc();
+  }
+
+  return IsConstExpr;
+}