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 15742, 15696, 15625, 15629, 15209


This patch fixes an additional five regressions in GCC 3.4.0.  These
are:

15742 -- A false-positive warning about functions that do not return a
value in templates.

15696 -- An ICE-on-invalid for use of non-static member functions for
purposes other than to call the function.

15625 -- A rejects-valid case involving friends and templates.

15629 -- A problem with argument-dependent lookup involving friends
and templates.

15209 -- A problem with "__attribute__((packed))".  Nathan modified
the compiler (correctly) to treat packed fields much like bitfields in
the sense that they may be bound to a const reference, but the
compiler must introduce a temporary.  However, we were treating more
things as packed than we should have, in this sense.

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

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

2004-05-31  Mark Mitchell  <mark@codesourcery.com>

	PR c++/15742
	* call.c (build_over_call): Set
	current_function_returns_abnormally even in template functions.

	PR c++/15696
	* cp-tree.h (invalid_nonstatic_memfn_p): New function.
	* cvt.c (convert_to_void): Use it.
	* typeck.c (invalid_nonstatic_memfn_p): New function.
	(decay_conversion): Use it.

	PR c++/15625
	* pt.c (tsubst_decl): Set DECL_FRIEND_CONTEXT for instantiated
	templates.

	PR c++/15629
	* name-lookup.c (arg_assoc_class): Do not find template
	specializations.

	PR c++/15209
	* tree.c (lvalue_p_1): Only consider the right-hand side of "."
	expressions when determining whether or not an express is packed.

2004-05-31  Mark Mitchell  <mark@codesourcery.com>

	PR c++/15742
	* g++.dg/warn/Wreturn-1.C: New test.

	PR c++/15696
	* g++.dg/expr/ptrmem5.C: New test.

	PR c++/15625
	* g++.dg/template/friend27.C: New test.

	PR c++/15629
	* g++.dg/template/friend28.C: New test.
	* g++.dg/template/friend.C: Do not depend on <iostream>.  Add
	error message.

	PR c++/15209
	* g++.dg/ext/packed3.C: Remove bogus error.
	* g++.dg/ext/packed4.C: Remove bogus check.
	* g++.dg/ext/packed6.C: New test.

Index: cp/call.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.452.2.16
diff -c -5 -p -r1.452.2.16 call.c
*** cp/call.c	20 Mar 2004 00:13:07 -0000	1.452.2.16
--- cp/call.c	31 May 2004 20:48:58 -0000
*************** build_over_call (struct z_candidate *can
*** 4351,4360 ****
--- 4351,4362 ----
      {
        tree expr;
        tree return_type;
        return_type = TREE_TYPE (TREE_TYPE (fn));
        expr = build (CALL_EXPR, return_type, fn, args);
+       if (TREE_THIS_VOLATILE (fn) && cfun)
+ 	current_function_returns_abnormally = 1;
        if (!VOID_TYPE_P (return_type))
  	require_complete_type (return_type);
        return convert_from_reference (expr);
      }
  
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.946.4.12
diff -c -5 -p -r1.946.4.12 cp-tree.h
*** cp/cp-tree.h	28 May 2004 23:33:33 -0000	1.946.4.12
--- cp/cp-tree.h	31 May 2004 20:48:58 -0000
*************** extern tree check_return_expr           
*** 4246,4255 ****
--- 4246,4256 ----
  extern tree build_ptrmemfunc_access_expr       (tree, tree);
  extern tree build_address                       (tree);
  extern tree build_nop                           (tree, tree);
  extern tree non_reference                       (tree);
  extern tree lookup_anon_field                   (tree, tree);
+ extern bool invalid_nonstatic_memfn_p           (tree);
  
  /* in typeck2.c */
  extern void require_complete_eh_spec_types	(tree, tree);
  extern void cxx_incomplete_type_diagnostic	(tree, tree, int);
  #undef cxx_incomplete_type_error
Index: cp/cvt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cvt.c,v
retrieving revision 1.151.4.1
diff -c -5 -p -r1.151.4.1 cvt.c
*** cp/cvt.c	23 Feb 2004 12:46:37 -0000	1.151.4.1
--- cp/cvt.c	31 May 2004 20:48:58 -0000
*************** convert_to_void (tree expr, const char *
*** 789,798 ****
--- 789,800 ----
    if (expr == error_mark_node 
        || TREE_TYPE (expr) == error_mark_node)
      return error_mark_node;
    if (!TREE_TYPE (expr))
      return expr;
+   if (invalid_nonstatic_memfn_p (expr))
+     return error_mark_node;
    if (VOID_TYPE_P (TREE_TYPE (expr)))
      return expr;
    switch (TREE_CODE (expr))
      {
      case COND_EXPR:
Index: cp/name-lookup.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/name-lookup.c,v
retrieving revision 1.34.2.13
diff -c -5 -p -r1.34.2.13 name-lookup.c
*** cp/name-lookup.c	28 May 2004 22:29:41 -0000	1.34.2.13
--- cp/name-lookup.c	31 May 2004 20:48:58 -0000
*************** arg_assoc_class (struct arg_lookup *k, t
*** 4287,4301 ****
    for (list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type)); list; 
         list = TREE_CHAIN (list))
      if (k->name == FRIEND_NAME (list))
        for (friends = FRIEND_DECLS (list); friends; 
  	   friends = TREE_CHAIN (friends))
! 	/* Only interested in global functions with potentially hidden
!            (i.e. unqualified) declarations.  */
! 	if (CP_DECL_CONTEXT (TREE_VALUE (friends)) == context)
! 	  if (add_function (k, TREE_VALUE (friends)))
  	    return true;
  
    /* Process template arguments.  */
    if (CLASSTYPE_TEMPLATE_INFO (type))
      {
        list = INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (type));
--- 4287,4311 ----
    for (list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type)); list; 
         list = TREE_CHAIN (list))
      if (k->name == FRIEND_NAME (list))
        for (friends = FRIEND_DECLS (list); friends; 
  	   friends = TREE_CHAIN (friends))
! 	{
! 	  tree fn = TREE_VALUE (friends);
! 
! 	  /* Only interested in global functions with potentially hidden
! 	     (i.e. unqualified) declarations.  */
! 	  if (CP_DECL_CONTEXT (fn) != context)
! 	    continue;
! 	  /* Template specializations are never found by name lookup.
! 	     (Templates themselves can be found, but not template
! 	     specializations.)  */
! 	  if (TREE_CODE (fn) == FUNCTION_DECL && DECL_USE_TEMPLATE (fn))
! 	    continue;
! 	  if (add_function (k, fn))
  	    return true;
+ 	}
  
    /* Process template arguments.  */
    if (CLASSTYPE_TEMPLATE_INFO (type))
      {
        list = INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (type));
Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.816.2.26
diff -c -5 -p -r1.816.2.26 pt.c
*** cp/pt.c	23 May 2004 22:45:04 -0000	1.816.2.26
--- cp/pt.c	31 May 2004 20:48:58 -0000
*************** tsubst_decl (tree t, tree args, tree typ
*** 6259,6268 ****
--- 6259,6273 ----
  	      clone_function_decl (r, /*update_method_vec_p=*/0);
  	  }
  	else if (IDENTIFIER_OPNAME_P (DECL_NAME (r)))
  	  grok_op_properties (r, DECL_FRIEND_P (r),
  			      (complain & tf_error) != 0);
+ 
+ 	if (DECL_FRIEND_P (t) && DECL_FRIEND_CONTEXT (t))
+ 	  SET_DECL_FRIEND_CONTEXT (r,
+ 				   tsubst (DECL_FRIEND_CONTEXT (t),
+ 					    args, complain, in_decl));
        }
        break;
  
      case PARM_DECL:
        {
Index: cp/tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/tree.c,v
retrieving revision 1.360.4.5
diff -c -5 -p -r1.360.4.5 tree.c
*** cp/tree.c	19 Mar 2004 07:13:37 -0000	1.360.4.5
--- cp/tree.c	31 May 2004 20:48:58 -0000
*************** lvalue_p_1 (tree ref, 
*** 88,97 ****
--- 88,101 ----
  			 treat_class_rvalues_as_lvalues);
  
      case COMPONENT_REF:
        op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 0),
  				    treat_class_rvalues_as_lvalues);
+       /* In an expression of the form "X.Y", the packed-ness of the
+ 	 expression does not depend on "X".  */
+       op1_lvalue_kind &= ~clk_packed;
+       /* Look at the member designator.  */
        if (!op1_lvalue_kind 
  	  /* The "field" can be a FUNCTION_DECL or an OVERLOAD in some	
    	     situations.  */
   	  || TREE_CODE (TREE_OPERAND (ref, 1)) != FIELD_DECL)
   	;
Index: cp/typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck.c,v
retrieving revision 1.519.2.18
diff -c -5 -p -r1.519.2.18 typeck.c
*** cp/typeck.c	28 May 2004 23:33:35 -0000	1.519.2.18
--- cp/typeck.c	31 May 2004 20:48:59 -0000
*************** cxx_sizeof_or_alignof_expr (tree e, enum
*** 1282,1291 ****
--- 1282,1318 ----
    
    return cxx_sizeof_or_alignof_type (e, op, true);
  }
    
  
+ /* EXPR is being used in a context that is not a function call.
+    Enforce:
+ 
+      [expr.ref] 
+ 
+      The expression can be used only as the left-hand operand of a
+      member function call.  
+ 
+      [expr.mptr.operator]
+ 
+      If the result of .* or ->* is a function, then that result can be
+      used only as the operand for the function call operator ().  
+ 
+    by issuing an error message if appropriate.  Returns true iff EXPR
+    violates these rules.  */
+ 
+ bool
+ invalid_nonstatic_memfn_p (tree expr)
+ {
+   if (TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE)
+     {
+       error ("invalid use of non-static member function");
+       return true;
+     }
+   return false;
+ }
+ 
  /* Perform the conversions in [expr] that apply when an lvalue appears
     in an rvalue context: the lvalue-to-rvalue, array-to-pointer, and
     function-to-pointer conversions.
  
     In addition manifest constants are replaced by their values.  */
*************** decay_conversion (tree exp)
*** 1334,1348 ****
    if (code == VOID_TYPE)
      {
        error ("void value not ignored as it ought to be");
        return error_mark_node;
      }
!   if (code == METHOD_TYPE)
!     {
!       error ("invalid use of non-static member function");
!       return error_mark_node;
!     }
    if (code == FUNCTION_TYPE || is_overloaded_fn (exp))
      return build_unary_op (ADDR_EXPR, exp, 0);
    if (code == ARRAY_TYPE)
      {
        tree adr;
--- 1361,1372 ----
    if (code == VOID_TYPE)
      {
        error ("void value not ignored as it ought to be");
        return error_mark_node;
      }
!   if (invalid_nonstatic_memfn_p (exp))
!     return error_mark_node;
    if (code == FUNCTION_TYPE || is_overloaded_fn (exp))
      return build_unary_op (ADDR_EXPR, exp, 0);
    if (code == ARRAY_TYPE)
      {
        tree adr;
Index: testsuite/g++.dg/expr/ptrmem5.C
===================================================================
RCS file: testsuite/g++.dg/expr/ptrmem5.C
diff -N testsuite/g++.dg/expr/ptrmem5.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/expr/ptrmem5.C	31 May 2004 20:48:59 -0000
***************
*** 0 ****
--- 1,7 ----
+ // PR c++/15696
+ 
+ struct A {};
+ 
+ typedef void (A::*ftype)();
+ 
+ void foo() { A().*ftype(); } // { dg-error "" }
Index: testsuite/g++.dg/ext/packed3.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/ext/packed3.C,v
retrieving revision 1.1
diff -c -5 -p -r1.1 packed3.C
*** testsuite/g++.dg/ext/packed3.C	22 Jul 2003 09:53:34 -0000	1.1
--- testsuite/g++.dg/ext/packed3.C	31 May 2004 20:48:59 -0000
*************** struct  __attribute__ ((packed)) Packed
*** 18,25 ****
  };
  
  void Foo (Packed &p)
  {
    Ref (p.i); // { dg-error "cannot bind packed field" "" }
!   Ref (p.u.i); // { dg-error "cannot bind packed field" "" }
    Ref (p.u); // { dg-error "cannot bind packed field" "" }
  }
--- 18,25 ----
  };
  
  void Foo (Packed &p)
  {
    Ref (p.i); // { dg-error "cannot bind packed field" "" }
!   Ref (p.u.i);
    Ref (p.u); // { dg-error "cannot bind packed field" "" }
  }
Index: testsuite/g++.dg/ext/packed4.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/ext/packed4.C,v
retrieving revision 1.1
diff -c -5 -p -r1.1 packed4.C
*** testsuite/g++.dg/ext/packed4.C	22 Jul 2003 09:53:34 -0000	1.1
--- testsuite/g++.dg/ext/packed4.C	31 May 2004 20:48:59 -0000
*************** int Foo (Packed &p, int i, int ui)
*** 57,70 ****
    if ((r = Val (p.u, ui)))
      return r + 4;
    
    if ((r = ConstRef (p.i, &p.i, i)))
      return r + 6;
-   if ((r = ConstRef (p.u.i, &p.u.i, ui)))
-     return r + 8;
-   if ((r = ConstRef (p.u, &p.u, ui)))
-     return r + 10;
  
    return 0;
  }
  
  int main ()
--- 57,66 ----
Index: testsuite/g++.dg/ext/packed6.C
===================================================================
RCS file: testsuite/g++.dg/ext/packed6.C
diff -N testsuite/g++.dg/ext/packed6.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/ext/packed6.C	31 May 2004 20:48:59 -0000
***************
*** 0 ****
--- 1,78 ----
+ // PR c++/15209
+ // { dg-options "-w" }
+ 
+ typedef unsigned int size_t;
+ typedef unsigned char uint8_t;
+ typedef unsigned short int uint16_t;
+ 
+ typedef unsigned int uint32_t;
+ __extension__ typedef unsigned long long int uint64_t;
+ 
+ typedef uint8_t u8;
+ typedef uint16_t u16;
+ typedef uint32_t u32;
+ typedef uint64_t u64;
+ 
+ struct MAGIC {u8 magic[8];} __attribute__ ((packed));
+ struct PACKETTYPE {u8 type[16];} __attribute__ ((packed));
+ 
+ 
+ typedef u16 leu16;
+ typedef u32 leu32;
+ typedef u64 leu64;
+ 
+ class MD5Hash
+ {
+ public:
+ 
+   MD5Hash(void) {};
+ 
+   void *print(void) const;
+   MD5Hash(const MD5Hash &other);
+   MD5Hash& operator=(const MD5Hash &other);
+ 
+ public:
+   u8 hash[16];
+ };
+ 
+ struct PACKET_HEADER
+ {
+ 
+   MAGIC magic;
+   leu64 length;
+   MD5Hash hash;
+   MD5Hash setid;
+   PACKETTYPE type;
+ } __attribute__ ((packed));
+ 
+ 
+ struct MAINPACKET
+ {
+   PACKET_HEADER header;
+ 
+   leu64 blocksize;
+   leu32 recoverablefilecount;
+   MD5Hash fileid[0];
+ 
+ 
+ } __attribute__ ((packed));
+ 
+ struct CriticalPacket
+ {
+   u8 *packetdata;
+   size_t packetlength;
+ };
+ 
+ class MainPacket : public CriticalPacket
+ {
+   const MD5Hash& SetId(void) const;
+ 
+   u64 blocksize;
+   u32 totalfilecount;
+   u32 recoverablefilecount;
+ };
+ 
+ inline const MD5Hash& MainPacket::SetId(void) const
+ {
+   return ((const MAINPACKET*)packetdata)->header.setid;
+ }
Index: testsuite/g++.dg/template/friend.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/template/friend.C,v
retrieving revision 1.5
diff -c -5 -p -r1.5 friend.C
*** testsuite/g++.dg/template/friend.C	18 Mar 2002 13:27:03 -0000	1.5
--- testsuite/g++.dg/template/friend.C	31 May 2004 20:48:59 -0000
***************
*** 1,11 ****
  // Contribued by Gabriel Dos Reis <gdr@codesourcery.com>
  // Origin: iskey@i100.ryd.student.liu.se
- // { dg-do link }
  
! #include <iostream>
! using namespace std;
  
  template <class T> struct s;
  
  template <class T>
  ostream& operator<<(ostream &o, const typename s<T>::t &x)
--- 1,10 ----
  // Contribued by Gabriel Dos Reis <gdr@codesourcery.com>
  // Origin: iskey@i100.ryd.student.liu.se
  
! class ostream;
! extern ostream& cout;
  
  template <class T> struct s;
  
  template <class T>
  ostream& operator<<(ostream &o, const typename s<T>::t &x)
*************** struct s {
*** 24,30 ****
  };
  
  int main()
  {
    s<int>::t y;
!   cout << y;
  }
--- 23,29 ----
  };
  
  int main()
  {
    s<int>::t y;
!   cout << y; // { dg-error "" }
  }
Index: testsuite/g++.dg/template/friend27.C
===================================================================
RCS file: testsuite/g++.dg/template/friend27.C
diff -N testsuite/g++.dg/template/friend27.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/friend27.C	31 May 2004 20:48:59 -0000
***************
*** 0 ****
--- 1,22 ----
+ // PR c++/15265
+ 
+ enum Relation {equalOp};
+ template<typename B>
+ class A {
+ public:
+     static
+     bool    Relop(const A&, const A&, Relation);
+ 
+     friend
+     bool    operator==(const A& a1, const A& a2) {
+       return Relop(a1, a2, equalOp);
+     }
+   B* b;
+ };
+ 
+ int main() {
+   A<int> a; a == a;
+   return 0;
+ }
+ 
+ 
Index: testsuite/g++.dg/template/friend28.C
===================================================================
RCS file: testsuite/g++.dg/template/friend28.C
diff -N testsuite/g++.dg/template/friend28.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/friend28.C	31 May 2004 20:48:59 -0000
***************
*** 0 ****
--- 1,23 ----
+ // PR c++/15629
+ // { dg-do link }
+ 
+ template<int a, int b> class T; 
+  
+ template<int a, int b> void func(T<a, b> * t);
+ template<int a>        void func(T<a, 3> * t) {}
+ template void func<2>(T<2, 3>*);
+  
+ template<int a, int b> struct T { 
+   friend void func<a, b>(T<a, b> * t); 
+   friend void func<a>   (T<a, 3> * t); 
+    
+   void foo(); 
+ }; 
+  
+ template<int a, int b> void T<a, b>::foo() { 
+   func((T<2,3>*)0); 
+ } 
+  
+ int main() { 
+   T<2,3>().foo(); 
+ } 
Index: testsuite/g++.dg/warn/Wreturn-1.C
===================================================================
RCS file: testsuite/g++.dg/warn/Wreturn-1.C
diff -N testsuite/g++.dg/warn/Wreturn-1.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/warn/Wreturn-1.C	31 May 2004 20:48:59 -0000
***************
*** 0 ****
--- 1,9 ----
+ // { dg-options "-Wreturn-type" }
+ // PR c++/15742
+ 
+ extern void exit(int) __attribute__ ((noreturn));
+ 
+ template<typename T>
+ struct A {
+   int find_cmp(void) { exit(1); }
+ };


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