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)