This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH: PR 19457 a PR 19349


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 "" }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]