diff options
author | Jason Merrill <jason@redhat.com> | 2016-01-31 06:53:04 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2016-01-31 06:53:04 -0500 |
commit | 6978c505d01ec65a1465a196e35f27eb5cc79c66 (patch) | |
tree | 651eed443dd698aafb447881f43a5825ec17e9fe /gcc | |
parent | b1568582a07836b3aa1073d8f5395931061d9cf3 (diff) | |
download | gcc-6978c505d01ec65a1465a196e35f27eb5cc79c66.zip gcc-6978c505d01ec65a1465a196e35f27eb5cc79c66.tar.gz gcc-6978c505d01ec65a1465a196e35f27eb5cc79c66.tar.bz2 |
re PR c++/69009 (ICE in instantiate_decl, at cp/pt.c:21511)
PR c++/69009
* pt.c (partial_specialization_p, impartial_args): New.
(instantiate_decl): Call impartial_args.
From-SVN: r233019
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cp/pt.c | 32 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/var-templ47.C | 19 |
3 files changed, 54 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0113e5d..783fe72 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2016-01-31 Jason Merrill <jason@redhat.com> + PR c++/69009 + * pt.c (partial_specialization_p, impartial_args): New. + (instantiate_decl): Call impartial_args. + * mangle.c (maybe_check_abi_tags): New. (write_guarded_var_name): Call it. (mangle_ref_init_variable): Call check_abi_tags. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 0d0e664..27dfdf86 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -20746,6 +20746,36 @@ most_general_template (tree decl) return decl; } +/* True iff the TEMPLATE_DECL tmpl is a partial specialization. */ + +static bool +partial_specialization_p (tree tmpl) +{ + /* Any specialization has DECL_TEMPLATE_SPECIALIZATION. */ + if (!DECL_TEMPLATE_SPECIALIZATION (tmpl)) + return false; + tree t = DECL_TI_TEMPLATE (tmpl); + /* A specialization that fully specializes one of the containing classes is + not a partial specialization. */ + return (list_length (DECL_TEMPLATE_PARMS (tmpl)) + == list_length (DECL_TEMPLATE_PARMS (t))); +} + +/* If TMPL is a partial specialization, return the arguments for its primary + template. */ + +static tree +impartial_args (tree tmpl, tree args) +{ + if (!partial_specialization_p (tmpl)) + return args; + + /* If TMPL is a partial specialization, we need to substitute to get + the args for the primary template. */ + return tsubst_template_args (DECL_TI_ARGS (tmpl), args, + tf_warning_or_error, tmpl); +} + /* Return the most specialized of the template partial specializations which can produce TARGET, a specialization of some class or variable template. The value returned is actually a TREE_LIST; the TREE_VALUE is @@ -21570,7 +21600,7 @@ instantiate_decl (tree d, int defer_ok, return d; gen_tmpl = most_general_template (tmpl); - gen_args = DECL_TI_ARGS (d); + gen_args = impartial_args (tmpl, DECL_TI_ARGS (d)); if (tmpl != gen_tmpl) /* We should already have the extra args. */ diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ47.C b/gcc/testsuite/g++.dg/cpp1y/var-templ47.C new file mode 100644 index 0000000..a40ec57 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/var-templ47.C @@ -0,0 +1,19 @@ +// PR c++/69009 +// { dg-do compile { target c++14 } } + +using _uchar = char; +using _size_t = decltype(sizeof(_uchar)); +using size_t = _size_t; +template <class T, T> struct integral_constant; +template <bool b> using bool_constant = integral_constant<bool, b>; +template <class> constexpr auto tuple_size_v = 0; +template <class T> auto const tuple_size_v<T const volatile> = tuple_size_v<T>; +template <class T> +using tuple_size = integral_constant<size_t, tuple_size_v<T>>; +template <typename Base, typename Deriv> +using is_base_of = bool_constant<__is_base_of(Base, Deriv)>; +template <class T, size_t N> void test() { + is_base_of<integral_constant<size_t, N>, tuple_size<T>> value( + is_base_of<integral_constant<size_t, N>, tuple_size<const volatile T>>); +} +void foo() { test<int, 0>; } |