diff --git include/clang/Basic/DiagnosticSemaKinds.td include/clang/Basic/DiagnosticSemaKinds.td
index f566e10..7d8e1ea 100644
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -1648,6 +1648,9 @@ def warn_impcast_bool_to_null_pointer : Warning<
 def warn_impcast_null_pointer_to_integer : Warning<
     "implicit conversion of NULL constant to integer">,
     InGroup<DiagGroup<"conversion">>, DefaultIgnore;
+def warn_impcast_function_to_bool : Warning<
+    "the address of %q0 will always evaluate to 'true'">,
+    InGroup<BoolConversions>;
 
 def warn_cast_align : Warning<
   "cast from %0 to %1 increases required alignment from %2 to %3">,
diff --git lib/Sema/SemaChecking.cpp lib/Sema/SemaChecking.cpp
index c66b8da..23cbb56 100644
--- lib/Sema/SemaChecking.cpp
+++ lib/Sema/SemaChecking.cpp
@@ -3758,6 +3758,24 @@ void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
       // by a check in AnalyzeImplicitConversions().
       return DiagnoseImpCast(S, E, T, CC,
                              diag::warn_impcast_string_literal_to_bool);
+    if (Source->isFunctionType()) {
+      // Warn on function to bool. Checks free functions and static member
+      // functions. Weakly imported functions are excluded from the check,
+      // since it's common to test their value to check whether the linker
+      // found a definition for them.
+      Decl *D = 0;
+      if (DeclRefExpr* R = dyn_cast<DeclRefExpr>(E)) {
+        D = R->getDecl();
+      } else if (MemberExpr *M = dyn_cast<MemberExpr>(E)) {
+        D = M->getMemberDecl();
+      }
+
+      if (D && !D->isWeakImported()) {
+        FunctionDecl* F = cast<FunctionDecl>(D);
+        S.Diag(E->getExprLoc(), diag::warn_impcast_function_to_bool) << F;
+        return;
+      }
+    }
     return; // Other casts to bool are not checked.
   }
 
diff --git test/CXX/over/over.over/p2-resolve-single-template-id.cpp test/CXX/over/over.over/p2-resolve-single-template-id.cpp
index 1bd0d34..7bf3d73 100644
--- test/CXX/over/over.over/p2-resolve-single-template-id.cpp
+++ test/CXX/over/over.over/p2-resolve-single-template-id.cpp
@@ -100,8 +100,8 @@ int main()
   { (void) reinterpret_cast<int>(two); } //expected-error {{reinterpret_cast}}
   { (void) reinterpret_cast<int (*)(char, double)>(two); } //expected-error {{reinterpret_cast}}
 
-  { bool b = (twoT<int>); } // ok
-  { bool b = (twoT<int, int>); } //ok
+  { bool b = (twoT<int>); } // expected-warning {{the address of 'twoT<int>' will always evaluate to 'true'}}
+  { bool b = (twoT<int, int>); } // expected-warning {{the address of 'twoT<int, int>' will always evaluate to 'true'}}
 
   { bool b = &twoT<int>; //&foo<int>; }
     b = &(twoT<int>); }
@@ -142,20 +142,20 @@ namespace member_pointers {
     if (&s.f<char>) return; // expected-error {{cannot create a non-constant pointer to member function}}
     if (&s.f<int>) return; // expected-error {{cannot create a non-constant pointer to member function}}
 
-    if (S::g<char>) return;
-    if (S::g<int>) return;
+    if (S::g<char>) return; // expected-warning {{the address of 'member_pointers::S::g<char>' will always evaluate to 'true'}}
+    if (S::g<int>) return; // expected-warning {{the address of 'member_pointers::S::g<int>' will always evaluate to 'true'}}
     if (&S::g<char>) return;
     if (&S::g<int>) return;
-    if (s.g<char>) return;
-    if (s.g<int>) return;
+    if (s.g<char>) return; // expected-warning {{the address of 'member_pointers::S::g<char>' will always evaluate to 'true'}}
+    if (s.g<int>) return; // expected-warning {{the address of 'member_pointers::S::g<int>' will always evaluate to 'true'}}
     if (&s.g<char>) return;
     if (&s.g<int>) return;
 
-    if (S::h<42>) return;
+    if (S::h<42>) return; // expected-warning {{the address of 'member_pointers::S::h<42>' will always evaluate to 'true'}}
     if (S::h<int>) return; // expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}}
     if (&S::h<42>) return;
     if (&S::h<int>) return;
-    if (s.h<42>) return;
+    if (s.h<42>) return;  // expected-warning {{the address of 'member_pointers::S::h<42>' will always evaluate to 'true'}}
     if (s.h<int>) return; // expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}}
     if (&s.h<42>) return;
     if (&s.h<int>) return; // expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}}
@@ -170,20 +170,20 @@ namespace member_pointers {
     { bool b = &s.f<char>; } // expected-error {{cannot create a non-constant pointer to member function}}
     { bool b = &s.f<int>; } // expected-error {{cannot create a non-constant pointer to member function}}
 
-    { bool b = S::g<char>; }
-    { bool b = S::g<int>; }
+    { bool b = S::g<char>; } // expected-warning {{the address of 'member_pointers::S::g<char>' will always evaluate to 'true'}}
+    { bool b = S::g<int>; } // expected-warning {{the address of 'member_pointers::S::g<int>' will always evaluate to 'true'}}
     { bool b = &S::g<char>; }
     { bool b = &S::g<int>; }
-    { bool b = s.g<char>; }
-    { bool b = s.g<int>; }
+    { bool b = s.g<char>; }  // expected-warning {{the address of 'member_pointers::S::g<char>' will always evaluate to 'true'}}
+    { bool b = s.g<int>; } // expected-warning {{the address of 'member_pointers::S::g<int>' will always evaluate to 'true'}}
     { bool b = &s.g<char>; }
     { bool b = &s.g<int>; }
 
-    { bool b = S::h<42>; }
+    { bool b = S::h<42>; } // expected-warning {{the address of 'member_pointers::S::h<42>' will always evaluate to 'true'}}
     { bool b = S::h<int>; } // expected-error {{can't form member pointer of type 'bool' without '&' and class name}}
     { bool b = &S::h<42>; }
     { bool b = &S::h<int>; }
-    { bool b = s.h<42>; }
+    { bool b = s.h<42>; }  // expected-warning {{the address of 'member_pointers::S::h<42>' will always evaluate to 'true'}}
     { bool b = s.h<int>; } // expected-error {{can't form member pointer of type 'bool' without '&' and class name}}
     { bool b = &s.h<42>; }
     { bool b = &s.h<int>; } // expected-error {{can't form member pointer of type 'bool' without '&' and class name}}
diff --git test/SemaCXX/condition.cpp test/SemaCXX/condition.cpp
index 3441bae..6c739f2 100644
--- test/SemaCXX/condition.cpp
+++ test/SemaCXX/condition.cpp
@@ -49,6 +49,6 @@ void test3() {
   if ("help")
     (void) 0;
 
-  if (test3)
+  if (test3) // expected-warning {{the address of 'test3' will always evaluate to 'true'}}
     (void) 0;
 }
diff --git test/SemaCXX/warn-func-as-bool.cpp test/SemaCXX/warn-func-as-bool.cpp
new file mode 100644
index 0000000..24f6120
--- /dev/null
+++ test/SemaCXX/warn-func-as-bool.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -x c++ -verify -fsyntax-only %s
+
+void f1();
+
+struct S {
+  static void f2();
+};
+
+extern void f3() __attribute__((weak_import));
+
+struct S2 {
+  static void f4() __attribute__((weak_import));
+};
+
+void bar() {
+
+  bool b1 = f1; // expected-warning {{the address of 'f1' will always evaluate to 'true'}}
+  if (f1) { // expected-warning {{the address of 'f1' will always evaluate to 'true'}}
+  }
+
+  bool b2 = S::f2; // expected-warning {{the address of 'S::f2' will always evaluate to 'true'}}
+  if (S::f2) { // expected-warning {{the address of 'S::f2' will always evaluate to 'true'}}
+  }
+
+  bool b3 = f3;
+  if (f3) {
+  }
+
+  bool b4 = S2::f4;
+  if (S2::f4) {
+  }
+}
diff --git test/SemaTemplate/resolve-single-template-id.cpp test/SemaTemplate/resolve-single-template-id.cpp
index b9833d8..513b6b3 100644
--- test/SemaTemplate/resolve-single-template-id.cpp
+++ test/SemaTemplate/resolve-single-template-id.cpp
@@ -41,7 +41,7 @@ int main()
   *oneT<int>;   // expected-warning {{expression result unused}}
   *two;  //expected-error {{reference to overloaded function could not be resolved; did you mean to call it with no arguments?}} expected-error {{indirection requires pointer operand}}
   *twoT<int>; //expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}}
-  !oneT<int>;  // expected-warning {{expression result unused}}
+  !oneT<int>;  // expected-warning {{expression result unused}} expected-warning {{the address of 'oneT<int>' will always evaluate to 'true'}}
   +oneT<int>;  // expected-warning {{expression result unused}}
   -oneT<int>;  //expected-error {{invalid argument type}}
   oneT<int> == 0;   // expected-warning {{equality comparison result unused}} \
@@ -53,7 +53,7 @@ int main()
   
   int i = (int) (false ? (void (*)(int))twoT<int> : oneT<int>); //expected-error {{incompatible operand}}
   (twoT<int>) == oneT<int>; //expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}} {{cannot resolve overloaded function 'twoT' from context}}
-  bool b = oneT<int>;
+  bool b = oneT<int>; // expected-warning {{the address of 'oneT<int>' will always evaluate to 'true'}}
   void (*p)() = oneT<int>;
   test<oneT<int> > ti;
   void (*u)(int) = oneT<int>;
