PR c++/68703 - bogus error with dependent vector length
authorJason Merrill <jason@redhat.com>
Tue, 9 Aug 2016 22:03:07 +0000 (18:03 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 9 Aug 2016 22:03:07 +0000 (18:03 -0400)
gcc/c-family/
* c-common.c (c_common_attribute_table): vector_size affects type
identity.
gcc/cp/
* decl2.c (any_dependent_type_attributes_p): New.
* pt.c (dependent_type_p_r, type_dependent_expression_p): Check it.
* semantics.c (finish_id_expression): Check it.
* typeck.c (finish_class_member_access_expr): Check it.

From-SVN: r239309

gcc/c-family/ChangeLog
gcc/c-family/c-common.c
gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl2.c
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/cp/typeck.c
gcc/testsuite/g++.dg/ext/vector32.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/vector32a.C [new file with mode: 0644]

index a1dbc735c50b41fad81988453dc41a29ab34571c..def4e11401f7c058ccdff8138a465e8c0cd7aaf8 100644 (file)
@@ -1,3 +1,8 @@
+2016-08-09  Jason Merrill  <jason@redhat.com>
+
+       * c-common.c (c_common_attribute_table): vector_size affects type
+       identity.
+
 2016-08-09  Marek Polacek  <polacek@redhat.com>
 
        PR c/7652
index 569f000150f277b2356318ac199ad7a2769578a2..7fd84eebc44ee6820c0a30f92a6f10d43a85660e 100644 (file)
@@ -754,7 +754,7 @@ const struct attribute_spec c_common_attribute_table[] =
   { "deprecated",             0, 1, false, false, false,
                              handle_deprecated_attribute, false },
   { "vector_size",           1, 1, false, true, false,
-                             handle_vector_size_attribute, false },
+                             handle_vector_size_attribute, true },
   { "visibility",            1, 1, false, false, false,
                              handle_visibility_attribute, false },
   { "tls_model",             1, 1, true,  false, false,
index c71ea1703c87eae2309b7e8fc3313f3ba0916bcc..ca04d6438a486255fbe00504e6f91753ff570b15 100644 (file)
@@ -1,5 +1,11 @@
 2016-08-09  Jason Merrill  <jason@redhat.com>
 
+       PR c++/68703
+       * decl2.c (any_dependent_type_attributes_p): New.
+       * pt.c (dependent_type_p_r, type_dependent_expression_p): Check it.
+       * semantics.c (finish_id_expression): Check it.
+       * typeck.c (finish_class_member_access_expr): Check it.
+
        PR c++/71712
        * class.c (check_abi_tags): Don't duplicate tags for conversion ops.
 
index f32613c05b700822215c6935b50b95bab8258766..f98b1c4d50304897ddfb45248960b414506cbbda 100644 (file)
@@ -5852,6 +5852,7 @@ extern tree grokfield (const cp_declarator *, cp_decl_specifier_seq *,
                       tree, bool, tree, tree);
 extern tree grokbitfield (const cp_declarator *, cp_decl_specifier_seq *,
                          tree, tree);
+extern bool any_dependent_type_attributes_p    (tree);
 extern tree cp_reconstruct_complex_type                (tree, tree);
 extern bool attributes_naming_typedef_ok       (tree);
 extern void cplus_decl_attributes              (tree *, tree, int);
index 1daa9f525d6acfc59c9951bbebb8c8824244b6b2..55bb987ebbe643e7f3d933fc9775b8f48a6c24b2 100644 (file)
@@ -1305,6 +1305,22 @@ save_template_attributes (tree *attr_p, tree *decl_p)
     }
 }
 
+/* True if ATTRS contains any dependent attributes that affect type
+   identity.  */
+
+bool
+any_dependent_type_attributes_p (tree attrs)
+{
+  for (tree a = attrs; a; a = TREE_CHAIN (a))
+    if (ATTR_IS_DEPENDENT (a))
+      {
+       const attribute_spec *as = lookup_attribute_spec (TREE_PURPOSE (a));
+       if (as && as->affects_type_identity)
+         return true;
+      }
+  return false;
+}
+
 /* Return true iff ATTRS are acceptable attributes to be applied in-place
    to a typedef which gives a previously unnamed class or enum a name for
    linkage purposes.  */
index 38840827ee7024cd5da99528303c825765292cb6..2638564612d73245730f2927419729b940c2eb7e 100644 (file)
@@ -22673,6 +22673,9 @@ dependent_type_p_r (tree type)
   if (TREE_CODE (type) == TYPE_PACK_EXPANSION)
     return true;
 
+  if (any_dependent_type_attributes_p (TYPE_ATTRIBUTES (type)))
+    return true;
+
   /* The standard does not specifically mention types that are local
      to template functions or local classes, but they should be
      considered dependent too.  For example:
@@ -23225,6 +23228,12 @@ type_dependent_expression_p (tree expression)
 
   gcc_assert (TREE_CODE (expression) != TYPE_DECL);
 
+  /* Dependent type attributes might not have made it from the decl to
+     the type yet.  */
+  if (DECL_P (expression)
+      && any_dependent_type_attributes_p (DECL_ATTRIBUTES (expression)))
+    return true;
+
   return (dependent_type_p (TREE_TYPE (expression)));
 }
 
index 4bffe6dc8514c8c654fb913c2ab28c3fd89d4c22..bffdddbb965bf7361490d7ad85440087921b6935 100644 (file)
@@ -3548,6 +3548,12 @@ finish_id_expression (tree id_expression,
         resolve the name at instantiation time.  */
       if (dependent_p)
        {
+         if (DECL_P (decl)
+             && any_dependent_type_attributes_p (DECL_ATTRIBUTES (decl)))
+           /* Dependent type attributes on the decl mean that the TREE_TYPE is
+              wrong, so just return the identifier.  */
+           return id_expression;
+
          /* If we found a variable, then name lookup during the
             instantiation will always resolve to the same VAR_DECL
             (or an instantiation thereof).  */
index bedc453a945ca62593052be6cd3e6579f0249353..a591d291602f10a51cbfb21dacb50234d89ecd3d 100644 (file)
@@ -2853,6 +2853,11 @@ finish_class_member_access_expr (cp_expr object, tree name, bool template_p,
            }
          if (member == error_mark_node)
            return error_mark_node;
+         if (DECL_P (member)
+             && any_dependent_type_attributes_p (DECL_ATTRIBUTES (member)))
+           /* Dependent type attributes on the decl mean that the TREE_TYPE is
+              wrong, so don't use it.  */
+           goto dependent;
          if (TREE_CODE (member) == USING_DECL && DECL_DEPENDENT_P (member))
            goto dependent;
        }
diff --git a/gcc/testsuite/g++.dg/ext/vector32.C b/gcc/testsuite/g++.dg/ext/vector32.C
new file mode 100644 (file)
index 0000000..8901d0b
--- /dev/null
@@ -0,0 +1,18 @@
+// PR c++/68703
+
+template <int N>
+struct D {
+  int v __attribute__((vector_size (N * sizeof (int))));
+  int f1 () { return this->v[N-1]; }
+  int f2 () { return v[N-1]; }
+};
+
+int
+main ()
+{
+  D<4> a = { { 0, 1, 2, 3 } };
+  D<8> b = { { 0, 1, 2, 3, 4, 5, 6, 7 } };
+  if (a.f1 () != 3 || a.f2 () != 3
+      || b.f1 () != 7 || b.f2 () != 7)
+    __builtin_abort ();
+}
diff --git a/gcc/testsuite/g++.dg/ext/vector32a.C b/gcc/testsuite/g++.dg/ext/vector32a.C
new file mode 100644 (file)
index 0000000..8901d0b
--- /dev/null
@@ -0,0 +1,18 @@
+// PR c++/68703
+
+template <int N>
+struct D {
+  int v __attribute__((vector_size (N * sizeof (int))));
+  int f1 () { return this->v[N-1]; }
+  int f2 () { return v[N-1]; }
+};
+
+int
+main ()
+{
+  D<4> a = { { 0, 1, 2, 3 } };
+  D<8> b = { { 0, 1, 2, 3, 4, 5, 6, 7 } };
+  if (a.f1 () != 3 || a.f2 () != 3
+      || b.f1 () != 7 || b.f2 () != 7)
+    __builtin_abort ();
+}