diff options
author | Marek Polacek <polacek@redhat.com> | 2018-06-06 17:51:19 +0000 |
---|---|---|
committer | Marek Polacek <mpolacek@gcc.gnu.org> | 2018-06-06 17:51:19 +0000 |
commit | e58c9d921da423712db8369e8bb69d4ae992e94d (patch) | |
tree | 35d098db01a750035183720b183fbfd6b7b9d242 | |
parent | b66ec0c0324bb43f1fe462e7dc21fc14073d69e6 (diff) | |
download | gcc-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/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/pt.c | 54 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/initlist102.C | 39 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/initlist103.C | 11 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/initlist104.C | 11 |
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}); +} |