Index: include/clang/Basic/DiagnosticGroups.td
===================================================================
--- include/clang/Basic/DiagnosticGroups.td
+++ include/clang/Basic/DiagnosticGroups.td
@@ -38,7 +38,6 @@
 def ConstantConversion :
   DiagGroup<"constant-conversion", [ BitFieldConstantConversion ] >;
 def LiteralConversion : DiagGroup<"literal-conversion">;
-def StringConversion : DiagGroup<"string-conversion">;
 def SignConversion : DiagGroup<"sign-conversion">;
 def PointerBoolConversion : DiagGroup<"pointer-bool-conversion">;
 def UndefinedBoolConversion : DiagGroup<"undefined-bool-conversion">;
@@ -568,8 +567,7 @@
                             NonLiteralNullConversion, // (1-1)->pointer (etc)
                             NullConversion, // NULL->non-pointer
                             ObjCLiteralConversion,
-                            SignConversion,
-                            StringConversion]>,
+                            SignConversion]>,
                  DiagCategory<"Value Conversion Issue">;
 
 def Unused : DiagGroup<"unused",
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -2704,12 +2704,12 @@
 def warn_impcast_bitfield_precision_constant : Warning<
   "implicit truncation from %2 to bitfield changes value from %0 to %1">,
   InGroup<BitFieldConstantConversion>;
+def warn_impcast_literal_to_bool : Warning<
+  "implicit conversion from %0 to %1; will always evaluate to "
+  "'%select{false|true}2'">, InGroup<LiteralConversion>;
 def warn_impcast_literal_float_to_integer : Warning<
   "implicit conversion from %0 to %1 changes value from %2 to %3">,
   InGroup<LiteralConversion>;
-def warn_impcast_string_literal_to_bool : Warning<
-  "implicit conversion turns string literal into bool: %0 to %1">,
-  InGroup<StringConversion>, DefaultIgnore;
 def warn_impcast_different_enum_types : Warning<
   "implicit conversion from enumeration type %0 to different enumeration type "
   "%1">, InGroup<EnumConversion>;
Index: lib/Sema/SemaChecking.cpp
===================================================================
--- lib/Sema/SemaChecking.cpp
+++ lib/Sema/SemaChecking.cpp
@@ -6982,10 +6982,7 @@
   Value.toString(PrettySourceValue, precision);
 
   SmallString<16> PrettyTargetValue;
-  if (T->isSpecificBuiltinType(BuiltinType::Bool))
-    PrettyTargetValue = Value.isZero() ? "false" : "true";
-  else
-    IntegerValue.toString(PrettyTargetValue);
+  IntegerValue.toString(PrettyTargetValue);
 
   S.Diag(FL->getExprLoc(), diag::warn_impcast_literal_float_to_integer)
     << FL->getType() << T.getUnqualifiedType() << PrettySourceValue
@@ -7190,12 +7187,31 @@
 
   // Diagnose implicit casts to bool.
   if (Target->isSpecificBuiltinType(BuiltinType::Bool)) {
-    if (isa<StringLiteral>(E))
-      // Warn on string literal to bool.  Checks for string literals in logical
-      // and expressions, for instance, assert(0 && "error here"), are
-      // prevented by a check in AnalyzeImplicitConversions().
-      return DiagnoseImpCast(S, E, T, CC,
-                             diag::warn_impcast_string_literal_to_bool);
+    if (isa<StringLiteral>(E)) {
+      // Warn on string literal to bool. Checks for string literals in logical
+      // AND expressions, for instance, assert(0 && "error here"), are
+      // prevented by a check in AnalyzeImplicitConversions(). All string
+      // literal implicit conversions to bool evaluate to true.
+      S.Diag(E->getLocStart(), diag::warn_impcast_literal_to_bool)
+          << E->getType() << T << true << E->getSourceRange()
+          << SourceRange(CC);
+      return;
+    }
+    if (const auto *CharLit = dyn_cast<CharacterLiteral>(E)) {
+      // Warn on char literal to bool.
+      S.Diag(CharLit->getLocation(), diag::warn_impcast_literal_to_bool)
+          << E->getType() << T << (bool)CharLit->getValue()
+          << E->getSourceRange() << SourceRange(CC);
+      return;
+    }
+    if (const auto *FL = dyn_cast<FloatingLiteral>(E)) {
+      // When converting from a floating-point literal to boolean, always
+      // diagnose, even if the literal will exactly convert to an interger.
+      S.Diag(FL->getExprLoc(), diag::warn_impcast_literal_to_bool)
+          << FL->getType() << T.getUnqualifiedType() << !FL->getValue().isZero()
+          << FL->getSourceRange() << SourceRange(CC);
+      return;
+    }
     if (isa<ObjCStringLiteral>(E) || isa<ObjCArrayLiteral>(E) ||
         isa<ObjCDictionaryLiteral>(E) || isa<ObjCBoxedExpr>(E)) {
       // This covers the literal expressions that evaluate to Objective-C
Index: test/Analysis/casts.c
===================================================================
--- test/Analysis/casts.c
+++ test/Analysis/casts.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify %s
-// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -Wno-literal-conversion -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -Wno-literal-conversion -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify %s
 
 extern void clang_analyzer_eval(_Bool);
 
Index: test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp
===================================================================
--- test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp
+++ test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -std=c++11 -triple x86_64-apple-macosx10.6.7 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-literal-conversion -std=c++11 -triple x86_64-apple-macosx10.6.7 -verify %s
 
 // Verify that narrowing conversions in initializer lists cause errors in C++0x
 // mode.
Index: test/CXX/expr/expr.unary/expr.unary.op/p6.cpp
===================================================================
--- test/CXX/expr/expr.unary/expr.unary.op/p6.cpp
+++ test/CXX/expr/expr.unary/expr.unary.op/p6.cpp
@@ -4,7 +4,7 @@
 
 bool b = !0;
 
-bool b2 = !1.2; //expected-warning{{implicit conversion from 'double' to 'bool' changes value from 1.2 to true}}
+bool b2 = !1.2; //expected-warning{{implicit conversion from 'double' to 'bool'; will always evaluate to 'true'}}
 
 bool b3 = !4;
 
Index: test/Sema/exprs.c
===================================================================
--- test/Sema/exprs.c
+++ test/Sema/exprs.c
@@ -242,7 +242,7 @@
 
 // Make sure we do function/array decay.
 void test22() {
-  if ("help")
+  if ("help") // expected-warning {{implicit conversion from 'char [5]' to '_Bool'; will always evaluate to 'true'}}
     (void) 0;
 
   if (test22) // expected-warning {{address of function 'test22' will always evaluate to 'true'}} \
Index: test/Sema/warn-string-conversion.c
===================================================================
--- test/Sema/warn-string-conversion.c
+++ test/Sema/warn-string-conversion.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fsyntax-only -Wstring-conversion %s
+// RUN: %clang_cc1 -verify -fsyntax-only %s
 
 void do_nothing();
 void assert_error();
@@ -16,19 +16,19 @@
 void test1() {
   assert1(0 && "foo");
   assert1("foo" && 0);
-  assert1(0 || "foo"); // expected-warning {{string literal}}
-  assert1("foo"); // expected-warning {{string literal}}
+  assert1(0 || "foo"); // expected-warning {{implicit conversion from 'char [4]' to '_Bool'; will always evaluate to 'true'}}
+  assert1("foo"); // expected-warning {{implicit conversion from 'char [4]' to '_Bool'; will always evaluate to 'true'}}
 
   assert2(0 && "foo");
   assert2("foo" && 0);
-  assert2(0 || "foo"); // expected-warning {{string literal}}
-  assert2("foo"); // expected-warning {{string literal}}
+  assert2(0 || "foo"); // expected-warning {{implicit conversion from 'char [4]' to '_Bool'; will always evaluate to 'true'}}
+  assert2("foo"); // expected-warning {{implicit conversion from 'char [4]' to '_Bool'; will always evaluate to 'true'}}
 }
 
 void test2() {
-  if ("hi") {}           // expected-warning {{string literal}}
-  while ("hello") {}     // expected-warning {{string literal}}
-  for (;"howdy";) {}     // expected-warning {{string literal}}
-  do { } while ("hey");  // expected-warning {{string literal}}
-  int x = "hey" ? 1 : 2; // expected-warning {{string literal}}
+  if ("hi") {}           // expected-warning {{implicit conversion from 'char [3]' to '_Bool'; will always evaluate to 'true'}}
+  while ("hello") {}     // expected-warning {{implicit conversion from 'char [6]' to '_Bool'; will always evaluate to 'true'}}
+  for (;"howdy";) {}     // expected-warning {{implicit conversion from 'char [6]' to '_Bool'; will always evaluate to 'true'}}
+  do { } while ("hey");  // expected-warning {{implicit conversion from 'char [4]' to '_Bool'; will always evaluate to 'true'}}
+  int x = "hey" ? 1 : 2; // expected-warning {{implicit conversion from 'char [4]' to '_Bool'; will always evaluate to 'true'}}
 }
Index: test/SemaCXX/condition.cpp
===================================================================
--- test/SemaCXX/condition.cpp
+++ test/SemaCXX/condition.cpp
@@ -45,7 +45,7 @@
 
 // Make sure we do function/array decay.
 void test3() {
-  if ("help")
+  if ("help") // expected-warning {{implicit conversion from 'const char [5]' to 'bool'; will always evaluate to 'true'}}
     (void) 0;
 
   if (test3) // expected-warning {{address of function 'test3' will always evaluate to 'true'}} \
Index: test/SemaCXX/overload-call.cpp
===================================================================
--- test/SemaCXX/overload-call.cpp
+++ test/SemaCXX/overload-call.cpp
@@ -69,7 +69,7 @@
 #else
   // expected-error@-4 {{cannot initialize a variable of type 'int *' with an rvalue of type 'double *'}}
 #endif
-  double* dp1 = k(L"foo");
+  double* dp1 = k(L"foo"); // expected-warning {{implicit conversion from 'const wchar_t [4]' to 'bool'; will always evaluate to 'true'}}
 }
 
 int* l(wchar_t*);
@@ -82,7 +82,7 @@
 #else
   // expected-error@-4 {{cannot initialize a variable of type 'int *' with an rvalue of type 'double *'}}
 #endif
-  double* dp1 = l("foo");
+  double* dp1 = l("foo"); // expected-warning {{implicit conversion from 'const char [4]' to 'bool'; will always evaluate to 'true'}}
 }
 
 int* m(const char*);
Index: test/SemaCXX/warn-literal-conversion.cpp
===================================================================
--- test/SemaCXX/warn-literal-conversion.cpp
+++ test/SemaCXX/warn-literal-conversion.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wliteral-conversion -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wliteral-conversion -std=c++1z -verify %s
 
 void foo(int y);
 
@@ -42,10 +42,26 @@
 // Similarly, test floating point conversion to bool. Only float values of zero
 // are converted to false; everything else is converted to true.
 void test1() {
-  bool b1 = 0.99f; // expected-warning {{implicit conversion from 'float' to 'bool' changes value from 0.99 to true}}
-  bool b2 = 0.99; // expected-warning {{implicit conversion from 'double' to 'bool' changes value from 0.99 to true}}
-  // These do not warn because they can be directly converted to integral
-  // values.
-  bool b3 = 0.0f;
-  bool b4 = 0.0;
+  bool b1 = 0.99f; // expected-warning {{implicit conversion from 'float' to 'bool'; will always evaluate to 'true'}}
+  bool b2 = 0.99; // expected-warning {{implicit conversion from 'double' to 'bool'; will always evaluate to 'true'}}
+  bool b3 = 0.0f; // expected-warning {{implicit conversion from 'float' to 'bool'; will always evaluate to 'false'}}
+  bool b4 = 0.0; // expected-warning {{implicit conversion from 'double' to 'bool'; will always evaluate to 'false'}}
+
+  bool b5 = "false"; // expected-warning {{implicit conversion from 'const char [6]' to 'bool'; will always evaluate to 'true'}}
+  bool b6 = L"false"; // expected-warning {{implicit conversion from 'const wchar_t [6]' to 'bool'; will always evaluate to 'true'}}
+  bool b7 = u"0"; // expected-warning {{implicit conversion from 'const char16_t [2]' to 'bool'; will always evaluate to 'true'}}
+  bool b8 = U"false"; // expected-warning {{implicit conversion from 'const char32_t [6]' to 'bool'; will always evaluate to 'true'}}
+  bool b9 = u8"0"; // expected-warning {{implicit conversion from 'const char [2]' to 'bool'; will always evaluate to 'true'}}
+
+  bool b10 = '\0'; // expected-warning {{implicit conversion from 'char' to 'bool'; will always evaluate to 'false'}}
+  bool b11 = L'1'; // expected-warning {{implicit conversion from 'wchar_t' to 'bool'; will always evaluate to 'true'}}
+  bool b12 = U'\0'; // expected-warning {{implicit conversion from 'char32_t' to 'bool'; will always evaluate to 'false'}}
+  bool b13 = u'1'; // expected-warning {{implicit conversion from 'char16_t' to 'bool'; will always evaluate to 'true'}}
+  bool b14 = u8'\0'; // expected-warning {{implicit conversion from 'char' to 'bool'; will always evaluate to 'false'}}
 }
+
+#define assert(x) (void)(!!(x))
+void should_not_diagnose() {
+  assert(1 && "false");
+  assert(1 && "some random string");
+}
Index: test/SemaCXX/warn-string-conversion.cpp
===================================================================
--- test/SemaCXX/warn-string-conversion.cpp
+++ test/SemaCXX/warn-string-conversion.cpp
@@ -1,24 +1,24 @@
-// RUN: %clang_cc1 -fsyntax-only -Wstring-conversion -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
 
 // Warn on cases where a string literal is converted into a bool.
 // An exception is made for this in logical and operators.
 void assert(bool condition);
 void test0() {
-  bool b0 = "hi"; // expected-warning{{implicit conversion turns string literal into bool: 'const char [3]' to 'bool'}}
-  b0 = ""; // expected-warning{{implicit conversion turns string literal into bool: 'const char [1]' to 'bool'}}
-  b0 = 0 || ""; // expected-warning{{implicit conversion turns string literal into bool: 'const char [1]' to 'bool'}}
-  b0 = "" || 0; // expected-warning{{implicit conversion turns string literal into bool: 'const char [1]' to 'bool'}}
+  bool b0 = "hi"; // expected-warning{{implicit conversion from 'const char [3]' to 'bool'; will always evaluate to 'true'}}
+  b0 = ""; // expected-warning{{implicit conversion from 'const char [1]' to 'bool'; will always evaluate to 'true'}}
+  b0 = 0 || ""; // expected-warning{{implicit conversion from 'const char [1]' to 'bool'; will always evaluate to 'true'}}
+  b0 = "" || 0; // expected-warning{{implicit conversion from 'const char [1]' to 'bool'; will always evaluate to 'true'}}
   b0 = 0 && "";
   b0 = "" && 0;
-  assert("error"); // expected-warning{{implicit conversion turns string literal into bool: 'const char [6]' to 'bool'}}
-  assert(0 || "error"); // expected-warning{{implicit conversion turns string literal into bool: 'const char [6]' to 'bool'}}
-  assert("error" || 0); // expected-warning{{implicit conversion turns string literal into bool: 'const char [6]' to 'bool'}}
+  assert("error"); // expected-warning{{implicit conversion from 'const char [6]' to 'bool'; will always evaluate to 'true'}}
+  assert(0 || "error"); // expected-warning{{implicit conversion from 'const char [6]' to 'bool'; will always evaluate to 'true'}}
+  assert("error" || 0); // expected-warning{{implicit conversion from 'const char [6]' to 'bool'; will always evaluate to 'true'}}
   assert(0 && "error");
   assert("error" && 0);
 
-  while("hi") {} // expected-warning{{implicit conversion turns string literal into bool: 'const char [3]' to 'bool'}}
-  do {} while("hi"); // expected-warning{{implicit conversion turns string literal into bool: 'const char [3]' to 'bool'}}
-  for (;"hi";); // expected-warning{{implicit conversion turns string literal into bool: 'const char [3]' to 'bool'}}
-  if("hi") {} // expected-warning{{implicit conversion turns string literal into bool: 'const char [3]' to 'bool'}}
+  while("hi") {} // expected-warning{{implicit conversion from 'const char [3]' to 'bool'; will always evaluate to 'true'}}
+  do {} while("hi"); // expected-warning{{implicit conversion from 'const char [3]' to 'bool'; will always evaluate to 'true'}}
+  for (;"hi";); // expected-warning{{implicit conversion from 'const char [3]' to 'bool'; will always evaluate to 'true'}}
+  if("hi") {} // expected-warning{{implicit conversion from 'const char [3]' to 'bool'; will always evaluate to 'true'}}
 }
 
Index: test/SemaCXX/warn-thread-safety-analysis.cpp
===================================================================
--- test/SemaCXX/warn-thread-safety-analysis.cpp
+++ test/SemaCXX/warn-thread-safety-analysis.cpp
@@ -1046,8 +1046,8 @@
   struct Bas { void operator& (Foo &) {} };
   void mumble()
   {
-    Bas() & Bar().func() << "" << "";
-    Bas() & Bar().func() << "";
+    Bas() & Bar().func() << true << true;
+    Bas() & Bar().func() << true;
   }
 } // end namespace thread_annot_lock_61_modified