From 037cc9c5dce2bd0569c90e67ab9760d36e1c620f Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Thu, 23 Sep 2004 18:22:25 +0000 Subject: [PATCH] PR c++/9844, PR c++/13989 PR c++/9844, PR c++/13989 Reviewed by Mark Mitchel. From-SVN: r87971 --- gcc/ChangeLog | 15 ++++++ gcc/config/rs6000/rs6000.c | 2 +- gcc/cp/cvt.c | 15 +++++- gcc/cp/decl.c | 22 ++++++--- gcc/cp/parser.c | 8 ++- gcc/testsuite/g++.dg/ext/attribute-test-1.C | 36 ++++++++++++++ gcc/testsuite/g++.dg/ext/attribute-test-2.C | 47 ++++++++++++++++++ gcc/testsuite/g++.dg/ext/attribute-test-3.C | 55 +++++++++++++++++++++ gcc/testsuite/g++.dg/ext/attribute-test-4.C | 48 ++++++++++++++++++ gcc/tree.c | 5 ++ 10 files changed, 241 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ext/attribute-test-1.C create mode 100644 gcc/testsuite/g++.dg/ext/attribute-test-2.C create mode 100644 gcc/testsuite/g++.dg/ext/attribute-test-3.C create mode 100644 gcc/testsuite/g++.dg/ext/attribute-test-4.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3c44c68c815..b54874f5683 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2004-09-21 Fariborz Jahanian + PR c++/13989 + PR c++/9844 + + * cp/decl.c (grokfndecl): Add new argument "attrlist", use it + to call cplus_decl_attributes. + (start_function): Remove call to cplus_decl_attributes. + * tree.c (reconstruct_complex_type): Remove extra "this". + * cp/cvt.c (ocp_convert): Add support to use type conversion + function to vector type. + * cp/parser.c (cp_parser_conversion_type_id): Add attributes, if any, + to the parsed type. + * config/rs6000/rs6000.c (rs6000_handle_altivec_attribute): + Add V4SFmode to case statement. + 2004-09-23 Joseph S. Myers PR c/16833 diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 7f448ee0c4b..39ace238fa3 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -16265,7 +16265,7 @@ rs6000_handle_altivec_attribute (tree *node, tree name, tree args, /* If the user says 'vector int bool', we may be handed the 'bool' attribute _before_ the 'vector' attribute, and so select the proper type in the 'b' case below. */ - case V4SImode: case V8HImode: case V16QImode: result = type; + case V4SImode: case V8HImode: case V16QImode: case V4SFmode: result = type; default: break; } break; diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index cb179d55ab2..5db41468c90 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -699,7 +699,20 @@ ocp_convert (tree type, tree expr, int convtype, int flags) if (POINTER_TYPE_P (type) || TYPE_PTR_TO_MEMBER_P (type)) return fold (cp_convert_to_pointer (type, e, false)); if (code == VECTOR_TYPE) - return fold (convert_to_vector (type, e)); + { + tree in_vtype = TREE_TYPE (e); + if (IS_AGGR_TYPE (in_vtype)) + { + tree ret_val; + ret_val = build_type_conversion (type, e); + if (ret_val) + return ret_val; + if (flags & LOOKUP_COMPLAIN) + error ("`%#T' used where a `%T' was expected", in_vtype, type); + return error_mark_node; + } + return fold (convert_to_vector (type, e)); + } if (code == REAL_TYPE || code == COMPLEX_TYPE) { if (IS_AGGR_TYPE (TREE_TYPE (e))) diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 30bfa8b6ef6..b3cdd6978bc 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -63,7 +63,8 @@ static void push_local_name (tree); static tree grok_reference_init (tree, tree, tree, tree *); static tree grokfndecl (tree, tree, tree, tree, tree, int, enum overload_flags, cp_cv_quals, - tree, int, int, int, int, int, int, tree); + tree, int, int, int, int, int, int, tree, + tree *); static tree grokvardecl (tree, tree, const cp_decl_specifier_seq *, int, int, tree); static void record_unknown_type (tree, const char *); @@ -5534,7 +5535,8 @@ grokfndecl (tree ctype, int inlinep, int funcdef_flag, int template_count, - tree in_namespace) + tree in_namespace, + tree* attrlist) { tree decl; int staticp = ctype && TREE_CODE (type) == FUNCTION_TYPE; @@ -5752,6 +5754,12 @@ grokfndecl (tree ctype, if (decl == error_mark_node) return NULL_TREE; + if (attrlist) + { + cplus_decl_attributes (&decl, *attrlist, 0); + *attrlist = NULL_TREE; + } + if (ctype != NULL_TREE && (! TYPE_FOR_JAVA (ctype) || check_java_method (decl)) && check) @@ -5762,7 +5770,7 @@ grokfndecl (tree ctype, (processing_template_decl > template_class_depth (ctype)) ? current_template_parms - : NULL_TREE); + : NULL_TREE); if (old_decl && TREE_CODE (old_decl) == TEMPLATE_DECL) /* Because grokfndecl is always supposed to return a @@ -7839,7 +7847,7 @@ grokdeclarator (const cp_declarator *declarator, unqualified_id, virtualp, flags, quals, raises, friendp ? -1 : 0, friendp, publicp, inlinep, - funcdef_flag, template_count, in_namespace); + funcdef_flag, template_count, in_namespace, attrlist); if (decl == NULL_TREE) return decl; #if 0 @@ -7886,7 +7894,7 @@ grokdeclarator (const cp_declarator *declarator, unqualified_id, virtualp, flags, quals, raises, friendp ? -1 : 0, friendp, 1, 0, funcdef_flag, - template_count, in_namespace); + template_count, in_namespace, attrlist); if (decl == NULL_TREE) return NULL_TREE; } @@ -8070,7 +8078,7 @@ grokdeclarator (const cp_declarator *declarator, virtualp, flags, quals, raises, 1, friendp, publicp, inlinep, funcdef_flag, - template_count, in_namespace); + template_count, in_namespace, attrlist); if (decl == NULL_TREE) return NULL_TREE; @@ -10088,8 +10096,6 @@ start_function (cp_decl_specifier_seq *declspecs, 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); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 05d5b6d5c66..db779a201b9 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -7441,6 +7441,7 @@ cp_parser_conversion_type_id (cp_parser* parser) tree attributes; cp_decl_specifier_seq type_specifiers; cp_declarator *declarator; + tree type_specified; /* Parse the attributes. */ attributes = cp_parser_attributes_opt (parser); @@ -7452,8 +7453,11 @@ cp_parser_conversion_type_id (cp_parser* parser) /* Parse the conversion-declarator. */ declarator = cp_parser_conversion_declarator_opt (parser); - return grokdeclarator (declarator, &type_specifiers, TYPENAME, - /*initialized=*/0, &attributes); + type_specified = grokdeclarator (declarator, &type_specifiers, TYPENAME, + /*initialized=*/0, &attributes); + if (attributes) + cplus_decl_attributes (&type_specified, attributes, /*flags=*/0); + return type_specified; } /* Parse an (optional) conversion-declarator. diff --git a/gcc/testsuite/g++.dg/ext/attribute-test-1.C b/gcc/testsuite/g++.dg/ext/attribute-test-1.C new file mode 100644 index 00000000000..2b852db57e5 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attribute-test-1.C @@ -0,0 +1,36 @@ +// { dg-do run } +// PR c++/13989 + +extern "C" void abort(); + +#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(); +} + +union u { + unsigned int f[4]; + vector unsigned int v; +} data; + +int main() +{ + Constants c; + data.v = const_deadbeef(c); + + if (data.f[0] != 0xdeadbeef || data.f[1] != 0xabababab + || data.f[2] != 0x55555555 || data.f[3] != 0x12345678) + abort(); + + return 0; +} + + diff --git a/gcc/testsuite/g++.dg/ext/attribute-test-2.C b/gcc/testsuite/g++.dg/ext/attribute-test-2.C new file mode 100644 index 00000000000..95a287e7ca8 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attribute-test-2.C @@ -0,0 +1,47 @@ +// { dg-do run } +// PR c++/9844 + +extern "C" void abort(); + +#define vector __attribute__((vector_size(16))) + +class vector_holder +{ + char __attribute__((vector_size(16))) vec; + char __attribute__((vector_size(16))) vec1; +public: + operator __attribute__((vector_size(16))) short (void) { + return (__attribute__((vector_size(16))) short) vec; + } + + operator __attribute__((vector_size(16))) int (void) { + return (__attribute__((vector_size(16))) int) vec1; + } + + vector_holder () { + vec = (__attribute__((vector_size(16))) char) {'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd', + 'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd'}; + vec1 = (__attribute__((vector_size(16))) char) {'m', 'n', 'o', 'q', 'm', 'n', 'o', 'p', + 'm', 'n', 'o', 'q', 'm', 'n', 'o', 'p'}; + } +}; + +union u { + char f[16]; + vector unsigned int v; +} data; + + +vector_holder vh; + +int main() +{ + data.v = (__attribute__((vector_size(16))) short) vh; + if (data.f[0] != 'a' || data.f[15] != 'd') + abort(); + data.v = (__attribute__((vector_size(16))) int) vh; + if (data.f[0] != 'm' || data.f[15] != 'p') + abort(); + + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/attribute-test-3.C b/gcc/testsuite/g++.dg/ext/attribute-test-3.C new file mode 100644 index 00000000000..76045f7f845 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attribute-test-3.C @@ -0,0 +1,55 @@ +// { dg-do run } + +#define vector __attribute__((vector_size(16))) + +extern "C" void abort(); + +class Star +{ + public: + inline vector float foo() const; + + Star() + { + data.f[0] = 1.0; data.f[1] = 2.0; data.f[2] = 3.0, data.f[3] = 4.0; + } + + private: + union { + float f[4]; + vector float v; + } data; + + friend vector float fTest(const Star &); +}; + +vector float Star::foo() const +{ + return data.v; +} + +vector float fTest(const Star & val) +{ + vector float vf = val.foo(); + return vf; +} + +int main() { + + Star s; + + union u { + float f[4]; + vector float v; + } data; + + data.v = fTest(s); + for (int i=0 ; i < 4; i++) + if (data.f[i] != (float)(i+1)) + abort(); + return 0; +} + + + + diff --git a/gcc/testsuite/g++.dg/ext/attribute-test-4.C b/gcc/testsuite/g++.dg/ext/attribute-test-4.C new file mode 100644 index 00000000000..d06365ca8f8 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attribute-test-4.C @@ -0,0 +1,48 @@ +// { dg-do run } + +#define vector __attribute__((vector_size(16))) + +extern "C" void abort(); + +union U { + float f[4]; + vector float v; +} data; + +class Star +{ + public: + static vector float foo(); + + Star() + { + data.f[0] = 1.0; data.f[1] = 2.0; data.f[2] = 3.0, data.f[3] = 4.0; + } + + private: + friend vector float fTest(); +}; + +vector float Star::foo() +{ + return data.v; +} + +vector float fTest() +{ + vector float vf = Star::foo(); + return vf; +} + +int main() { + + U data; + Star s; + + + data.v = fTest(); + for (int i=0 ; i < 4; i++) + if (data.f[i] != (float)(i+1)) + abort(); + return 0; +} diff --git a/gcc/tree.c b/gcc/tree.c index a0cb800470f..0237d072271 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -5642,10 +5642,15 @@ reconstruct_complex_type (tree type, tree bottom) } else if (TREE_CODE (type) == METHOD_TYPE) { + tree argtypes; inner = reconstruct_complex_type (TREE_TYPE (type), bottom); + /* The build_method_type_directly() routine prepends 'this' to argument list, + so we must compensate by getting rid of it. */ + argtypes = TYPE_ARG_TYPES (type); outer = build_method_type_directly (TYPE_METHOD_BASETYPE (type), inner, TYPE_ARG_TYPES (type)); + TYPE_ARG_TYPES (outer) = argtypes; } else return bottom;