This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: PR 19457 a PR 19349
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 30 Jan 2005 17:22:11 -0800
- Subject: C++ PATCH: PR 19457 a PR 19349
- Reply-to: mark at codesourcery dot com
This patch fixes:
* PR 19457, a PR in which we issued bogus warnings. After Nathan's
INTEGER_CST-sharing patch, it's often invalid for front-ends to set
flags on INTEGER_CSTs without first copying them. In this case, the
C++ front end was setting TREE_NEGATED_INT, and that caused us to
issue bogus warnings later. The longer-term fix for this particular
problem is actually to remove TREE_NEGATED_INT from the INTEGER_CST
altogether; this kind of non-semantic information should be encoded
in a temporary data structure, discarded after semantic analysis.
But, for now, we'll just copy the constant...
* PR 19349, a case in which we accessed gcc_free'd memory. I
introduced this bug after I modified duplicate_decls to discard the
new copy of a duplicate _DECL.
Both of these problems show that there is clearly risk associated with
certain compile-time performance patches...
Tested on x86_64-unknown-linux-gnu, applied on the mainline.
--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com
2005-01-30 Mark Mitchell <mark@codesourcery.com>
PR c++/19457
* call.c (convert_like_real): Inline call to
dubious_conversion_warnings here.
* cp-tree.h (dubious_conversion_warnings): Remove.
* semantics.c (finish_unary_op_expr): Copy INTEGER_CSTs before
setting TREE_NEGATED_INT.
* typeck.c (dubious_conversion_warnings): Remove.
PR c++/19349
* name-lookup.c (pushdecl_namespace_level): Avoid accessing free'd
memory.
2005-01-30 Mark Mitchell <mark@codesourcery.com>
PR c++/19457
* g++.dg/warn/conv3.C: New test.
Index: cp/call.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.527
diff -c -5 -p -r1.527 call.c
*** cp/call.c 18 Jan 2005 11:45:32 -0000 1.527
--- cp/call.c 31 Jan 2005 01:14:32 -0000
*************** convert_like_real (conversion *convs, tr
*** 4164,4175 ****
pedwarn (" initializing argument %P of %qD", argnum, fn);
return cp_convert (totype, expr);
}
if (issue_conversion_warnings)
! expr = dubious_conversion_warnings
! (totype, expr, "converting", fn, argnum);
switch (convs->kind)
{
case ck_user:
{
struct z_candidate *cand = convs->cand;
--- 4164,4213 ----
pedwarn (" initializing argument %P of %qD", argnum, fn);
return cp_convert (totype, expr);
}
if (issue_conversion_warnings)
! {
! tree t = non_reference (totype);
!
! /* Issue warnings about peculiar, but valid, uses of NULL. */
! if (ARITHMETIC_TYPE_P (t) && expr == null_node)
! {
! if (fn)
! warning ("passing NULL to non-pointer argument %P of %qD",
! argnum, fn);
! else
! warning ("converting to non-pointer type %qT from NULL", t);
! }
!
! /* Warn about assigning a floating-point type to an integer type. */
! if (TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE
! && TREE_CODE (t) == INTEGER_TYPE)
! {
! if (fn)
! warning ("passing %qT for argument %P to %qD",
! TREE_TYPE (expr), argnum, fn);
! else
! warning ("converting to %qT from %qT", t, TREE_TYPE (expr));
! }
! /* And warn about assigning a negative value to an unsigned
! variable. */
! else if (TYPE_UNSIGNED (t) && TREE_CODE (t) != BOOLEAN_TYPE)
! {
! if (TREE_CODE (expr) == INTEGER_CST && TREE_NEGATED_INT (expr))
! {
! if (fn)
! warning ("passing negative value %qE for argument %P to %qD",
! expr, argnum, fn);
! else
! warning ("converting negative value %qE to %qT", expr, t);
! }
!
! overflow_warning (expr);
! }
! }
!
switch (convs->kind)
{
case ck_user:
{
struct z_candidate *cand = convs->cand;
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.1097
diff -c -5 -p -r1.1097 cp-tree.h
*** cp/cp-tree.h 20 Jan 2005 07:12:49 -0000 1.1097
--- cp/cp-tree.h 31 Jan 2005 01:14:32 -0000
*************** extern tree build_static_cast (tree, t
*** 4296,4306 ****
extern tree build_reinterpret_cast (tree, tree);
extern tree build_const_cast (tree, tree);
extern tree build_c_cast (tree, tree);
extern tree build_x_modify_expr (tree, enum tree_code, tree);
extern tree build_modify_expr (tree, enum tree_code, tree);
- extern tree dubious_conversion_warnings (tree, tree, const char *, tree, int);
extern tree convert_for_initialization (tree, tree, tree, int, const char *, tree, int);
extern int comp_ptr_ttypes (tree, tree);
extern int ptr_reasonably_similar (tree, tree);
extern tree build_ptrmemfunc (tree, tree, int, bool);
extern int cp_type_quals (tree);
--- 4296,4305 ----
Index: cp/semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.458
diff -c -5 -p -r1.458 semantics.c
*** cp/semantics.c 27 Jan 2005 07:32:25 -0000 1.458
--- cp/semantics.c 31 Jan 2005 01:14:32 -0000
*************** finish_unary_op_expr (enum tree_code cod
*** 1957,1967 ****
setting TREE_NEGATED_INT. */
if (code == NEGATE_EXPR && TREE_CODE (expr) == INTEGER_CST
&& TREE_CODE (result) == INTEGER_CST
&& !TYPE_UNSIGNED (TREE_TYPE (result))
&& INT_CST_LT (result, integer_zero_node))
! TREE_NEGATED_INT (result) = 1;
overflow_warning (result);
return result;
}
/* Finish a compound-literal expression. TYPE is the type to which
--- 1957,1972 ----
setting TREE_NEGATED_INT. */
if (code == NEGATE_EXPR && TREE_CODE (expr) == INTEGER_CST
&& TREE_CODE (result) == INTEGER_CST
&& !TYPE_UNSIGNED (TREE_TYPE (result))
&& INT_CST_LT (result, integer_zero_node))
! {
! /* RESULT may be a cached INTEGER_CST, so we must copy it before
! setting TREE_NEGATED_INT. */
! result = copy_node (result);
! TREE_NEGATED_INT (result) = 1;
! }
overflow_warning (result);
return result;
}
/* Finish a compound-literal expression. TYPE is the type to which
Index: cp/typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck.c,v
retrieving revision 1.609
diff -c -5 -p -r1.609 typeck.c
*** cp/typeck.c 23 Jan 2005 15:22:18 -0000 1.609
--- cp/typeck.c 31 Jan 2005 01:14:32 -0000
*************** pfn_from_ptrmemfunc (tree t)
*** 5811,5871 ****
}
return build_ptrmemfunc_access_expr (t, pfn_identifier);
}
- /* Expression EXPR is about to be implicitly converted to TYPE. Warn
- if this is a potentially dangerous thing to do. Returns a possibly
- marked EXPR. */
-
- tree
- dubious_conversion_warnings (tree type, tree expr,
- const char *errtype, tree fndecl, int parmnum)
- {
- type = non_reference (type);
-
- /* Issue warnings about peculiar, but valid, uses of NULL. */
- if (ARITHMETIC_TYPE_P (type) && expr == null_node)
- {
- if (fndecl)
- warning ("passing NULL used for non-pointer %s %P of %qD",
- errtype, parmnum, fndecl);
- else
- warning ("%s to non-pointer type %qT from NULL", errtype, type);
- }
-
- /* Warn about assigning a floating-point type to an integer type. */
- if (TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE
- && TREE_CODE (type) == INTEGER_TYPE)
- {
- if (fndecl)
- warning ("passing %qT for %s %P of %qD",
- TREE_TYPE (expr), errtype, parmnum, fndecl);
- else
- warning ("%s to %qT from %qT", errtype, type, TREE_TYPE (expr));
- }
- /* And warn about assigning a negative value to an unsigned
- variable. */
- else if (TYPE_UNSIGNED (type) && TREE_CODE (type) != BOOLEAN_TYPE)
- {
- if (TREE_CODE (expr) == INTEGER_CST && TREE_NEGATED_INT (expr))
- {
- if (fndecl)
- warning ("passing negative value %qE for %s %P of %qD",
- expr, errtype, parmnum, fndecl);
- else
- warning ("%s of negative value %qE to %qT", errtype, expr, type);
- }
-
- overflow_warning (expr);
-
- if (TREE_CONSTANT (expr))
- expr = fold_if_not_in_template (expr);
- }
- return expr;
- }
-
/* Convert value RHS to type TYPE as preparation for an assignment to
an lvalue of type TYPE. ERRTYPE is a string to use in error
messages: "assignment", "return", etc. If FNDECL is non-NULL, we
are doing the conversion in order to pass the PARMNUMth argument of
FNDECL. */
--- 5811,5820 ----
Index: cp/name-lookup.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/name-lookup.c,v
retrieving revision 1.106
diff -c -5 -p -r1.106 name-lookup.c
*** cp/name-lookup.c 25 Jan 2005 08:55:00 -0000 1.106
--- cp/name-lookup.c 31 Jan 2005 01:14:33 -0000
*************** pushdecl_namespace_level (tree x)
*** 3022,3034 ****
timevar_push (TV_NAME_LOOKUP);
t = pushdecl_with_scope (x, NAMESPACE_LEVEL (current_namespace));
/* Now, the type_shadowed stack may screw us. Munge it so it does
what we want. */
! if (TREE_CODE (x) == TYPE_DECL)
{
! tree name = DECL_NAME (x);
tree newval;
tree *ptr = (tree *)0;
for (; !global_scope_p (b); b = b->level_chain)
{
tree shadowed = b->type_shadowed;
--- 3022,3034 ----
timevar_push (TV_NAME_LOOKUP);
t = pushdecl_with_scope (x, NAMESPACE_LEVEL (current_namespace));
/* Now, the type_shadowed stack may screw us. Munge it so it does
what we want. */
! if (TREE_CODE (t) == TYPE_DECL)
{
! tree name = DECL_NAME (t);
tree newval;
tree *ptr = (tree *)0;
for (; !global_scope_p (b); b = b->level_chain)
{
tree shadowed = b->type_shadowed;
*************** pushdecl_namespace_level (tree x)
*** 3039,3054 ****
/* Can't break out of the loop here because sometimes
a binding level will have duplicate bindings for
PT names. It's gross, but I haven't time to fix it. */
}
}
! newval = TREE_TYPE (x);
if (ptr == (tree *)0)
{
/* @@ This shouldn't be needed. My test case "zstring.cc" trips
up here if this is changed to an assertion. --KR */
! SET_IDENTIFIER_TYPE_VALUE (name, x);
}
else
{
*ptr = newval;
}
--- 3039,3054 ----
/* Can't break out of the loop here because sometimes
a binding level will have duplicate bindings for
PT names. It's gross, but I haven't time to fix it. */
}
}
! newval = TREE_TYPE (t);
if (ptr == (tree *)0)
{
/* @@ This shouldn't be needed. My test case "zstring.cc" trips
up here if this is changed to an assertion. --KR */
! SET_IDENTIFIER_TYPE_VALUE (name, t);
}
else
{
*ptr = newval;
}
Index: testsuite/g++.dg/warn/conv3.C
===================================================================
RCS file: testsuite/g++.dg/warn/conv3.C
diff -N testsuite/g++.dg/warn/conv3.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/warn/conv3.C 31 Jan 2005 01:14:33 -0000
***************
*** 0 ****
--- 1,4 ----
+ // PR c++/19457
+
+ int i=-1;
+ unsigned int j= ~0; // { dg-bogus "" }