Teach APValue printer to print boolean 0 and 1 as 'false' and 'true'. Fix up
some calling code to actually pass in a non-null type, to avoid a crash.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@153358 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h
index 1d53faa..d334447 100644
--- a/include/clang/Sema/Overload.h
+++ b/include/clang/Sema/Overload.h
@@ -236,7 +236,8 @@
     
     ImplicitConversionRank getRank() const;
     NarrowingKind getNarrowingKind(ASTContext &Context, const Expr *Converted,
-                                   APValue &ConstantValue) const;
+                                   APValue &ConstantValue,
+                                   QualType &ConstantType) const;
     bool isPointerConversionToBool() const;
     bool isPointerConversionToVoidPointer(ASTContext& Context) const;
     void DebugPrint() const;
diff --git a/lib/AST/APValue.cpp b/lib/AST/APValue.cpp
index 0b5b3b0..a31b3c5 100644
--- a/lib/AST/APValue.cpp
+++ b/lib/AST/APValue.cpp
@@ -312,7 +312,10 @@
     Out << "<uninitialized>";
     return;
   case APValue::Int:
-    Out << getInt();
+    if (Ty->isBooleanType())
+      Out << (getInt().getBoolValue() ? "true" : "false");
+    else
+      Out << getInt();
     return;
   case APValue::Float:
     Out << GetApproxValue(getFloat());
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 78a9f89..570b240 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -6045,7 +6045,9 @@
 
   // C++11 [dcl.init.list]p7: Check whether this is a narrowing conversion.
   APValue ConstantValue;
-  switch (SCS->getNarrowingKind(S.Context, PostInit, ConstantValue)) {
+  QualType ConstantType;
+  switch (SCS->getNarrowingKind(S.Context, PostInit, ConstantValue,
+                                ConstantType)) {
   case NK_Not_Narrowing:
     // No narrowing occurred.
     return;
@@ -6074,7 +6076,7 @@
              diag::err_init_list_constant_narrowing_sfinae
            : diag::err_init_list_constant_narrowing)
       << PostInit->getSourceRange()
-      << ConstantValue.getAsString(S.getASTContext(), EntityType)
+      << ConstantValue.getAsString(S.getASTContext(), ConstantType)
       << EntityType.getLocalUnqualifiedType();
     break;
 
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index ff227ee..be02434 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -288,10 +288,13 @@
 /// \param Converted  The result of applying this standard conversion sequence.
 /// \param ConstantValue  If this is an NK_Constant_Narrowing conversion, the
 ///        value of the expression prior to the narrowing conversion.
+/// \param ConstantType  If this is an NK_Constant_Narrowing conversion, the
+///        type of the expression prior to the narrowing conversion.
 NarrowingKind
 StandardConversionSequence::getNarrowingKind(ASTContext &Ctx,
                                              const Expr *Converted,
-                                             APValue &ConstantValue) const {
+                                             APValue &ConstantValue,
+                                             QualType &ConstantType) const {
   assert(Ctx.getLangOpts().CPlusPlus && "narrowing check outside C++");
 
   // C++11 [dcl.init.list]p7:
@@ -325,6 +328,7 @@
         // If the resulting value is different, this was a narrowing conversion.
         if (IntConstantValue != ConvertedValue) {
           ConstantValue = APValue(IntConstantValue);
+          ConstantType = Initializer->getType();
           return NK_Constant_Narrowing;
         }
       } else {
@@ -354,8 +358,10 @@
           llvm::APFloat::rmNearestTiesToEven, &ignored);
         // If there was no overflow, the source value is within the range of
         // values that can be represented.
-        if (ConvertStatus & llvm::APFloat::opOverflow)
+        if (ConvertStatus & llvm::APFloat::opOverflow) {
+          ConstantType = Initializer->getType();
           return NK_Constant_Narrowing;
+        }
       } else {
         return NK_Variable_Narrowing;
       }
@@ -400,8 +406,10 @@
         ConvertedValue = ConvertedValue.extend(InitializerValue.getBitWidth());
         ConvertedValue.setIsSigned(InitializerValue.isSigned());
         // If the result is different, this was a narrowing conversion.
-        if (ConvertedValue != InitializerValue)
+        if (ConvertedValue != InitializerValue) {
+          ConstantType = Initializer->getType();
           return NK_Constant_Narrowing;
+        }
       } else {
         // Variables are always narrowings.
         return NK_Variable_Narrowing;
@@ -4789,8 +4797,10 @@
 
   // Check for a narrowing implicit conversion.
   APValue PreNarrowingValue;
+  QualType PreNarrowingType;
   bool Diagnosed = false;
-  switch (SCS->getNarrowingKind(Context, Result.get(), PreNarrowingValue)) {
+  switch (SCS->getNarrowingKind(Context, Result.get(), PreNarrowingValue,
+                                PreNarrowingType)) {
   case NK_Variable_Narrowing:
     // Implicit conversion to a narrower type, and the value is not a constant
     // expression. We'll diagnose this in a moment.
@@ -4800,7 +4810,7 @@
   case NK_Constant_Narrowing:
     Diag(From->getLocStart(), diag::err_cce_narrowing)
       << CCE << /*Constant*/1
-      << PreNarrowingValue.getAsString(Context, QualType()) << T;
+      << PreNarrowingValue.getAsString(Context, PreNarrowingType) << T;
     Diagnosed = true;
     break;
 
diff --git a/test/SemaCXX/constexpr-printing.cpp b/test/SemaCXX/constexpr-printing.cpp
index 2e0eb9c..4e5bc42 100644
--- a/test/SemaCXX/constexpr-printing.cpp
+++ b/test/SemaCXX/constexpr-printing.cpp
@@ -96,3 +96,7 @@
   static_assert(mulBy3((LabelDiffTy)&&a-(LabelDiffTy)&&b) == 3, ""); // expected-error {{constant expression}} expected-note {{call to 'mulBy3(&&a - &&b)'}}
   a:b:return;
 }
+
+constexpr bool test_bool_printing(bool b) { return 1 / !(2*b | !(2*b)); } // expected-note 2{{division by zero}}
+constexpr bool test_bool_0 = test_bool_printing(false); // expected-error {{constant expr}} expected-note {{in call to 'test_bool_printing(false)'}}
+constexpr bool test_bool_1 = test_bool_printing(true); // expected-error {{constant expr}} expected-note {{in call to 'test_bool_printing(true)'}}