public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* 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).