aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2016-08-09 18:03:07 -0400
committerJason Merrill <jason@gcc.gnu.org>2016-08-09 18:03:07 -0400
commitf3365c1201908df5e3f929cc8fec3f4b88c126c6 (patch)
treeaff9bbf2a3b0a1784c16e435791500d42f2046d1 /gcc
parentb7597ae57977ff3d4ff359141a471acf22001f92 (diff)
downloadgcc-f3365c1201908df5e3f929cc8fec3f4b88c126c6.zip
gcc-f3365c1201908df5e3f929cc8fec3f4b88c126c6.tar.gz
gcc-f3365c1201908df5e3f929cc8fec3f4b88c126c6.tar.bz2
PR c++/68703 - bogus error with dependent vector length
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/c-family/ChangeLog5
-rw-r--r--gcc/c-family/c-common.c2
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/decl2.c16
-rw-r--r--gcc/cp/pt.c9
-rw-r--r--gcc/cp/semantics.c6
-rw-r--r--gcc/cp/typeck.c5
-rw-r--r--gcc/testsuite/g++.dg/ext/vector32.C18
-rw-r--r--gcc/testsuite/g++.dg/ext/vector32a.C18
10 files changed, 85 insertions, 1 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index a1dbc73..def4e11 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -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
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 569f000..7fd84ee 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -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,
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index c71ea17..ca04d64 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index f32613c..f98b1c4 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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);
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 1daa9f5..55bb987 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -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. */
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 3884082..2638564 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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)));
}
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 4bffe6d..bffdddb 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -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). */
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index bedc453..a591d29 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -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
index 0000000..8901d0b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/vector32.C
@@ -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
index 0000000..8901d0b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/vector32a.C
@@ -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 ();
+}