summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0352-PR-c-48424.patch
blob: 0ae608ba4ae2091c8c74d972700aefa639acaec9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
From 1d07ea72697228c40996bb2e61c7b5b8ed38dc36 Mon Sep 17 00:00:00 2001
From: jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Thu, 26 May 2011 13:44:20 +0000
Subject: [PATCH] 	PR c++/48424
 	* decl.c (grokparms): Function parameter packs don't need to
 	go at the end.
 	* pt.c (type_unification_real): But they aren't deduced otherwise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch@174287 138bc75d-0d04-0410-961f-82ee72b054a4

index b3de096..dac87dd 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -10358,12 +10358,6 @@ grokparms (tree parmlist, tree *parms)
 	    init = check_default_argument (decl, init);
 	}
 
-      if (TREE_CODE (decl) == PARM_DECL
-          && FUNCTION_PARAMETER_PACK_P (decl)
-          && TREE_CHAIN (parm)
-          && TREE_CHAIN (parm) != void_list_node)
-        error ("parameter packs must be at the end of the parameter list");
-
       DECL_CHAIN (decl) = decls;
       decls = decl;
       result = tree_cons (init, type, result);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 7c71092..f648511 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -14039,11 +14039,24 @@ type_unification_real (tree tparms,
   while (parms && parms != void_list_node
 	 && ia < nargs)
     {
-      if (TREE_CODE (TREE_VALUE (parms)) == TYPE_PACK_EXPANSION)
-        break;
-
       parm = TREE_VALUE (parms);
+
+      if (TREE_CODE (parm) == TYPE_PACK_EXPANSION
+	  && (!TREE_CHAIN (parms) || TREE_CHAIN (parms) == void_list_node))
+	/* For a function parameter pack that occurs at the end of the
+	   parameter-declaration-list, the type A of each remaining
+	   argument of the call is compared with the type P of the
+	   declarator-id of the function parameter pack.  */
+	break;
+
       parms = TREE_CHAIN (parms);
+
+      if (TREE_CODE (parm) == TYPE_PACK_EXPANSION)
+	/* For a function parameter pack that does not occur at the
+	   end of the parameter-declaration-list, the type of the
+	   parameter pack is a non-deduced context.  */
+	continue;
+
       arg = args[ia];
       ++ia;
       arg_expr = NULL;
new file mode 100644
index 0000000..378162e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic111.C
@@ -0,0 +1,19 @@
+// PR c++/48424
+// { dg-options -std=c++0x }
+
+template<typename... Args1>
+struct S
+{
+  template<typename... Args2>
+    void f(Args1... args1, Args2&&... args2)
+    {
+    }
+};
+
+int main()
+{
+  S<int, double> s;
+  s.f(1,2.0,false,'a');
+}
+
+// { dg-final { scan-assembler "_ZN1SIIidEE1fIIbcEEEvidDpOT_" } }
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic41.C b/gcc/testsuite/g++.dg/cpp0x/variadic41.C
index d209766..9cfd847 100644
--- a/gcc/testsuite/g++.dg/cpp0x/variadic41.C
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic41.C
@@ -1,3 +1,14 @@
+// A function parameter pack is only deduced if it's at the end
 // { dg-options "-std=gnu++0x" }
 template<typename... Args>
-void f(const Args&... args, int oops); // { dg-error "end" }
+void f(const Args&... args, int oops);
+
+int main()
+{
+  f<>(1);
+  f(1);
+  f<int>(1,2);
+  f(1,2);			// { dg-error "no match" }
+}
+
+// { dg-prune-output "note" }
-- 
1.7.0.4