OSDN Git Service

PR c++/9844, PR c++/13989
authorfjahanian <fjahanian@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 23 Sep 2004 18:22:25 +0000 (18:22 +0000)
committerfjahanian <fjahanian@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 23 Sep 2004 18:22:25 +0000 (18:22 +0000)
Reviewed by Mark Mitchel.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@87971 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/rs6000/rs6000.c
gcc/cp/cvt.c
gcc/cp/decl.c
gcc/cp/parser.c
gcc/testsuite/g++.dg/ext/attribute-test-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/attribute-test-2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/attribute-test-3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/attribute-test-4.C [new file with mode: 0644]
gcc/tree.c

index 3c44c68..b54874f 100644 (file)
@@ -1,3 +1,18 @@
+2004-09-21 Fariborz Jahanian <fjahanian@apple.com>
+       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  <jsm@polyomino.org.uk>
 
        PR c/16833
index 7f448ee..39ace23 100644 (file)
@@ -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;
index cb179d5..5db4146 100644 (file)
@@ -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)))
index 30bfa8b..b3cdd69 100644 (file)
@@ -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);
index 05d5b6d..db779a2 100644 (file)
@@ -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 (file)
index 0000000..2b852db
--- /dev/null
@@ -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 (file)
index 0000000..95a287e
--- /dev/null
@@ -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 (file)
index 0000000..76045f7
--- /dev/null
@@ -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 (file)
index 0000000..d06365c
--- /dev/null
@@ -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;
+}
index a0cb800..0237d07 100644 (file)
@@ -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;