diff mbox

[C++] PR 50956

Message ID 4EB17B12.1020005@oracle.com
State New
Headers show

Commit Message

Paolo Carlini Nov. 2, 2011, 5:17 p.m. UTC
Hi,

this should restore -Wcast-qual to the 3.4.x (!) behavior, more or less. 
The diff seems large but the new code is essentially in the last 5 
lines. When fixing this issue the most subtle existing testcase to get 
right, IMHO, is c-c++-common/Wcast-qual-1.c. Duplicate warnings should 
not be an issue because, in input, the valid_p parameter of 
build_const_cast_1 essentially plays the role of c_cast_p afterwards and 
all the following check_for_casting_away_constness calls are protected 
by !c_cast_p.

Tested x86_64-linux.

Ok for mainline?

Thanks,
Paolo.

/////////////////////////
/cp
2011-11-02  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/50956
	* typeck.c (build_const_cast_1): Fix -Wcast-qual for false
	comp_ptr_ttypes_const.

/testsuite
2011-11-02  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/50956
	* g++.dg/warn/Wcast-qual2.C: New.

Comments

Jason Merrill Nov. 2, 2011, 5:44 p.m. UTC | #1
OK.

Jason
diff mbox

Patch

Index: testsuite/g++.dg/warn/Wcast-qual2.C
===================================================================
--- testsuite/g++.dg/warn/Wcast-qual2.C	(revision 0)
+++ testsuite/g++.dg/warn/Wcast-qual2.C	(revision 0)
@@ -0,0 +1,4 @@ 
+// PR c++/50956
+// { dg-options "-Wcast-qual" }
+
+void* p = (void*)"txt"; // { dg-warning "cast" }
Index: cp/typeck.c
===================================================================
--- cp/typeck.c	(revision 180778)
+++ cp/typeck.c	(working copy)
@@ -6345,34 +6345,41 @@  build_const_cast_1 (tree dst_type, tree expr, tsub
 	return error_mark_node;
     }
 
-  if ((TYPE_PTR_P (src_type) || TYPE_PTRMEM_P (src_type))
-      && comp_ptr_ttypes_const (dst_type, src_type))
+  if (TYPE_PTR_P (src_type) || TYPE_PTRMEM_P (src_type))
     {
-      if (valid_p)
+      if (comp_ptr_ttypes_const (dst_type, src_type))
 	{
-	  *valid_p = true;
-	  /* This cast is actually a C-style cast.  Issue a warning if
-	     the user is making a potentially unsafe cast.  */
-	  check_for_casting_away_constness (src_type, dst_type, CAST_EXPR,
-					    complain);
+	  if (valid_p)
+	    {
+	      *valid_p = true;
+	      /* This cast is actually a C-style cast.  Issue a warning if
+		 the user is making a potentially unsafe cast.  */
+	      check_for_casting_away_constness (src_type, dst_type,
+						CAST_EXPR, complain);
+	    }
+	  if (reference_type)
+	    {
+	      expr = cp_build_addr_expr (expr, complain);
+	      expr = build_nop (reference_type, expr);
+	      return convert_from_reference (expr);
+	    }
+	  else
+	    {
+	      expr = decay_conversion (expr);
+	      /* build_c_cast puts on a NOP_EXPR to make the result not an
+		 lvalue.  Strip such NOP_EXPRs if VALUE is being used in
+		 non-lvalue context.  */
+	      if (TREE_CODE (expr) == NOP_EXPR
+		  && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
+		expr = TREE_OPERAND (expr, 0);
+	      return build_nop (dst_type, expr);
+	    }
 	}
-      if (reference_type)
-	{
-	  expr = cp_build_addr_expr (expr, complain);
-	  expr = build_nop (reference_type, expr);
-	  return convert_from_reference (expr);
-	}
-      else
-	{
-	  expr = decay_conversion (expr);
-	  /* build_c_cast puts on a NOP_EXPR to make the result not an
-	     lvalue.  Strip such NOP_EXPRs if VALUE is being used in
-	     non-lvalue context.  */
-	  if (TREE_CODE (expr) == NOP_EXPR
-	      && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
-	    expr = TREE_OPERAND (expr, 0);
-	  return build_nop (dst_type, expr);
-	}
+      else if (valid_p
+	       && !at_least_as_qualified_p (TREE_TYPE (dst_type),
+					    TREE_TYPE (src_type)))
+	check_for_casting_away_constness (src_type, dst_type, CAST_EXPR,
+					  complain);
     }
 
   if (complain & tf_error)