aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2018-06-06 17:51:19 +0000
committerMarek Polacek <mpolacek@gcc.gnu.org>2018-06-06 17:51:19 +0000
commite58c9d921da423712db8369e8bb69d4ae992e94d (patch)
tree35d098db01a750035183720b183fbfd6b7b9d242
parentb66ec0c0324bb43f1fe462e7dc21fc14073d69e6 (diff)
downloadgcc-e58c9d921da423712db8369e8bb69d4ae992e94d.zip
gcc-e58c9d921da423712db8369e8bb69d4ae992e94d.tar.gz
gcc-e58c9d921da423712db8369e8bb69d4ae992e94d.tar.bz2
re PR c++/85977 (Incorrect handling of array reference size deduction)
PR c++/85977 * pt.c (unify): If ELTTYPE has no deducible template parms, skip deduction from the list elements. (type_unification_real): Check convertibility of list elements. * g++.dg/cpp0x/initlist102.C: New test. * g++.dg/cpp0x/initlist103.C: New test. * g++.dg/cpp0x/initlist104.C: New test. From-SVN: r261241
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/pt.c54
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist102.C39
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist103.C11
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist104.C11
6 files changed, 113 insertions, 16 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index f03c9df..68df054 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2018-06-06 Marek Polacek <polacek@redhat.com>
+
+ PR c++/85977
+ * pt.c (unify): If ELTTYPE has no deducible template parms, skip
+ deduction from the list elements.
+ (type_unification_real): Check convertibility of list elements.
+
2018-06-06 Jason Merrill <jason@redhat.com>
PR c++/86060 - ICE on range for with -std=c++98.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 448cd69..d8880eb 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -20370,6 +20370,22 @@ type_unification_real (tree tparms,
if (check_non_deducible_conversion (parm, arg, strict, flags,
explain_p))
return 1;
+
+ if (BRACE_ENCLOSED_INITIALIZER_P (arg)
+ && (TREE_CODE (parm) == ARRAY_TYPE || is_std_init_list (parm)))
+ {
+ tree elt, elttype;
+ unsigned int i;
+
+ if (TREE_CODE (parm) == ARRAY_TYPE)
+ elttype = TREE_TYPE (parm);
+ else
+ elttype = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (parm), 0);
+ FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (arg), i, elt)
+ if (check_non_deducible_conversion (elttype, elt, strict,
+ flags, explain_p))
+ return 1;
+ }
}
/* Now substitute into the default template arguments. */
@@ -21404,24 +21420,30 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
return unify_success (explain_p);
}
- FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (arg), i, elt)
- {
- int elt_strict = strict;
+ if (strict != DEDUCE_EXACT
+ && TYPE_P (elttype)
+ && !uses_deducible_template_parms (elttype))
+ /* If ELTTYPE has no deducible template parms, skip deduction from
+ the list elements. */;
+ else
+ FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (arg), i, elt)
+ {
+ int elt_strict = strict;
- if (elt == error_mark_node)
- return unify_invalid (explain_p);
+ if (elt == error_mark_node)
+ return unify_invalid (explain_p);
- if (!BRACE_ENCLOSED_INITIALIZER_P (elt))
- {
- tree type = TREE_TYPE (elt);
- if (type == error_mark_node)
- return unify_invalid (explain_p);
- /* It should only be possible to get here for a call. */
- gcc_assert (elt_strict & UNIFY_ALLOW_OUTER_LEVEL);
- elt_strict |= maybe_adjust_types_for_deduction
- (DEDUCE_CALL, &elttype, &type, elt);
- elt = type;
- }
+ if (!BRACE_ENCLOSED_INITIALIZER_P (elt))
+ {
+ tree type = TREE_TYPE (elt);
+ if (type == error_mark_node)
+ return unify_invalid (explain_p);
+ /* It should only be possible to get here for a call. */
+ gcc_assert (elt_strict & UNIFY_ALLOW_OUTER_LEVEL);
+ elt_strict |= maybe_adjust_types_for_deduction
+ (DEDUCE_CALL, &elttype, &type, elt);
+ elt = type;
+ }
RECUR_AND_CHECK_FAILURE (tparms, targs, elttype, elt, elt_strict,
explain_p);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f63c9d7..14f575e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2018-06-06 Marek Polacek <polacek@redhat.com>
+
+ PR c++/85977
+ * g++.dg/cpp0x/initlist102.C: New test.
+ * g++.dg/cpp0x/initlist103.C: New test.
+ * g++.dg/cpp0x/initlist104.C: New test.
+
2018-06-06 Eric Botcazou <ebotcazou@adacore.com>
* gcc.dg/torture/pr86066.c: New test.
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist102.C b/gcc/testsuite/g++.dg/cpp0x/initlist102.C
new file mode 100644
index 0000000..e114866
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist102.C
@@ -0,0 +1,39 @@
+// PR c++/85977, Incorrect handling of array reference size deduction
+// { dg-do compile { target c++11 } }
+
+template <int N>
+void fn1 (const char (&)[N]) { static_assert (N == 3, "fn1");}
+
+template <int N>
+void fn2 (const short (&)[N]) { static_assert (N == 3, "fn2");}
+
+template <int N>
+void fn3 (const int (&)[N]) { static_assert (N == 3, "fn2");}
+
+template <int N>
+void fn4 (const long (&)[N]) { static_assert (N == 3, "fn4");}
+
+template <int N>
+void fn5 (const unsigned char (&)[N]) { static_assert (N == 3, "fn5");}
+
+template <int N>
+void fn6 (const unsigned short (&)[N]) { static_assert (N == 3, "fn6");}
+
+template <int N>
+void fn7 (const unsigned int (&)[N]) { static_assert (N == 3, "fn7");}
+
+template <int N>
+void fn8 (const unsigned int (&)[N]) { static_assert (N == 3, "fn8");}
+
+void
+bar ()
+{
+ fn1 ({1, 2, 3});
+ fn2 ({1, 2, 3});
+ fn3 ({1, 2, 3});
+ fn4 ({1, 2, 3});
+ fn5 ({1, 2, 3});
+ fn6 ({1, 2, 3});
+ fn7 ({1, 2, 3});
+ fn8 ({1, 2, 3});
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist103.C b/gcc/testsuite/g++.dg/cpp0x/initlist103.C
new file mode 100644
index 0000000..0c1923c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist103.C
@@ -0,0 +1,11 @@
+// PR c++/85977, Incorrect handling of array reference size deduction
+// { dg-do compile { target c++11 } }
+
+template <int N>
+void fn (const char (&)[N]) { }
+
+void
+bar ()
+{
+ fn ({1.2}); // { dg-error "narrowing" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist104.C b/gcc/testsuite/g++.dg/cpp0x/initlist104.C
new file mode 100644
index 0000000..99487a7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist104.C
@@ -0,0 +1,11 @@
+// PR c++/85977, Incorrect handling of array reference size deduction
+// { dg-do compile { target c++11 } }
+
+template <typename T, int N>
+void fn (const T (&)[N]) { static_assert (N == 3, "fn"); }
+
+void
+bar ()
+{
+ fn ({1, 2, 3});
+}