Emit -Waddress warnings for comparing address of reference against NULL
authorPatrick Palka <ppalka@gcc.gnu.org>
Sat, 13 Jun 2015 16:11:15 +0000 (16:11 +0000)
committerPatrick Palka <ppalka@gcc.gnu.org>
Sat, 13 Jun 2015 16:11:15 +0000 (16:11 +0000)
gcc/c-family/ChangeLog:

PR c++/65168
* c-common.c (c_common_truthvalue_conversion): Warn when
converting an address of a reference to a truth value.

gcc/cp/ChangeLog:

PR c++/65168
* typeck.c (cp_build_binary_op): Warn when comparing an address
of a reference against NULL.

gcc/testsuite/ChangeLog:

PR c++/65168
g++.dg/warn/Walways-true-3.C: New test.

From-SVN: r224455

gcc/c-family/ChangeLog
gcc/c-family/c-common.c
gcc/cp/ChangeLog
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/warn/Walways-true-3.C [new file with mode: 0644]

index a2324a49b543517cb8e53e61408ee337ce93d3cd..80c3e48e13dea093a930478ebcef10629f183c86 100644 (file)
@@ -1,3 +1,9 @@
+2015-06-13  Patrick Palka  <ppalka@gcc.gnu.org>
+
+       PR c++/65168
+       * c-common.c (c_common_truthvalue_conversion): Warn when
+       converting an address of a reference to a truth value.
+
 2015-06-08  Andrew MacLeod  <amacleod@redhat.com>
 
        * array-notation-common.c : Adjust include files.
index 5b76567735a8e70d99653bafff92e5fce6ad61de..b1af682cf622f99ff8424a74c3c7f3c855530b0d 100644 (file)
@@ -4973,6 +4973,20 @@ c_common_truthvalue_conversion (location_t location, tree expr)
        tree totype = TREE_TYPE (expr);
        tree fromtype = TREE_TYPE (TREE_OPERAND (expr, 0));
 
+       if (POINTER_TYPE_P (totype)
+           && TREE_CODE (fromtype) == REFERENCE_TYPE)
+         {
+           tree inner = expr;
+           STRIP_NOPS (inner);
+
+           if (DECL_P (inner))
+             warning_at (location,
+                         OPT_Waddress,
+                         "the compiler can assume that the address of "
+                         "%qD will always evaluate to %<true%>",
+                         inner);
+         }
+
        /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
           since that affects how `default_conversion' will behave.  */
        if (TREE_CODE (totype) == REFERENCE_TYPE
index b18a893a2ca831122a04ce6d3f57364119aedef5..c091617f960a60128d43a856ee3bb4b2b2cd5dbf 100644 (file)
@@ -1,3 +1,9 @@
+2015-06-13  Patrick Palka  <ppalka@gcc.gnu.org>
+
+       PR c++/65168
+       * typeck.c (cp_build_binary_op): Warn when comparing an address
+       of a reference against NULL.
+
 2015-06-12  Jason Merrill  <jason@redhat.com>
 
        PR c++/65719
index 5b09b73bafa29120ce697cd22b64159f91005457..7716c2154250179fc5ea628e249f6580d4e5f931 100644 (file)
@@ -4430,6 +4430,23 @@ cp_build_binary_op (location_t location,
                warning (OPT_Waddress, "the address of %qD will never be NULL",
                         TREE_OPERAND (op0, 0));
            }
+
+         if (CONVERT_EXPR_P (op0)
+             && TREE_CODE (TREE_TYPE (TREE_OPERAND (op0, 0)))
+                == REFERENCE_TYPE)
+           {
+             tree inner_op0 = op0;
+             STRIP_NOPS (inner_op0);
+
+             if ((complain & tf_warning)
+                 && c_inhibit_evaluation_warnings == 0
+                 && !TREE_NO_WARNING (op0)
+                 && DECL_P (inner_op0))
+               warning_at (location, OPT_Waddress,
+                           "the compiler can assume that the address of "
+                           "%qD will never be NULL",
+                           inner_op0);
+           }
        }
       else if (((code1 == POINTER_TYPE || TYPE_PTRDATAMEM_P (type1))
                && null_ptr_cst_p (op0))
@@ -4452,6 +4469,23 @@ cp_build_binary_op (location_t location,
                warning (OPT_Waddress, "the address of %qD will never be NULL",
                         TREE_OPERAND (op1, 0));
            }
+
+         if (CONVERT_EXPR_P (op1)
+             && TREE_CODE (TREE_TYPE (TREE_OPERAND (op1, 0)))
+                == REFERENCE_TYPE)
+           {
+             tree inner_op1 = op1;
+             STRIP_NOPS (inner_op1);
+
+             if ((complain & tf_warning)
+                 && c_inhibit_evaluation_warnings == 0
+                 && !TREE_NO_WARNING (op1)
+                 && DECL_P (inner_op1))
+               warning_at (location, OPT_Waddress,
+                           "the compiler can assume that the address of "
+                           "%qD will never be NULL",
+                           inner_op1);
+           }
        }
       else if ((code0 == POINTER_TYPE && code1 == POINTER_TYPE)
               || (TYPE_PTRDATAMEM_P (type0) && TYPE_PTRDATAMEM_P (type1)))
index 35822f36c769d31630740f499275306ccd1a610e..b9b96e7e1b32af547e96ee730a8a29460573ed9b 100644 (file)
@@ -1,3 +1,8 @@
+2015-06-13  Patrick Palka  <ppalka@gcc.gnu.org>
+
+       PR c++/65168
+       g++.dg/warn/Walways-true-3.C: New test.
+
 2015-06-13  Tom de Vries  <tom@codesourcery.com>
 
        * gcc.dg/parloops-exit-first-loop-alt-4.c: New test.
diff --git a/gcc/testsuite/g++.dg/warn/Walways-true-3.C b/gcc/testsuite/g++.dg/warn/Walways-true-3.C
new file mode 100644 (file)
index 0000000..d6e9df4
--- /dev/null
@@ -0,0 +1,46 @@
+// PR c++/65168
+// { dg-options "-Waddress" }
+
+void foo (void);
+
+int d;
+int &c = d;
+
+void
+bar (int &a)
+{
+  int &b = a;
+
+  if ((int *)&a) // { dg-warning "address of" }
+    foo ();
+
+  if (&b) // { dg-warning "address of" }
+    foo ();
+
+  if (!&c) // { dg-warning "address of" }
+    foo ();
+
+  if (!&(int &)(int &)a) // { dg-warning "address of" }
+    foo ();
+
+  if (&a == 0) // { dg-warning "never be NULL" }
+    foo ();
+
+  if (&b != 0) // { dg-warning "never be NULL" }
+    foo ();
+
+  if (0 == &(int &)(int &)c) // { dg-warning "never be NULL" }
+    foo ();
+
+  if (&a != (int *)0) // { dg-warning "never be NULL" }
+    foo ();
+}
+
+bool
+bar_1 (int &a)
+{
+  if (d == 5)
+    return &a; // { dg-warning "address of" }
+  else
+    return !&(int &)(int &)a; // { dg-warning "address of" }
+}