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]

PATCH: PR c++/17524, c++/17685


This patch fixes two C++ PRs where we ICE'd on erroneous code.

The fix for 17524 involves sharing more code between the template and
non-template processing paths, which is usually a good thing.  The
patch for 17685 is straightforward: we were simply failing to
check that only functions can be declared to be operators.

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

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

2004-10-09  Mark Mitchell  <mark@codesourcery.com>

	PR c++/17524
	* cp-tree.h (check_var_type): New function.
	* decl.c (check_var_type): New function, split out from ...
	(grokdeclarator): ... here.
	* pt.c (tsubst_decl): Use check_var_type.

	PR c++/17685
	* decl.c (grokdeclarator): Disallow declarations of operators as
	non-functions.

2004-10-09  Mark Mitchell  <mark@codesourcery.com>

	PR c++/17524
	* g++.dg/template/static9.C: New test.

	PR c++/17685
	* g++.dg/parse/operator5.C: New test.

Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.1058
diff -c -5 -p -r1.1058 cp-tree.h
*** cp/cp-tree.h	8 Oct 2004 09:33:54 -0000	1.1058
--- cp/cp-tree.h	9 Oct 2004 17:28:02 -0000
*************** extern tree builtin_function (const char
*** 3757,3766 ****
--- 3757,3767 ----
  extern tree check_elaborated_type_specifier     (enum tag_types, tree, bool);
  extern void warn_extern_redeclared_static (tree, tree);
  extern const char *cxx_comdat_group             (tree);
  extern bool cp_missing_noreturn_ok_p		(tree);
  extern void initialize_artificial_var            (tree, tree);
+ extern tree check_var_type (tree, tree);
  
  extern bool have_extern_spec;
  
  /* in decl2.c */
  extern bool check_java_method (tree);
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1311
diff -c -5 -p -r1.1311 decl.c
*** cp/decl.c	7 Oct 2004 17:48:30 -0000	1.1311
--- cp/decl.c	9 Oct 2004 17:28:03 -0000
*************** check_special_function_return_type (spec
*** 6393,6402 ****
--- 6393,6427 ----
      }
  
    return type;
  }
  
+ /* A variable or data member (whose unqualified name is IDENTIFIER)
+    has been declared with the indicated TYPE.  If the TYPE is not
+    acceptable, issue an error message and return a type to use for
+    error-recovery purposes. */
+ 
+ tree
+ check_var_type (tree identifier, tree type)
+ {
+   if (VOID_TYPE_P (type))
+     {
+       if (!identifier)
+ 	error ("unnamed variable or field declared void");
+       else if (TREE_CODE (identifier) == IDENTIFIER_NODE)
+ 	{
+ 	  gcc_assert (!IDENTIFIER_OPNAME_P (identifier));
+ 	  error ("variable or field %qE declared void", identifier);
+ 	}
+       else
+ 	error ("variable or field declared void");
+       type = integer_type_node;
+     }
+   
+   return type;
+ }
+ 
  /* Given declspecs and a declarator (abstract or otherwise), determine
     the name and type of the object declared and construct a DECL node
     for it.
  
     DECLSPECS is a chain of tree_list nodes whose value fields
*************** grokdeclarator (const cp_declarator *dec
*** 7741,7769 ****
      {
        error ("abstract declarator %qT used as declaration", type);
        unqualified_id = make_anon_name ();
      }
  
!   /* `void' at top level (not within pointer)
!      is allowed only in typedefs or type names.
!      We don't complain about parms either, but that is because
!      a better error message can be made later.  */
! 
!   if (TREE_CODE (type) == VOID_TYPE && decl_context != PARM)
      {
!       if (! unqualified_id)
! 	error ("unnamed variable or field declared void");
!       else if (TREE_CODE (unqualified_id) == IDENTIFIER_NODE)
! 	{
! 	  gcc_assert (!IDENTIFIER_OPNAME_P (unqualified_id));
! 	  error ("variable or field %qs declared void", name);
! 	}
!       else
! 	error ("variable or field declared void");
!       type = integer_type_node;
      }
  
    /* Now create the decl, which may be a VAR_DECL, a PARM_DECL
       or a FUNCTION_DECL, depending on DECL_CONTEXT and TYPE.  */
  
    if (decl_context == PARM || decl_context == CATCHPARM)
      {
--- 7766,7790 ----
      {
        error ("abstract declarator %qT used as declaration", type);
        unqualified_id = make_anon_name ();
      }
  
!   /* Only functions may be declared using an operator-function-id.  */
!   if (unqualified_id
!       && IDENTIFIER_OPNAME_P (unqualified_id)
!       && TREE_CODE (type) != FUNCTION_TYPE
!       && TREE_CODE (type) != METHOD_TYPE)
      {
!       error ("declaration of %qD as non-function", unqualified_id);
!       return error_mark_node;
      }
  
+   /* We don't check parameter types here because we can emit a better
+      error message later.  */
+   if (decl_context != PARM)
+     type = check_var_type (unqualified_id, type);
+ 
    /* Now create the decl, which may be a VAR_DECL, a PARM_DECL
       or a FUNCTION_DECL, depending on DECL_CONTEXT and TYPE.  */
  
    if (decl_context == PARM || decl_context == CATCHPARM)
      {
Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.933
diff -c -5 -p -r1.933 pt.c
*** cp/pt.c	8 Oct 2004 13:04:04 -0000	1.933
--- cp/pt.c	9 Oct 2004 17:28:11 -0000
*************** tsubst_decl (tree t, tree args, tree typ
*** 6506,6515 ****
--- 6506,6516 ----
  	if (TREE_CODE (r) == VAR_DECL)
  	  {
  	    type = complete_type (type);
  	    DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (r)
  	      = DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (t);
+ 	    type = check_var_type (DECL_NAME (r), type);
  	  }
  	else if (DECL_SELF_REFERENCE_P (t))
  	  SET_DECL_SELF_REFERENCE_P (r);
  	TREE_TYPE (r) = type;
  	c_apply_type_quals_to_decl (cp_type_quals (type), r);
*************** tsubst_decl (tree t, tree args, tree typ
*** 6546,6558 ****
  	  }
  	else
  	  register_local_specialization (r, t);
  
  	TREE_CHAIN (r) = NULL_TREE;
- 	if (TREE_CODE (r) == VAR_DECL && VOID_TYPE_P (type))
- 	  cp_error_at ("instantiation of %qD as type %qT", r, type);
- 	/* Compute the size, alignment, etc. of R.  */
  	layout_decl (r, 0);
        }
        break;
  
      default:
--- 6547,6556 ----
Index: testsuite/g++.dg/parse/operator5.C
===================================================================
RCS file: testsuite/g++.dg/parse/operator5.C
diff -N testsuite/g++.dg/parse/operator5.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/parse/operator5.C	9 Oct 2004 17:28:25 -0000
***************
*** 0 ****
--- 1,7 ----
+ // PR c++/17685
+ 
+ struct S {
+   operator int; // { dg-error "" }
+   operator void; // { dg-error "" }
+ };
+ 
Index: testsuite/g++.dg/template/static9.C
===================================================================
RCS file: testsuite/g++.dg/template/static9.C
diff -N testsuite/g++.dg/template/static9.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/static9.C	9 Oct 2004 17:28:25 -0000
***************
*** 0 ****
--- 1,8 ----
+ // PR c++/17524
+ 
+ template<typename T> struct A
+ {
+   static const T i = 0; // { dg-error "" }
+ };
+ 
+ A<void> a; // { dg-error "" }


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