(C++) attribute handling patch

Jason Merrill jason@cygnus.com
Fri Apr 9 12:44:00 GMT 1999


We were silently ignoring attributes on objects declared with
constructor-syntax initializers.

1999-04-09  Jason Merrill  <jason@yorick.cygnus.com>

	* decl.c (start_decl): Pass attributes to grokdeclarator.
	(grokdeclarator): Handle attributes on constructor-syntax
	initializers.

Index: decl.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/decl.c,v
retrieving revision 1.335
diff -c -p -r1.335 decl.c
*** decl.c	1999/04/05 23:09:51	1.335
--- decl.c	1999/04/09 19:43:39
*************** start_decl (declarator, declspecs, initi
*** 6975,6980 ****
--- 6975,6981 ----
    tree context;
    extern int have_extern_spec;
    extern int used_extern_spec;
+   tree attrlist;
  
  #if 0
    /* See code below that used this.  */
*************** start_decl (declarator, declspecs, initi
*** 6989,6996 ****
        used_extern_spec = 1;
      }
  
    decl = grokdeclarator (declarator, declspecs, NORMAL, initialized,
! 			 NULL_TREE);
    if (decl == NULL_TREE || TREE_CODE (decl) == VOID_TYPE)
      return NULL_TREE;
  
--- 6990,7003 ----
        used_extern_spec = 1;
      }
  
+   if (attributes || prefix_attributes)
+     attrlist = build_scratch_list (attributes, prefix_attributes);
+   else
+     attrlist = NULL_TREE;
+ 
    decl = grokdeclarator (declarator, declspecs, NORMAL, initialized,
! 			 attrlist);
! 			 
    if (decl == NULL_TREE || TREE_CODE (decl) == VOID_TYPE)
      return NULL_TREE;
  
*************** build_ptrmemfunc_type (type)
*** 8900,8905 ****
--- 8907,8947 ----
    return t;
  }
  
+ /* DECL is a VAR_DECL defined in-class, whose TYPE is also given.
+    Check to see that the definition is valid.  Issue appropriate error
+    messages.  Return 1 if the definition is particularly bad, or 0
+    otherwise.  */
+ 
+ int
+ check_static_variable_definition (decl, type)
+      tree decl;
+      tree type;
+ {
+   /* Motion 10 at San Diego: If a static const integral data member is
+      initialized with an integral constant expression, the initializer
+      may appear either in the declaration (within the class), or in
+      the definition, but not both.  If it appears in the class, the
+      member is a member constant.  The file-scope definition is always
+      required.  */
+   if (CLASS_TYPE_P (type) || TREE_CODE (type) == REFERENCE_TYPE)
+     {
+       cp_error ("in-class initialization of static data member of non-integral type `%T'", 
+ 		type);
+       /* If we just return the declaration, crashes will sometimes
+ 	 occur.  We therefore return void_type_node, as if this was a
+ 	 friend declaration, to cause callers to completely ignore
+ 	 this declaration.  */
+       return 1;
+     }
+   else if (!CP_TYPE_CONST_P (type))
+     cp_error ("ANSI C++ forbids in-class initialization of non-const static member `%D'",
+ 	      decl);
+   else if (pedantic && !INTEGRAL_TYPE_P (type))
+     cp_pedwarn ("ANSI C++ forbids initialization of member constant `%D' of non-integral type `%T'", decl, type);
+ 
+   return 0;
+ }
+ 
  /* Given declspecs and a declarator,
     determine the name and type of the object declared
     and construct a ..._DECL node for it.
*************** build_ptrmemfunc_type (type)
*** 8927,8932 ****
--- 8969,8977 ----
       BITFIELD for a field with specified width.
     INITIALIZED is 1 if the decl has an initializer.
  
+    ATTRLIST is a TREE_LIST node with prefix attributes in TREE_VALUE and
+    normal attributes in TREE_PURPOSE, or NULL_TREE.
+ 
     In the TYPENAME case, DECLARATOR is really an absolute declarator.
     It may also be so in the PARM case, for a prototype where the
     argument type is specified but not the name.
*************** build_ptrmemfunc_type (type)
*** 8958,8998 ****
  
  enum return_types { return_normal, return_ctor, return_dtor, return_conversion };
  
- /* DECL is a VAR_DECL defined in-class, whose TYPE is also given.
-    Check to see that the definition is valid.  Issue appropriate error
-    messages.  Return 1 if the definition is particularly bad, or 0
-    otherwise.  */
- 
- int
- check_static_variable_definition (decl, type)
-      tree decl;
-      tree type;
- {
-   /* Motion 10 at San Diego: If a static const integral data member is
-      initialized with an integral constant expression, the initializer
-      may appear either in the declaration (within the class), or in
-      the definition, but not both.  If it appears in the class, the
-      member is a member constant.  The file-scope definition is always
-      required.  */
-   if (CLASS_TYPE_P (type) || TREE_CODE (type) == REFERENCE_TYPE)
-     {
-       cp_error ("in-class initialization of static data member of non-integral type `%T'", 
- 		type);
-       /* If we just return the declaration, crashes will sometimes
- 	 occur.  We therefore return void_type_node, as if this was a
- 	 friend declaration, to cause callers to completely ignore
- 	 this declaration.  */
-       return 1;
-     }
-   else if (!CP_TYPE_CONST_P (type))
-     cp_error ("ANSI C++ forbids in-class initialization of non-const static member `%D'",
- 	      decl);
-   else if (pedantic && !INTEGRAL_TYPE_P (type))
-     cp_pedwarn ("ANSI C++ forbids initialization of member constant `%D' of non-integral type `%T'", decl, type);
- 
-   return 0;
- }
- 
  tree
  grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
       tree declspecs;
--- 9003,9008 ----
*************** grokdeclarator (declarator, declspecs, d
*** 9129,9142 ****
  	  case CALL_EXPR:
  	    if (parmlist_is_exprlist (TREE_OPERAND (decl, 1)))
  	      {
! 		/* This is actually a variable declaration using constructor
! 		   syntax.  We need to call start_decl and cp_finish_decl so we
! 		   can get the variable initialized...  */
  
  		*next = TREE_OPERAND (decl, 0);
  		init = TREE_OPERAND (decl, 1);
  
! 		decl = start_decl (declarator, declspecs, 1, NULL_TREE, NULL_TREE);
  		if (decl)
  		  {
  		    /* Look for __unused__ attribute */
--- 9139,9167 ----
  	  case CALL_EXPR:
  	    if (parmlist_is_exprlist (TREE_OPERAND (decl, 1)))
  	      {
! 		/* This is actually a variable declaration using
! 		   constructor syntax.  We need to call start_decl and
! 		   cp_finish_decl so we can get the variable
! 		   initialized...  */
  
+ 		tree attributes, prefix_attributes;
+ 
  		*next = TREE_OPERAND (decl, 0);
  		init = TREE_OPERAND (decl, 1);
+ 
+ 		if (attrlist)
+ 		  {
+ 		    attributes = TREE_PURPOSE (attrlist);
+ 		    prefix_attributes = TREE_VALUE (attrlist);
+ 		  }
+ 		else
+ 		  {
+ 		    attributes = NULL_TREE;
+ 		    prefix_attributes = NULL_TREE;
+ 		  }
  
! 		decl = start_decl (declarator, declspecs, 1,
! 				   attributes, prefix_attributes);
  		if (decl)
  		  {
  		    /* Look for __unused__ attribute */


More information about the Gcc-patches mailing list