This code was first allowed by DR 850: as of C++11, in unevaluated
context it's OK to refer to a non-static data member without an
associated object. The ABI says that this is mangled like an unresolved
name, i.e. as the plain identifier.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit e6a6cf41c76af773e573c00d8e7314c1223b0cff
Author: Jason Merrill <ja...@redhat.com>
Date: Fri Sep 19 06:15:02 2014 -0400
PR c++/61392
* mangle.c (write_expression): Use unresolved-name mangling for
DR850 case.
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 5c201d6..1642da5 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -2866,11 +2866,16 @@ write_expression (tree expr)
{
write_string (operator_name_info[(int)code].mangled_name);
ob = TREE_OPERAND (ob, 0);
+ write_expression (ob);
}
- else
- write_string ("dt");
+ else if (!is_dummy_object (ob))
+ {
+ write_string ("dt");
+ write_expression (ob);
+ }
+ /* else, for a non-static data member with no associated object (in
+ unevaluated context), use the unresolved-name mangling. */
- write_expression (ob);
write_member_name (TREE_OPERAND (expr, 1));
return;
}
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index bcf161b..1d81028 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -1685,7 +1685,7 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
if (object == error_mark_node)
return error_mark_node;
- /* DR 613: Can use non-static data members without an associated
+ /* DR 613/850: Can use non-static data members without an associated
object in sizeof/decltype/alignof. */
if (is_dummy_object (object) && cp_unevaluated_operand == 0
&& (!processing_template_decl || !current_class_ref))
diff --git a/gcc/testsuite/g++.dg/abi/mangle63.C b/gcc/testsuite/g++.dg/abi/mangle63.C
new file mode 100644
index 0000000..d6a58a3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/mangle63.C
@@ -0,0 +1,11 @@
+// DR 850 makes this valid
+// { dg-do compile { target c++11 } }
+
+template<class T> struct A
+{
+ int mem;
+ template<class U> decltype(U()+mem) f();
+};
+int i = A<int>().f<int>();
+
+// { dg-final { scan-assembler "_ZN1AIiE1fIiEEDTplcvT__E3memEv" } }