diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e5f963d4b99eaa0b6635bb87c50dac0d8607b63f..26b5d22546839e4b334d743c7a4a42d8f08d576b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2010-04-27  Shujing Zhao  <pearly.zhao@oracle.com>
+	
+	PR c/32207
+	* c-typeck.c (build_binary_op): Move forward check for comparison
+	pointer with null pointer constant and adjust the diagnostic message.
+
 2010-04-27  Dave Korn  <dave.korn.cygwin@gmail.com>
 
 	PR lto/42776
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index df02975f9dc7f3d6a90195d0aba7ee7c3238cabf..96b2ab156ad0782b6028e4021ac866d099dc4a6a 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -9503,6 +9503,46 @@ build_binary_op (location_t location, enum tree_code code,
 	  && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
 	      || code1 == FIXED_POINT_TYPE || code1 == COMPLEX_TYPE))
 	short_compare = 1;
+      else if (code0 == POINTER_TYPE && null_pointer_constant_p (orig_op1))
+	{
+	  if (TREE_CODE (op0) == ADDR_EXPR
+	      && decl_with_nonnull_addr_p (TREE_OPERAND (op0, 0)))
+	    {
+	      if (code == EQ_EXPR)
+		warning_at (location,
+			    OPT_Waddress,
+			    "the comparison will always evaluate as %<false%> "
+			    "for the address of %qD will never be NULL",
+			    TREE_OPERAND (op0, 0));
+	      else
+		warning_at (location,
+			    OPT_Waddress,
+			    "the comparison will always evaluate as %<true%> "
+			    "for the address of %qD will never be NULL",
+			    TREE_OPERAND (op0, 0));
+	    }
+	  result_type = type0;
+	}
+      else if (code1 == POINTER_TYPE && null_pointer_constant_p (orig_op0))
+	{
+	  if (TREE_CODE (op1) == ADDR_EXPR
+	      && decl_with_nonnull_addr_p (TREE_OPERAND (op1, 0)))
+	    {
+	      if (code == EQ_EXPR)
+		warning_at (location,
+			    OPT_Waddress, 
+			    "the comparison will always evaluate as %<false%> "
+			    "for the address of %qD will never be NULL",
+			    TREE_OPERAND (op1, 0));
+	      else
+		warning_at (location,
+			    OPT_Waddress,
+			    "the comparison will always evaluate as %<true%> "
+			    "for the address of %qD will never be NULL",
+			    TREE_OPERAND (op1, 0));
+	    }
+	  result_type = type1;
+	}
       else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
 	{
 	  tree tt0 = TREE_TYPE (type0);
@@ -9516,10 +9556,6 @@ build_binary_op (location_t location, enum tree_code code,
 	     and both must be object or both incomplete.  */
 	  if (comp_target_types (location, type0, type1))
 	    result_type = common_pointer_type (type0, type1);
-	  else if (null_pointer_constant_p (orig_op0))
-	    result_type = type1;
-	  else if (null_pointer_constant_p (orig_op1))
-	    result_type = type0;
 	  else if (!addr_space_superset (as0, as1, &as_common))
 	    {
 	      error_at (location, "comparison of pointers to "
@@ -9551,24 +9587,6 @@ build_binary_op (location_t location, enum tree_code code,
 			      (build_qualified_type (void_type_node, qual));
 	    }
 	}
-      else if (code0 == POINTER_TYPE && null_pointer_constant_p (orig_op1))
-	{
-	  if (TREE_CODE (op0) == ADDR_EXPR
-	      && decl_with_nonnull_addr_p (TREE_OPERAND (op0, 0)))
-	    warning_at (location,
-			OPT_Waddress, "the address of %qD will never be NULL",
-			TREE_OPERAND (op0, 0));
-	  result_type = type0;
-	}
-      else if (code1 == POINTER_TYPE && null_pointer_constant_p (orig_op0))
-	{
-	  if (TREE_CODE (op1) == ADDR_EXPR
-	      && decl_with_nonnull_addr_p (TREE_OPERAND (op1, 0)))
-	    warning_at (location,
-			OPT_Waddress, "the address of %qD will never be NULL",
-			TREE_OPERAND (op1, 0));
-	  result_type = type1;
-	}
       else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
 	{
 	  result_type = type0;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index a025895843b4604ab8843d9e983724df0b52bde0..e94e8e70762aefc6bf3ecdcba603061b5f9dfde2 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,12 @@
+2010-04-27  Shujing Zhao  <pearly.zhao@oracle.com>
+
+	PR c/32207
+	* gcc.dg/pr32207.c: New test.
+	* gcc.dg/misc-column.c: Adjust expected warning.
+	* gcc.dg/Walways-true-1.c: Likewise.
+	* gcc.dg/Walways-true-2.c: Likewise.
+	* gcc.dg/warn-addr-cmp.c: Likewise.
+
 2010-04-27  Dave Korn  <dave.korn.cygwin@gmail.com>
 
 	PR lto/42776
diff --git a/gcc/testsuite/gcc.dg/Walways-true-1.c b/gcc/testsuite/gcc.dg/Walways-true-1.c
index 32b921c3fa7330ada7e046966d209bd953de4954..274ec32b38b706e562019efd47bee924dc732e97 100644
--- a/gcc/testsuite/gcc.dg/Walways-true-1.c
+++ b/gcc/testsuite/gcc.dg/Walways-true-1.c
@@ -26,32 +26,32 @@ bar (int a)
     foo (5);
   if (&&lab)	/* { dg-warning "7:always evaluate as" "correct warning" } */
     foo (6);
-  if (foo == 0)	/* { dg-warning "11:never be NULL" "correct warning" } */
+  if (foo == 0)	/* { dg-warning "11:the comparison will always evaluate to 'false'" "correct warning" } */
     foo (7);
   if (foo (1) == 0)
     foo (8);
-  if (&i == 0)	/* { dg-warning "10:never be NULL" "correct warning" } */
+  if (&i == 0)	/* { dg-warning "10:the comparison will always evaluate to 'false'" "correct warning" } */
     foo (9);
   if (i == 0)
     foo (10);
-  if (&a == 0)	/* { dg-warning "10:never be NULL" "correct warning" } */
+  if (&a == 0)	/* { dg-warning "10:the comparison will always evaluate to 'false'" "correct warning" } */
     foo (11);
   if (a == 0)
     foo (12);
-  if (&&lab == 0) /* { dg-warning "13:never be NULL" "correct warning" } */
+  if (&&lab == 0) /* { dg-warning "13:the comparison will always evaluate to 'false'" "correct warning" } */
     foo (13);
-  if (0 == foo)	/* { dg-warning "9:never be NULL" "correct warning" } */
+  if (0 == foo)	/* { dg-warning "9:the comparison will always evaluate to 'false'" "correct warning" } */
     foo (14);
   if (0 == foo (1))
     foo (15);
-  if (0 == &i)	/* { dg-warning "9:never be NULL" "correct warning" } */
+  if (0 == &i)	/* { dg-warning "9:the comparison will always evaluate to 'false'" "correct warning" } */
     foo (16);
   if (0 == i)
     foo (17);
-  if (0 == &a)	/* { dg-warning "9:never be NULL" "correct warning" } */
+  if (0 == &a)	/* { dg-warning "9:the comparison will always evaluate to 'false'" "correct warning" } */
     foo (18);
   if (0 == a)
     foo (19);
-  if (0 == &&lab) /* { dg-warning "9:never be NULL" "correct warning" } */
+  if (0 == &&lab) /* { dg-warning "9:the comparison will always evaluate to 'false'" "correct warning" } */
     foo (20);
 }
diff --git a/gcc/testsuite/gcc.dg/Walways-true-2.c b/gcc/testsuite/gcc.dg/Walways-true-2.c
index c14857eaee618b4a754d3c64847d26513e6da72f..3978a446188d8e4d3f149188a61b490470c1ecd0 100644
--- a/gcc/testsuite/gcc.dg/Walways-true-2.c
+++ b/gcc/testsuite/gcc.dg/Walways-true-2.c
@@ -37,11 +37,11 @@ bar (int a)
     foo (9);
   if (i == 0)
     foo (10);
-  if (&a == 0)	/* { dg-warning "never be NULL" "correct warning" } */
+  if (&a == 0)	/* { dg-warning "the comparison will always evaluate to 'false'" "correct warning" } */
     foo (11);
   if (a == 0)
     foo (12);
-  if (&&lab == 0) /* { dg-warning "never be NULL" "correct warning" } */
+  if (&&lab == 0) /* { dg-warning "the comparison will always evaluate to 'false'" "correct warning" } */
     foo (13);
   if (0 == foo)
     foo (14);
@@ -51,10 +51,10 @@ bar (int a)
     foo (16);
   if (0 == i)
     foo (17);
-  if (0 == &a)	/* { dg-warning "never be NULL" "correct warning" } */
+  if (0 == &a)	/* { dg-warning "the comparison will always evaluate to 'false'" "correct warning" } */
     foo (18);
   if (0 == a)
     foo (19);
-  if (0 == &&lab) /* { dg-warning "never be NULL" "correct warning" } */
+  if (0 == &&lab) /* { dg-warning "the comparison will always evaluate to 'false'" "correct warning" } */
     foo (20);
 }
diff --git a/gcc/testsuite/gcc.dg/misc-column.c b/gcc/testsuite/gcc.dg/misc-column.c
index a24427e4baa4689800ca134f7fa71f31b6da3c1b..f69f98884d9e87ddef29261a8560e49accad0988 100644
--- a/gcc/testsuite/gcc.dg/misc-column.c
+++ b/gcc/testsuite/gcc.dg/misc-column.c
@@ -19,7 +19,7 @@ void foo (void)
   if (p < q) /* { dg-warning "9:comparison of distinct pointer types" } */
     bar ();
 
-  if (&p == 0) /* { dg-warning "10:will never be NULL" } */
+  if (&p == 0) /* { dg-warning "10:comparison will always evaluate to 'false'" } */
     bar();
 
   if (p == 4) /* { dg-warning "9:comparison between pointer and integer" } */
diff --git a/gcc/testsuite/gcc.dg/pr32207.c b/gcc/testsuite/gcc.dg/pr32207.c
new file mode 100644
index 0000000000000000000000000000000000000000..549d51a9e9d1296781dfbe1eaba2c177f44aa1b6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr32207.c
@@ -0,0 +1,9 @@
+/* Test warning for comparison non-null address with null pointer constant. */
+/* Origin: Pawel Sikora <pluto@agmk.net> */
+/* { dg-do compile } */
+/* { dg-options "-Waddress" } */
+extern void z();
+
+void f() { if ( z ) z(); } /* { dg-warning "always evaluate as" } */
+void g() { if ( z != 0 ) z(); } /* { dg-warning "the comparison will always evaluate to 'true'" } */
+void h() { if ( z != (void*)0 ) z(); } /* { dg-warning "the comparison will always evaluate to 'true'" } */
diff --git a/gcc/testsuite/gcc.dg/warn-addr-cmp.c b/gcc/testsuite/gcc.dg/warn-addr-cmp.c
index 6ad94731affba8a7f6fb67dbe4e3076bf2b351ea..c1e68f5c5987f2a4f86e08e789906f5c2f9e0ea3 100644
--- a/gcc/testsuite/gcc.dg/warn-addr-cmp.c
+++ b/gcc/testsuite/gcc.dg/warn-addr-cmp.c
@@ -36,13 +36,13 @@ test_func_cmp (void)
 int
 test_func_cmp_rhs_zero (void)
 {
-  if (func == 0)     /* { dg-warning "the address of 'func'" } */
+  if (func == 0)     /* { dg-warning "the comparison will always evaluate to 'false'" } */
     return 1;
-  if (func != 0)     /* { dg-warning "the address of 'func'" } */
+  if (func != 0)     /* { dg-warning "the comparison will always evaluate to 'true'" } */
     return 1;
-  if (&var == 0)     /* { dg-warning "the address of 'var'" } */
+  if (&var == 0)     /* { dg-warning "the comparison will always evaluate to 'false'" } */
     return 1;
-  if (&var != 0)     /* { dg-warning "the address of 'var'" } */
+  if (&var != 0)     /* { dg-warning "the comparison will always evaluate to 'true'" } */
     return 1;
   if (weak_func == 0)
     return 1;
@@ -59,13 +59,13 @@ test_func_cmp_rhs_zero (void)
 int
 test_func_cmp_lhs_zero (void)
 {
-  if (0 == func)     /* { dg-warning "the address of 'func'" } */
+  if (0 == func)     /* { dg-warning "the comparison will always evaluate to 'false'" } */
     return 1;
-  if (0 != func)     /* { dg-warning "the address of 'func'" } */
+  if (0 != func)     /* { dg-warning "the comparison will always evaluate to 'true'" } */
     return 1;
-  if (0 == &var)     /* { dg-warning "the address of 'var'" } */
+  if (0 == &var)     /* { dg-warning "the comparison will always evaluate to 'false'" } */
     return 1;
-  if (0 != &var)     /* { dg-warning "the address of 'var'" } */
+  if (0 != &var)     /* { dg-warning "the comparison will always evaluate to 'true'" } */
     return 1;
   if (0 == weak_func)
     return 1;