This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH for c++/42277 (error on decltype of member access in template)
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 04 Dec 2009 17:50:54 -0500
- Subject: C++ PATCH for c++/42277 (error on decltype of member access in template)
The issue here is that within a template, even if a COMPONENT_REF is
non-dependent, we leave its second operand as an IDENTIFIER_NODE so that
we look it up again at instantiation time and get any access control
errors at that point (in case the particular instantiation has more
access than the template). So we need to defer decltype handling until
that point as well.
Tested x86_64-pc-linux-gnu, applied to trunk.
commit 4440ad5dc914322505ba4224f8fe2b4eb0956266
Author: Jason Merrill <jason@redhat.com>
Date: Fri Dec 4 16:10:32 2009 -0500
PR c++/42277
* semantics.c (finish_decltype_type): Don't assume that op1 of a
COMPONENT_REF is always the field.
* g++.dg/cpp0x/decltype20.C: New.
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 4c36280..841efc8 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -4777,7 +4777,13 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
return error_mark_node;
}
- if (type_dependent_expression_p (expr))
+ if (type_dependent_expression_p (expr)
+ /* In a template, a COMPONENT_REF has an IDENTIFIER_NODE for op1 even
+ if it isn't dependent, so that we can check access control at
+ instantiation time, so defer the decltype as well (PR 42277). */
+ || (id_expression_or_member_access_p
+ && processing_template_decl
+ && TREE_CODE (expr) == COMPONENT_REF))
{
if (id_expression_or_member_access_p)
{
diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype20.C b/gcc/testsuite/g++.dg/cpp0x/decltype20.C
new file mode 100644
index 0000000..3155cdc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/decltype20.C
@@ -0,0 +1,10 @@
+// PR c++/42277
+// { dg-options -std=c++0x }
+
+struct S { int s; };
+template <int N>
+void foo ()
+{
+ S s;
+ decltype (s.s) i;
+}