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: Fix 14122 and 14108


PR 14122 was a problem with non-type arguments whose origin was this
piece of code:

- 	  /* ??? This is not really quite correct
- 	     in that the type of the operand of ADDR_EXPR
- 	     is not the target type of the type of the ADDR_EXPR itself.
- 	     Question is, can this lossage be avoided?  */
- 	  adr = build1 (ADDR_EXPR, ptrtype, exp);

to which the answer is "yes, this lossage can be avoided; that's what
we have NOP_EXPR for."

PR 14108 was a problem with thunks, in the case that the back end does
not have the magic for doing a jump at the assembly level.

Tested on i686-pc-linux-gnu, applied on the mainline and on the
branch.

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

2004-02-13  Mark Mitchell  <mark@codesourcery.com>

	PR c++/14122
	* cp-tree.h (delete_sanity): Change prototype.
	* decl2.c (delete_sanity): Make doing_vec a bool, not an int.
	Remove dead code.  Adjust code to warn about deleting an array.
	* typekc.c (decay_conversion): Use build_address and build_nop.

	PR c++/14108
	* search.c (accessible_p): Do not check access in thunks.

2004-02-13  Mark Mitchell  <mark@codesourcery.com>

	PR c++/14122
	* g++.dg/template/array4.C: New test.
	
	PR c++/14108
	* g++.dg/inherit/thunk2.C: New test.

Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.952
diff -c -5 -p -r1.952 cp-tree.h
*** cp/cp-tree.h	13 Feb 2004 07:19:16 -0000	1.952
--- cp/cp-tree.h	14 Feb 2004 00:46:03 -0000
*************** extern int grok_method_quals (tree, tree
*** 3707,3717 ****
  extern void grok_x_components (tree);
  extern void maybe_retrofit_in_chrg (tree);
  extern void maybe_make_one_only	(tree);
  extern void grokclassfn	(tree, tree, enum overload_flags, tree);
  extern tree grok_array_decl (tree, tree);
! extern tree delete_sanity (tree, tree, int, int);
  extern tree check_classfn (tree, tree, bool);
  extern void check_member_template (tree);
  extern tree grokfield (tree, tree, tree, tree, tree);
  extern tree grokbitfield (tree, tree, tree);
  extern tree groktypefield			(tree, tree);
--- 3707,3717 ----
  extern void grok_x_components (tree);
  extern void maybe_retrofit_in_chrg (tree);
  extern void maybe_make_one_only	(tree);
  extern void grokclassfn	(tree, tree, enum overload_flags, tree);
  extern tree grok_array_decl (tree, tree);
! extern tree delete_sanity (tree, tree, bool, int);
  extern tree check_classfn (tree, tree, bool);
  extern void check_member_template (tree);
  extern tree grokfield (tree, tree, tree, tree, tree);
  extern tree grokbitfield (tree, tree, tree);
  extern tree groktypefield			(tree, tree);
Index: cp/decl2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl2.c,v
retrieving revision 1.698
diff -c -5 -p -r1.698 decl2.c
*** cp/decl2.c	13 Feb 2004 07:19:17 -0000	1.698
--- cp/decl2.c	14 Feb 2004 00:46:03 -0000
*************** grok_array_decl (tree array_expr, tree i
*** 430,451 ****
  }
  
  /* Given the cast expression EXP, checking out its validity.   Either return
     an error_mark_node if there was an unavoidable error, return a cast to
     void for trying to delete a pointer w/ the value 0, or return the
!    call to delete.  If DOING_VEC is 1, we handle things differently
!    for doing an array delete.  If DOING_VEC is 2, they gave us the
!    array size as an argument to delete.
     Implements ARM $5.3.4.  This is called from the parser.  */
  
  tree
! delete_sanity (tree exp, tree size, int doing_vec, int use_global_delete)
  {
    tree t, type;
-   /* For a regular vector delete (aka, no size argument) we will pass
-      this down as a NULL_TREE into build_vec_delete.  */
-   tree maxindex = NULL_TREE;
  
    if (exp == error_mark_node)
      return exp;
  
    if (processing_template_decl)
--- 430,447 ----
  }
  
  /* Given the cast expression EXP, checking out its validity.   Either return
     an error_mark_node if there was an unavoidable error, return a cast to
     void for trying to delete a pointer w/ the value 0, or return the
!    call to delete.  If DOING_VEC is true, we handle things differently
!    for doing an array delete.
     Implements ARM $5.3.4.  This is called from the parser.  */
  
  tree
! delete_sanity (tree exp, tree size, bool doing_vec, int use_global_delete)
  {
    tree t, type;
  
    if (exp == error_mark_node)
      return exp;
  
    if (processing_template_decl)
*************** delete_sanity (tree exp, tree size, int 
*** 455,479 ****
        DELETE_EXPR_USE_VEC (t) = doing_vec;
        return t;
      }
  
    exp = convert_from_reference (exp);
    t = build_expr_type_conversion (WANT_POINTER, exp, true);
  
    if (t == NULL_TREE || t == error_mark_node)
      {
        error ("type `%#T' argument given to `delete', expected pointer",
  		TREE_TYPE (exp));
        return error_mark_node;
      }
  
-   if (doing_vec == 2)
-     {
-       maxindex = cp_build_binary_op (MINUS_EXPR, size, integer_one_node);
-       pedwarn ("anachronistic use of array size in vector delete");
-     }
- 
    type = TREE_TYPE (t);
  
    /* As of Valley Forge, you can delete a pointer to const.  */
  
    /* You can't delete functions.  */
--- 451,475 ----
        DELETE_EXPR_USE_VEC (t) = doing_vec;
        return t;
      }
  
    exp = convert_from_reference (exp);
+ 
+   /* An array can't have been allocated by new, so complain.  */
+   if (TREE_CODE (exp) == VAR_DECL
+       && TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)
+     warning ("deleting array `%#D'", exp);
+ 
    t = build_expr_type_conversion (WANT_POINTER, exp, true);
  
    if (t == NULL_TREE || t == error_mark_node)
      {
        error ("type `%#T' argument given to `delete', expected pointer",
  		TREE_TYPE (exp));
        return error_mark_node;
      }
  
    type = TREE_TYPE (t);
  
    /* As of Valley Forge, you can delete a pointer to const.  */
  
    /* You can't delete functions.  */
*************** delete_sanity (tree exp, tree size, int 
*** 488,509 ****
      {
        warning ("deleting `%T' is undefined", type);
        doing_vec = 0;
      }
  
-   /* An array can't have been allocated by new, so complain.  */
-   if (TREE_CODE (t) == ADDR_EXPR
-       && TREE_CODE (TREE_OPERAND (t, 0)) == VAR_DECL
-       && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == ARRAY_TYPE)
-     warning ("deleting array `%#D'", TREE_OPERAND (t, 0));
- 
    /* Deleting a pointer with the value zero is valid and has no effect.  */
    if (integer_zerop (t))
      return build1 (NOP_EXPR, void_type_node, t);
  
    if (doing_vec)
!     return build_vec_delete (t, maxindex, sfk_deleting_destructor,
  			     use_global_delete);
    else
      return build_delete (type, t, sfk_deleting_destructor,
  			 LOOKUP_NORMAL, use_global_delete);
  }
--- 484,500 ----
      {
        warning ("deleting `%T' is undefined", type);
        doing_vec = 0;
      }
  
    /* Deleting a pointer with the value zero is valid and has no effect.  */
    if (integer_zerop (t))
      return build1 (NOP_EXPR, void_type_node, t);
  
    if (doing_vec)
!     return build_vec_delete (t, /*maxindex=*/NULL_TREE, 
! 			     sfk_deleting_destructor,
  			     use_global_delete);
    else
      return build_delete (type, t, sfk_deleting_destructor,
  			 LOOKUP_NORMAL, use_global_delete);
  }
Index: cp/search.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/search.c,v
retrieving revision 1.286
diff -c -5 -p -r1.286 search.c
*** cp/search.c	4 Feb 2004 19:15:29 -0000	1.286
--- cp/search.c	14 Feb 2004 00:46:03 -0000
*************** friend_accessible_p (tree scope, tree de
*** 903,912 ****
--- 903,913 ----
  int 
  accessible_p (tree type, tree decl)
  {
    tree binfo;
    tree t;
+   tree scope;
    access_kind access;
  
    /* Nonzero if it's OK to access DECL if it has protected
       accessibility in TYPE.  */
    int protected_ok = 0;
*************** accessible_p (tree type, tree decl)
*** 914,923 ****
--- 915,929 ----
    /* If this declaration is in a block or namespace scope, there's no
       access control.  */
    if (!TYPE_P (context_for_name_lookup (decl)))
      return 1;
  
+   /* There is no need to perform access checks inside a thunk.  */
+   scope = current_scope ();
+   if (scope && DECL_THUNK_P (scope))
+     return 1;
+ 
    /* In a template declaration, we cannot be sure whether the
       particular specialization that is instantiated will be a friend
       or not.  Therefore, all access checks are deferred until
       instantiation.  */
    if (processing_template_decl)
*************** accessible_p (tree type, tree decl)
*** 956,966 ****
    if (current_class_type)
      protected_ok = protected_accessible_p (decl, current_class_type, binfo);
  
    /* Now, loop through the classes of which we are a friend.  */
    if (!protected_ok)
!     protected_ok = friend_accessible_p (current_scope (), decl, binfo);
  
    /* Standardize the binfo that access_in_type will use.  We don't
       need to know what path was chosen from this point onwards.  */
    binfo = TYPE_BINFO (type);
  
--- 962,972 ----
    if (current_class_type)
      protected_ok = protected_accessible_p (decl, current_class_type, binfo);
  
    /* Now, loop through the classes of which we are a friend.  */
    if (!protected_ok)
!     protected_ok = friend_accessible_p (scope, decl, binfo);
  
    /* Standardize the binfo that access_in_type will use.  We don't
       need to know what path was chosen from this point onwards.  */
    binfo = TYPE_BINFO (type);
  
Index: cp/typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck.c,v
retrieving revision 1.527
diff -c -5 -p -r1.527 typeck.c
*** cp/typeck.c	11 Feb 2004 01:47:06 -0000	1.527
--- cp/typeck.c	14 Feb 2004 00:46:03 -0000
*************** decay_conversion (tree exp)
*** 1369,1386 ****
  
        ptrtype = build_pointer_type (TREE_TYPE (type));
  
        if (TREE_CODE (exp) == VAR_DECL)
  	{
- 	  /* ??? This is not really quite correct
- 	     in that the type of the operand of ADDR_EXPR
- 	     is not the target type of the type of the ADDR_EXPR itself.
- 	     Question is, can this lossage be avoided?  */
- 	  adr = build1 (ADDR_EXPR, ptrtype, exp);
  	  if (!cxx_mark_addressable (exp))
  	    return error_mark_node;
! 	  TREE_CONSTANT (adr) = staticp (exp);
  	  TREE_SIDE_EFFECTS (adr) = 0;   /* Default would be, same as EXP.  */
  	  return adr;
  	}
        /* This way is better for a COMPONENT_REF since it can
  	 simplify the offset for a component.  */
--- 1369,1381 ----
  
        ptrtype = build_pointer_type (TREE_TYPE (type));
  
        if (TREE_CODE (exp) == VAR_DECL)
  	{
  	  if (!cxx_mark_addressable (exp))
  	    return error_mark_node;
! 	  adr = build_nop (ptrtype, build_address (exp));
  	  TREE_SIDE_EFFECTS (adr) = 0;   /* Default would be, same as EXP.  */
  	  return adr;
  	}
        /* This way is better for a COMPONENT_REF since it can
  	 simplify the offset for a component.  */
Index: testsuite/g++.dg/inherit/thunk2.C
===================================================================
RCS file: testsuite/g++.dg/inherit/thunk2.C
diff -N testsuite/g++.dg/inherit/thunk2.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/inherit/thunk2.C	14 Feb 2004 00:46:04 -0000
***************
*** 0 ****
--- 1,19 ----
+ // PR c++/14108
+ 
+ class ClassC {
+ public:
+   ~ClassC();
+ };
+ 
+ class ClassA {
+   virtual ClassC f();
+ };
+ 
+ class ClassB : public virtual ClassA {
+   virtual ClassC f();
+ };
+ 
+ ClassC ClassB::f() {
+   return ClassC();
+ }
+ 
Index: testsuite/g++.dg/template/array4.C
===================================================================
RCS file: testsuite/g++.dg/template/array4.C
diff -N testsuite/g++.dg/template/array4.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/array4.C	14 Feb 2004 00:46:04 -0000
***************
*** 0 ****
--- 1,11 ----
+ // PR c++/14122
+ 
+ extern const char str[];
+ 
+ template <const char* P>
+ struct A
+ {
+   template <const char* R>  void foo();
+ };
+ 
+ template class A<str>;


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