* C++ PATCH for c++/52596 (C++11 ICE with qualified-id in template)
@ 2012-04-06 13:18 Jason Merrill
0 siblings, 0 replies; only message in thread
From: Jason Merrill @ 2012-04-06 13:18 UTC (permalink / raw)
To: gcc-patches List
[-- Attachment #1: Type: text/plain, Size: 1154 bytes --]
Since in C++11 the things you can do with an lvalue are no longer a
superset of the things you can do with an rvalue (specifically, you
can't bind one to an rvalue reference) we can't just conservatively
assume that an expression is an lvalue in a template and then get a
better answer later. So we've started looking into NON_DEPENDENT_EXPR
in lvalue_kind. But that breaks on this testcase; when we encounter a
qualified-id in a template we build up a SCOPE_REF for it even though we
know what it refers to so that we can do access control at instantiation
time, and lvalue_kind didn't know how to deal with that.
For 4.8 I'm fixing this by changing the second operand of the SCOPE_REF
to be the decl found by lookup, as the instantiation code already knows
what to do with that. For 4.7 I'm just conservatively assuming it's a
regular lvalue; it has to be an lvalue because it's something with a
name, and if it's a field it's a member of *this, which is an lvalue.
It might be a bit-field, but bit-field semantics are a strict subset of
normal lvalue semantics, so this is OK.
Tested x86_64-pc-linux-gnu, applying to trunk and 4.7.
[-- Attachment #2: 52596.patch --]
[-- Type: text/x-patch, Size: 2021 bytes --]
commit 8710fe66438bef24c30444eec07c7a82222d6661
Author: Jason Merrill <jason@redhat.com>
Date: Thu Apr 5 14:41:25 2012 -0400
PR c++/52596
* semantics.c (finish_non_static_data_member): In templates, pass
the decl to build_qualified_name.
* tree.c (lvalue_kind) [SCOPE_REF]: Handle FIELD_DECL.
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 65b771f..9bdd2ee 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -1590,7 +1590,7 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
else if (processing_template_decl)
return build_qualified_name (TREE_TYPE (decl),
qualifying_scope,
- DECL_NAME (decl),
+ decl,
/*template_p=*/false);
else
{
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 992c22a..b5a360f 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -151,8 +151,14 @@ lvalue_kind (const_tree ref)
/* A scope ref in a template, left as SCOPE_REF to support later
access checking. */
case SCOPE_REF:
- gcc_assert (!type_dependent_expression_p (CONST_CAST_TREE(ref)));
- return lvalue_kind (TREE_OPERAND (ref, 1));
+ gcc_assert (!type_dependent_expression_p (CONST_CAST_TREE (ref)));
+ {
+ tree op = TREE_OPERAND (ref, 1);
+ if (TREE_CODE (op) == FIELD_DECL)
+ return (DECL_C_BIT_FIELD (op) ? clk_bitfield : clk_ordinary);
+ else
+ return lvalue_kind (op);
+ }
case MAX_EXPR:
case MIN_EXPR:
diff --git a/gcc/testsuite/g++.dg/template/qualified-id5.C b/gcc/testsuite/g++.dg/template/qualified-id5.C
new file mode 100644
index 0000000..3126d33
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/qualified-id5.C
@@ -0,0 +1,17 @@
+// PR c++/52596
+
+struct msgpack_zone_finalizer_array {
+ int* tail;
+};
+struct msgpack_zone {
+ msgpack_zone_finalizer_array finalizer_array;
+};
+struct zone : public msgpack_zone {
+ template <typename T> T* allocate();
+
+};
+template <typename T>
+T* zone::allocate()
+{
+ --msgpack_zone::finalizer_array.tail;
+}
[-- Attachment #3: 52596-4.7.patch --]
[-- Type: text/x-patch, Size: 1532 bytes --]
commit 078e78553f6e1a3727dedf10ab2825c96552e86d
Author: Jason Merrill <jason@redhat.com>
Date: Thu Apr 5 14:41:25 2012 -0400
PR c++/52596
* tree.c (lvalue_kind): Treat a deferred access control SCOPE_REF
as an lvalue.
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 2bb2801..9129a7e 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -150,8 +150,14 @@ lvalue_kind (const_tree ref)
/* A scope ref in a template, left as SCOPE_REF to support later
access checking. */
case SCOPE_REF:
- gcc_assert (!type_dependent_expression_p (CONST_CAST_TREE(ref)));
- return lvalue_kind (TREE_OPERAND (ref, 1));
+ {
+ tree op = TREE_OPERAND (ref, 1);
+ /* The member must be an lvalue; assume it isn't a bit-field. */
+ if (TREE_CODE (op) == IDENTIFIER_NODE)
+ return clk_ordinary;
+ gcc_assert (!type_dependent_expression_p (CONST_CAST_TREE (ref)));
+ return lvalue_kind (op);
+ }
case MAX_EXPR:
case MIN_EXPR:
diff --git a/gcc/testsuite/g++.dg/template/qualified-id5.C b/gcc/testsuite/g++.dg/template/qualified-id5.C
new file mode 100644
index 0000000..3126d33
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/qualified-id5.C
@@ -0,0 +1,17 @@
+// PR c++/52596
+
+struct msgpack_zone_finalizer_array {
+ int* tail;
+};
+struct msgpack_zone {
+ msgpack_zone_finalizer_array finalizer_array;
+};
+struct zone : public msgpack_zone {
+ template <typename T> T* allocate();
+
+};
+template <typename T>
+T* zone::allocate()
+{
+ --msgpack_zone::finalizer_array.tail;
+}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2012-04-06 13:18 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-06 13:18 C++ PATCH for c++/52596 (C++11 ICE with qualified-id in template) Jason Merrill
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).