diff mbox

RFC: C++0x ABI PATCH to decltype handling

Message ID 4D64677A.5020105@redhat.com
State New
Headers show

Commit Message

Jason Merrill Feb. 23, 2011, 1:48 a.m. UTC
Discussion on the ABI mailing list eventually came to the conclusion 
that my attempts to define a subset of decltypes that can be folded away 
was misguided, and we should just directly mangle all dependent 
decltypes.  The consequence of this is that we can't fold them away 
internally either.

I don't think the ABI breakage will be that significant, since it only 
applies to situations where there's no real reason to use decltype in 
the first place.  And it only applies to C++0x code, which is still in flux.

Any comments?

Tested x86_64-pc-linux-gnu.
commit bccfc8f2ec33b0576c94408f2d9ba68829bda147
Author: Jason Merrill <jason@redhat.com>
Date:   Mon Feb 21 21:42:29 2011 -0500

    	* semantics.c (finish_decltype_type): Remove shortcut for decltype
    	of id-expression.

Comments

Mark Mitchell Feb. 23, 2011, 2:42 a.m. UTC | #1
On 2/22/2011 5:48 PM, Jason Merrill wrote:

> Discussion on the ABI mailing list eventually came to the conclusion
> that my attempts to define a subset of decltypes that can be folded away
> was misguided, and we should just directly mangle all dependent
> decltypes.  The consequence of this is that we can't fold them away
> internally either.

> Any comments?

I hate breaking backwards compatibility, but even I find it hard to
argue against this change.  In general, I think that requiring lexical
(rather than semantic) equivalence between template declarations and
definitions makes a ton of sense, and I do agree that there's probably
very little code out there that's depending on the old behavior.

Maybe we ought to decide that -fcxa-abi=latest (sp?) is the default, and
that immediately after each release we bump the version, so that every
compiler has a new version number, and users can always go backwards if
they really care?  (I know that EDG has done something similar to that.)

Thank you,
diff mbox

Patch

diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 6a9c6a0..b070d0a 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -4772,6 +4772,7 @@  finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
       return error_mark_node;
     }
 
+  /* FIXME instantiation-dependent  */
   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
@@ -4780,27 +4781,6 @@  finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
 	  && processing_template_decl
 	  && TREE_CODE (expr) == COMPONENT_REF))
     {
-      if (id_expression_or_member_access_p)
-	{
-	  switch (TREE_CODE (expr))
-	    {
-	    case VAR_DECL:
-	    case PARM_DECL:
-	    case RESULT_DECL:
-	    case FUNCTION_DECL:
-	    case CONST_DECL:
-	    case TEMPLATE_PARM_INDEX:
-	      type = TREE_TYPE (expr);
-	      break;
-
-	    default:
-	      break;
-	    }
-	}
-
-      if (type && !type_uses_auto (type))
-	return type;
-
     treat_as_dependent:
       type = cxx_make_type (DECLTYPE_TYPE);
       DECLTYPE_TYPE_EXPR (type) = expr;
diff --git a/gcc/testsuite/g++.dg/cpp0x/trailing1.C b/gcc/testsuite/g++.dg/cpp0x/trailing1.C
index 11e73d2..fcf65e3 100644
--- a/gcc/testsuite/g++.dg/cpp0x/trailing1.C
+++ b/gcc/testsuite/g++.dg/cpp0x/trailing1.C
@@ -78,7 +78,6 @@  auto k(T t, U u, V v) -> decltype (t.U::template B<V>::MEM)
   return t.U::template B<V>::MEM;
 }
 
-// For these two examples we can elide the 'decltype' and just mangle the type.
 template <class T>
 auto l(T t) -> decltype (t)
 {
@@ -111,8 +110,8 @@  int main()
   h(a,1.0);
   // { dg-final { scan-assembler "_Z1kI1C1AIiE1DEDtdtfp_srNT0_1BIT1_EE3MEMET_S4_S6_" } }
   k( C(), A<int>(), D() );
-  // { dg-final { scan-assembler "_Z1lIiET_S0_" } }
+  // { dg-final { scan-assembler "_Z1lIiEDtfp_ET_" } }
   l(1);
-  // { dg-final { scan-assembler "_Z1mIiLi1EET_S0_" } }
+  // { dg-final { scan-assembler "_Z1mIiLi1EEDtT0_ET_" } }
   m<int,1>(1);
 }
diff --git a/gcc/testsuite/g++.dg/template/canon-type-12.C b/gcc/testsuite/g++.dg/template/canon-type-12.C
index 694cc5e..08c86f0 100644
--- a/gcc/testsuite/g++.dg/template/canon-type-12.C
+++ b/gcc/testsuite/g++.dg/template/canon-type-12.C
@@ -9,7 +9,7 @@  struct S
 
 template<class T, T t>
 void
-S<T, t>::foo(T)
+S<T, t>::foo(decltype(t))
 {
 }
 
diff --git a/gcc/testsuite/g++.dg/template/canon-type-9.C b/gcc/testsuite/g++.dg/template/canon-type-9.C
index de6170e..cb4ad89 100644
--- a/gcc/testsuite/g++.dg/template/canon-type-9.C
+++ b/gcc/testsuite/g++.dg/template/canon-type-9.C
@@ -11,7 +11,7 @@  struct S
 };
 
 template<class T, T *u>
-T* S<T, u>::foo(T)
+decltype(u) S<T, u>::foo(T)
 {
   T t;
   return t;