diff mbox

[C++,Patch/RFC] PR 64877

Message ID 54D0A6D5.9090406@oracle.com
State New
Headers show

Commit Message

Paolo Carlini Feb. 3, 2015, 10:45 a.m. UTC
Hi,

Manuel did most of the work on this [5 Regression], caused by my fix for 
c++/43906, which extended a lot the functionality of -Waddress: a 
spurious warning is emitted with -Waddress for an expression internally 
generated in cp_build_binary_op. Manuel suggested that when safe we 
could completely avoid generating the relevant recursive calls to 
cp_build_binary_op. Alternately, for these internally generated 
expressions we could probably use tf_none instead of passing down 
complain. Note: I'm not 100% sure the ptrmemfunc_vbit_in_delta bits are 
correct, for sure avoid the spurious warning for those targets too.

Thanks,
Paolo.

///////////////////////////

Comments

Jason Merrill Feb. 3, 2015, 2:19 p.m. UTC | #1
On 02/03/2015 05:45 AM, Paolo Carlini wrote:
> +	      if (TREE_CODE (pfn0) != ADDR_EXPR
> +		  || !decl_with_nonnull_addr_p (TREE_OPERAND (pfn0, 0)))

I don't like duplicating the logic for when we might know the pfn is 
non-null; that seems fragile.  I'd rather go with the tf_none approach, 
or otherwise suppress the warning.

Jason
diff mbox

Patch

Index: cp/typeck.c
===================================================================
--- cp/typeck.c	(revision 220366)
+++ cp/typeck.c	(working copy)
@@ -4552,35 +4552,44 @@  cp_build_binary_op (location_t location,
 
 	         The reason for the `!op0.pfn' bit is that a NULL
 	         pointer-to-member is any member with a zero PFN and
-	         LSB of the DELTA field is 0.  */
+	         LSB of the DELTA field is 0.  Note: avoid generating the
+		 '|| (!op0.pfn && ...)' if !op0.pfn is known to be false.  */
 
-	      e1 = cp_build_binary_op (location, BIT_AND_EXPR,
-				       delta0, 
-				       integer_one_node,
-				       complain);
-	      e1 = cp_build_binary_op (location,
-				       EQ_EXPR, e1, integer_zero_node,
-				       complain);
-	      e2 = cp_build_binary_op (location, BIT_AND_EXPR,
-				       delta1,
-				       integer_one_node,
-				       complain);
-	      e2 = cp_build_binary_op (location,
-				       EQ_EXPR, e2, integer_zero_node,
-				       complain);
-	      e1 = cp_build_binary_op (location,
-				       TRUTH_ANDIF_EXPR, e2, e1,
-				       complain);
-	      e2 = cp_build_binary_op (location, EQ_EXPR,
-				       pfn0,
-				       build_zero_cst (TREE_TYPE (pfn0)),
-				       complain);
-	      e2 = cp_build_binary_op (location,
-				       TRUTH_ANDIF_EXPR, e2, e1, complain);
-	      e1 = cp_build_binary_op (location,
-				       EQ_EXPR, delta0, delta1, complain);
-	      e1 = cp_build_binary_op (location,
-				       TRUTH_ORIF_EXPR, e1, e2, complain);
+	      if (TREE_CODE (pfn0) != ADDR_EXPR
+		  || !decl_with_nonnull_addr_p (TREE_OPERAND (pfn0, 0)))
+		{
+		  e1 = cp_build_binary_op (location, BIT_AND_EXPR,
+					   delta0, 
+					   integer_one_node,
+					   complain);
+		  e1 = cp_build_binary_op (location,
+					   EQ_EXPR, e1, integer_zero_node,
+					   complain);
+		  e2 = cp_build_binary_op (location, BIT_AND_EXPR,
+					   delta1,
+					   integer_one_node,
+					   complain);
+		  e2 = cp_build_binary_op (location,
+					   EQ_EXPR, e2, integer_zero_node,
+					   complain);
+		  e1 = cp_build_binary_op (location,
+					   TRUTH_ANDIF_EXPR, e2, e1,
+					   complain);
+		  e2 = cp_build_binary_op (location, EQ_EXPR,
+					   pfn0,
+					   build_zero_cst (TREE_TYPE (pfn0)),
+					   complain);
+		  e2 = cp_build_binary_op (location,
+					   TRUTH_ANDIF_EXPR, e2, e1, complain);
+		  e1 = cp_build_binary_op (location,
+					   EQ_EXPR, delta0, delta1, complain);
+		  e1 = cp_build_binary_op (location,
+					   TRUTH_ORIF_EXPR, e1, e2, complain);
+
+		}
+	      else
+		e1 = cp_build_binary_op (location,
+					 EQ_EXPR, delta0, delta1, complain);
 	    }
 	  else
 	    {
@@ -4591,17 +4600,22 @@  cp_build_binary_op (location_t location,
 
 	         The reason for the `!op0.pfn' bit is that a NULL
 	         pointer-to-member is any member with a zero PFN; the
-	         DELTA field is unspecified.  */
+	         DELTA field is unspecified.  Note: avoid generating the
+		 '!op0.pfn ||' if !op0.pfn is known to be false.  */
  
     	      e1 = cp_build_binary_op (location,
 				       EQ_EXPR, delta0, delta1, complain);
-	      e2 = cp_build_binary_op (location,
-				       EQ_EXPR,
-		      		       pfn0,
-			   	       build_zero_cst (TREE_TYPE (pfn0)),
-				       complain);
-	      e1 = cp_build_binary_op (location,
-				       TRUTH_ORIF_EXPR, e1, e2, complain);
+	      if (TREE_CODE (pfn0) != ADDR_EXPR
+		  || !decl_with_nonnull_addr_p (TREE_OPERAND (pfn0, 0)))
+		{
+		  e2 = cp_build_binary_op (location,
+					   EQ_EXPR,
+					   pfn0,
+					   build_zero_cst (TREE_TYPE (pfn0)),
+					   complain);
+		  e1 = cp_build_binary_op (location,
+					   TRUTH_ORIF_EXPR, e1, e2, complain);
+		}
 	    }
 	  e2 = build2 (EQ_EXPR, boolean_type_node, pfn0, pfn1);
 	  e = cp_build_binary_op (location,
Index: testsuite/g++.dg/warn/Waddress-2.C
===================================================================
--- testsuite/g++.dg/warn/Waddress-2.C	(revision 0)
+++ testsuite/g++.dg/warn/Waddress-2.C	(working copy)
@@ -0,0 +1,24 @@ 
+// PR c++/64877
+// { dg-options "-Waddress" }
+
+template<class Derived>
+struct S
+{
+  void m() {
+  }
+
+  S()
+  {
+    if (&S<Derived>::Unwrap != &Derived::Unwrap)
+      m();
+  }
+
+  void Unwrap() {
+  }
+};
+
+struct T : public S<T>
+{
+};
+
+T t;