PATCH: PR c++/9844, c++/13989 fix

Ziemowit Laski zlaski@apple.com
Fri Jun 18 07:20:00 GMT 2004


This patch fixes assorted __attribute__(...) handling problems in the 
C++ front-end.
The cplus_decl_attributes() function was not being called in all the 
right places,
and attributes were getting dropped on the floor as a result.  There is 
also a small
tweak to the parser itself to allow more flexibility in specifying 
__attribute__ for
conversion types.  And, there are 3 test cases, all of which failed 
before but pass
now.

OK to install if the thing bootstraps and there are no regressions?

Thanks,

--Zem

[gcc/ChangeLog]
2004-06-17  Ziemowit Laski  <zlaski@apple.com>

	PR c++/9844, c++/13989
	* tree.c (reconstruct_complex_type): Exclude 'this' parameter when
	calling build_method_type_directly(), since the callee will add
	its own.

[gcc/cp/ChangeLog]
2004-06-17  Ziemowit Laski  <zlaski@apple.com>

	PR c++/9844, c++/13989
	* decl.c (grokfndecl): Add an 'attrs' parameter, and use it to call
	cplus_decl_attributes() with it.
	(grokdeclarator): Add 'attrlist' argument to all grokfndecl() calls.
	(start_function, start_method): Do not call cplus_decl_attributes().
	* decl2.c (grokfield): Do not call cplus_decl_attributes() for
	FUNCTION_DECLs; grokfndecl() now does it instead.
	* parser.c (cp_parser_conversion_type_id): Use
	cp_parser_type_specifier_seq() to parse both type specifiers and
	attributes, and groktypename() to split them apart.

[gcc/testsuite/ChangeLog]
2004-06-17  Ziemowit Laski  <zlaski@apple.com>

	PR c++/9844, c++/13989
	* g++.dg/ext/attrib16.C: New test case.
	* g++.dg/ext/attrib17.C: New test case.
	* g++.dg/ext/attrib18.C: New test case.


Index: gcc/tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.c,v
retrieving revision 1.376
diff -u -3 -p -r1.376 tree.c
--- gcc/tree.c  15 Jun 2004 18:37:32 -0000      1.376
+++ gcc/tree.c  18 Jun 2004 02:23:38 -0000
@@ -5417,9 +5417,12 @@ reconstruct_complex_type (tree type, tre
    else if (TREE_CODE (type) == METHOD_TYPE)
      {
        inner = reconstruct_complex_type (TREE_TYPE (type), bottom);
+      /* NB: The build_method_type_directly() routine will helpfully
+        prepend 'this' to our argument list, so we must compensate
+        by getting rid of it here.  */
        outer = build_method_type_directly (TYPE_METHOD_BASETYPE (type),
                                           inner,
-                                         TYPE_ARG_TYPES (type));
+                                         TREE_CHAIN (TYPE_ARG_TYPES 
(type)));
      }
    else
      return bottom;
Index: gcc/cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1220
diff -u -3 -p -r1.1220 decl.c
--- gcc/cp/decl.c       17 Jun 2004 01:24:03 -0000      1.1220
+++ gcc/cp/decl.c       18 Jun 2004 02:23:41 -0000
@@ -62,7 +62,7 @@ static int ambi_op_p (enum tree_code);
  static int unary_op_p (enum tree_code);
  static void push_local_name (tree);
  static tree grok_reference_init (tree, tree, tree, tree *);
-static tree grokfndecl (tree, tree, tree, tree, tree, int,
+static tree grokfndecl (tree, tree, tree, tree, tree, tree *, int,
                         enum overload_flags, tree,
                         tree, int, int, int, int, int, int, tree);
  static tree grokvardecl (tree, tree, RID_BIT_TYPE *, int, int, tree);
@@ -5468,6 +5468,8 @@ bad_specifiers (tree object,
     FLAGS are to be passed through to `grokclassfn'.
     QUALS are qualifiers indicating whether the function is `const'
     or `volatile'.
+   ATTRS is a pointer to a list of attributes to be applied to the
+   resulting function decl.
     RAISES is a list of exceptions that this function can raise.
     CHECK is 1 if we must find this method in CTYPE, 0 if we should
     not look, and -1 if we should not call `grokclassfn' at all.
@@ -5481,6 +5483,7 @@ grokfndecl (tree ctype,
              tree declarator,
             tree parms,
              tree orig_declarator,
+            tree *attrs,
              int virtualp,
              enum overload_flags flags,
              tree quals,
@@ -5507,6 +5510,10 @@ grokfndecl (tree ctype,
    if (TYPE_VOLATILE (type))
      TREE_THIS_VOLATILE (decl) = 1;

+  /* Apply attributes, if any.  */
+  if (attrs && *attrs)
+    cplus_decl_attributes (&decl, *attrs, 0);
+
    /* If this decl has namespace scope, set that up.  */
    if (in_namespace)
      set_decl_namespace (decl, in_namespace, friendp);
@@ -8139,11 +8146,12 @@ grokdeclarator (tree declarator,
               decl_function_context (TYPE_MAIN_DECL (ctype)) : 
NULL_TREE;
             publicp = (! friendp || ! staticp)
               && function_context == NULL_TREE;
+
             decl = grokfndecl (ctype, type,
                                TREE_CODE (declarator) != 
TEMPLATE_ID_EXPR
                                ? declarator : dname,
                                parms,
-                              declarator,
+                              declarator, attrlist,
                                virtualp, flags, quals, raises,
                                friendp ? -1 : 0, friendp, publicp, 
inlinep,
                                funcdef_flag, template_count, 
in_namespace);
@@ -8190,7 +8198,7 @@ grokdeclarator (tree declarator,
                                TREE_CODE (declarator) != 
TEMPLATE_ID_EXPR
                                ? declarator : dname,
                                parms,
-                              declarator,
+                              declarator, attrlist,
                                virtualp, flags, quals, raises,
                                friendp ? -1 : 0, friendp, 1, 0, 
funcdef_flag,
                                template_count, in_namespace);
@@ -8372,6 +8380,7 @@ grokdeclarator (tree declarator,
                    || !RIDBIT_SETP (RID_STATIC, specbits));

         decl = grokfndecl (ctype, type, original_name, parms, 
declarator,
+                          attrlist,
                            virtualp, flags, quals, raises,
                            1, friendp,
                            publicp, inlinep, funcdef_flag,
@@ -10102,8 +10111,6 @@ start_function (tree declspecs, tree dec
        if (decl1 == NULL_TREE || TREE_CODE (decl1) != FUNCTION_DECL)
         return 0;

-      cplus_decl_attributes (&decl1, attrs, 0);
-
        /* If #pragma weak was used, mark the decl weak now.  */
        if (global_scope_p (current_binding_level))
         maybe_apply_pragma_weak (decl1);
@@ -10890,9 +10897,6 @@ start_method (tree declspecs, tree decla
        return error_mark_node;
      }

-  if (attrlist)
-    cplus_decl_attributes (&fndecl, attrlist, 0);
-
    /* Pass friends other than inline friend functions back.  */
    if (fndecl == void_type_node)
      return fndecl;
Index: gcc/cp/decl2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl2.c,v
retrieving revision 1.716
diff -u -3 -p -r1.716 decl2.c
--- gcc/cp/decl2.c      17 Jun 2004 21:11:38 -0000      1.716
+++ gcc/cp/decl2.c      18 Jun 2004 02:23:41 -0000
@@ -969,7 +969,9 @@ grokfield (tree declarator, tree declspe
         return error_mark_node;
      }

-  if (attrlist)
+  /* Apply attributes, if any.  For member functions, this has already 
been
+     done in grokfndecl ().  */
+  if (attrlist && TREE_CODE (value) != FUNCTION_DECL)
      cplus_decl_attributes (&value, attrlist, 0);

    if (TREE_CODE (value) == VAR_DECL)
Index: gcc/cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.211
diff -u -3 -p -r1.211 parser.c
--- gcc/cp/parser.c     17 Jun 2004 01:24:04 -0000      1.211
+++ gcc/cp/parser.c     18 Jun 2004 02:23:43 -0000
@@ -7226,22 +7226,19 @@ cp_parser_conversion_function_id (cp_par
  static tree
  cp_parser_conversion_type_id (cp_parser* parser)
  {
-  tree attributes;
    tree type_specifiers;
    tree declarator;

-  /* Parse the attributes.  */
-  attributes = cp_parser_attributes_opt (parser);
    /* Parse the type-specifiers.  */
    type_specifiers = cp_parser_type_specifier_seq (parser);
    /* If that didn't work, stop.  */
    if (type_specifiers == error_mark_node)
      return error_mark_node;
+
    /* Parse the conversion-declarator.  */
    declarator = cp_parser_conversion_declarator_opt (parser);

-  return grokdeclarator (declarator, type_specifiers, TYPENAME,
-                        /*initialized=*/0, &attributes);
+  return groktypename (build_tree_list (type_specifiers, declarator));
  }

  /* Parse an (optional) conversion-declarator.
Index: gcc/testsuite/g++.dg/ext/attrib16.C
===================================================================
RCS file: gcc/testsuite/g++.dg/ext/attrib16.C
diff -N gcc/testsuite/g++.dg/ext/attrib16.C
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/g++.dg/ext/attrib16.C 18 Jun 2004 02:23:47 -0000
@@ -0,0 +1,15 @@
+// { dg-do compile }
+// PR c++/13989
+
+#define vector __attribute__((vector_size(16)))
+
+struct Constants {
+    inline vector unsigned int deadbeef(void) const {
+        return (vector unsigned int){0xdeadbeef, 0xabababab, 
0x55555555, 0x12345678};
+    };
+};
+inline vector unsigned int const_deadbeef(Constants &C)
+{
+    return C.deadbeef();
+}
+
Index: gcc/testsuite/g++.dg/ext/attrib17.C
===================================================================
RCS file: gcc/testsuite/g++.dg/ext/attrib17.C
diff -N gcc/testsuite/g++.dg/ext/attrib17.C
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/g++.dg/ext/attrib17.C 18 Jun 2004 02:23:47 -0000
@@ -0,0 +1,14 @@
+// { dg-do compile }
+// PR c++/9844
+
+class vector_holder
+{
+   char __attribute__((vector_size(16))) vec;
+  public:
+   operator __attribute__((vector_size(16))) short (void) {
+     return (__attribute__((vector_size(16))) short) vec;
+   }
+   operator int __attribute__((vector_size(16))) (void) {
+     return (int __attribute__((vector_size(16)))) vec;
+   }
+};
Index: gcc/testsuite/g++.dg/ext/attrib18.C
===================================================================
RCS file: gcc/testsuite/g++.dg/ext/attrib18.C
diff -N gcc/testsuite/g++.dg/ext/attrib18.C
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/g++.dg/ext/attrib18.C 18 Jun 2004 02:23:47 -0000
@@ -0,0 +1,21 @@
+// { dg-do compile }
+// PR c++/13989
+
+#define vector __attribute__((vector_size(16)))
+
+class Star
+{
+        public:
+               inline vector float foo() const;
+        private:
+          union {
+                float f[4];
+                vector float v;
+                       } data;
+};
+
+inline vector float Star::foo() const
+{
+    return data.v;
+}
+

--------------------------------------------------------------
Ziemowit Laski                 1 Infinite Loop, MS 301-2K
Mac OS X Compiler Group        Cupertino, CA USA  95014-2083
Apple Computer, Inc.           +1.408.974.6229  Fax .5477



More information about the Gcc-patches mailing list