This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PING: PATCH: PR c++/9844, c++/13989 fix
- From: Ziemowit Laski <zlaski at apple dot com>
- To: Gcc Patch List <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 18 Jun 2004 17:07:52 -0700
- Subject: PING: PATCH: PR c++/9844, c++/13989 fix
NEWS FLASH: The patch bootstraps and DejaGNUs beautifully, with no
regressions. I did
have to tweak one of the test cases slightly (to avoid pedantic-mode
warnings about
compound initializers), but aside from that everything else is the same.
OK to commit? Pretty please? This is at the root of some C++ AltiVec
weirdness
that we're seeing.
Thank you,
--Zem
============
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.
[gcc/ChangeLog]
2004-06-18 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-18 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-18 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 19 Jun 2004 00:05:49 -0000
@@ -0,0 +1,17 @@
+// { dg-do compile }
+// PR c++/13989
+
+#define vector __attribute__((vector_size(16)))
+
+struct Constants {
+ char vector vec;
+
+ inline vector unsigned int deadbeef(void) const {
+ return (vector unsigned int)vec;
+ };
+};
+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