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.carl...@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.carl...@oracle.com>

        PR c++/50956
        * g++.dg/warn/Wcast-qual2.C: New.
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)

Reply via email to