Patchwork C++ PATCH for c++/55564 (ICE with decltype of non-type template parameter)

login
register
mail settings
Submitter Jason Merrill
Date Dec. 6, 2012, 2:16 p.m.
Message ID <50C0A8C7.9000201@redhat.com>
Download mbox | patch
Permalink /patch/204239/
State New
Headers show

Comments

Jason Merrill - Dec. 6, 2012, 2:16 p.m.
In this PR the problem was that during deduction for the T(&)[N] 
function parameter we were trying to deduce the array bounds N first, 
but the type of N depends on T, so we need to deduce T first.  This also 
makes sense from a left-to-right perspective.  This broke with my 
instantiation-dependence patch because decltype(sizeof(T)) was 
previously folded to size_t, whereas now it is left alone because it is 
instantiation-dependent; if T is void, the result is an error rather 
than size_t.

Tested x86_64-pc-linux-gnu, applying to trunk.

Patch

commit 7500f9612ecc0799c72f61a11a213f969e42b17b
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Dec 5 11:32:46 2012 -0500

    	PR c++/55564
    	* pt.c (unify) [ARRAY_TYPE]: Unify the element type before the bounds.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index e349be6..27084a2 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -16593,6 +16593,8 @@  unify (tree tparms, tree targs, tree parm, tree arg, int strict,
       if ((TYPE_DOMAIN (parm) == NULL_TREE)
 	  != (TYPE_DOMAIN (arg) == NULL_TREE))
 	return unify_type_mismatch (explain_p, parm, arg);
+      RECUR_AND_CHECK_FAILURE (tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg),
+			       strict & UNIFY_ALLOW_MORE_CV_QUAL, explain_p);
       if (TYPE_DOMAIN (parm) != NULL_TREE)
 	{
 	  tree parm_max;
@@ -16651,8 +16653,7 @@  unify (tree tparms, tree targs, tree parm, tree arg, int strict,
 	  RECUR_AND_CHECK_FAILURE (tparms, targs, parm_max, arg_max,
 				   UNIFY_ALLOW_INTEGER, explain_p);
 	}
-      return unify (tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg),
-		    strict & UNIFY_ALLOW_MORE_CV_QUAL, explain_p);
+      return unify_success (explain_p);
 
     case REAL_TYPE:
     case COMPLEX_TYPE:
diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype47.C b/gcc/testsuite/g++.dg/cpp0x/decltype47.C
new file mode 100644
index 0000000..8e2abaa
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/decltype47.C
@@ -0,0 +1,12 @@ 
+// PR c++/55564
+// { dg-options -std=c++11 }
+
+template <typename T, decltype(sizeof(T)) N>
+auto array_size(T(&)[N]) -> decltype(N) { return N; }
+
+int main() {
+  int simple[4] = {};
+  int result =  array_size(simple);
+
+  return result;
+}