diff options
author | Jason Merrill <jason@redhat.com> | 2018-02-09 14:10:42 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2018-02-09 14:10:42 -0500 |
commit | dd2799cc2212a72a1b31828918f9bb9287ab9780 (patch) | |
tree | ae21c88b70f99da0013ad2fd18c0a4282796fa0b | |
parent | 8c67920556efc5fa97c2080098c202e75b93e2a0 (diff) | |
download | gcc-dd2799cc2212a72a1b31828918f9bb9287ab9780.zip gcc-dd2799cc2212a72a1b31828918f9bb9287ab9780.tar.gz gcc-dd2799cc2212a72a1b31828918f9bb9287ab9780.tar.bz2 |
PR c++/84296 - ICE with qualified-id in template.
PR c++/83714
* pt.c (unknown_base_ref_p): New.
(instantiation_dependent_scope_ref_p): Use it instead of
any_dependent_bases_p.
From-SVN: r257538
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/pt.c | 28 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/scope5.C | 66 |
3 files changed, 99 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ac53a74..fa66e1b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2018-02-09 Jason Merrill <jason@redhat.com> + + PR c++/84296 - ICE with qualified-id in template. + PR c++/83714 + * pt.c (unknown_base_ref_p): New. + (instantiation_dependent_scope_ref_p): Use it instead of + any_dependent_bases_p. + 2018-02-09 Marek Polacek <polacek@redhat.com> Jakub Jelinek <jakub@redhat.com> diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index a9e4770..9c57709 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -24012,6 +24012,30 @@ dependent_scope_p (tree scope) && !currently_open_class (scope)); } +/* T is a SCOPE_REF. Return whether it represents a non-static member of + an unknown base of 'this' (and is therefore instantiation-dependent). */ + +static bool +unknown_base_ref_p (tree t) +{ + if (!current_class_ptr) + return false; + + tree mem = TREE_OPERAND (t, 1); + if (shared_member_p (mem)) + return false; + + tree cur = current_nonlambda_class_type (); + if (!any_dependent_bases_p (cur)) + return false; + + tree ctx = TREE_OPERAND (t, 0); + if (DERIVED_FROM_P (ctx, cur)) + return false; + + return true; +} + /* T is a SCOPE_REF; return whether we need to consider it instantiation-dependent so that we can check access at instantiation time even though we know which member it resolves to. */ @@ -24021,9 +24045,7 @@ instantiation_dependent_scope_ref_p (tree t) { if (DECL_P (TREE_OPERAND (t, 1)) && CLASS_TYPE_P (TREE_OPERAND (t, 0)) - /* A dependent base could make a member inaccessible in the current - class. */ - && !any_dependent_bases_p () + && !unknown_base_ref_p (t) && accessible_in_template_p (TREE_OPERAND (t, 0), TREE_OPERAND (t, 1))) return false; diff --git a/gcc/testsuite/g++.dg/template/scope5.C b/gcc/testsuite/g++.dg/template/scope5.C new file mode 100644 index 0000000..629225c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/scope5.C @@ -0,0 +1,66 @@ +// PR c++/84296 + +namespace b {} +namespace c { +using namespace b; +} +namespace b { +template <int d> struct e { static const int f = d; }; +} +template <typename> struct g; +template <typename h, typename i, typename aa, typename j> +struct g<h(i, aa, j)> : h::template ab<i, aa, j> {}; +struct k { + template <typename l> struct m { typedef typename g<l>::n o; }; +}; +template <typename> struct ac; +struct r { + typedef ac<int> p; +}; +template <typename q> struct s : k { + template <typename i, typename, typename> + struct ab : q::template t<typename i::u>::template ab<i, int, int> {}; +}; +struct ad { + typedef int u; +}; +template <typename> struct ae; +template <typename, typename ag> struct ah { + typedef ae<ag> ai; + typedef typename ai::template w<ai(r, int)>::o n; +}; +struct x { + template <typename i, typename, typename> struct ab : ah<i, int> {}; +}; +struct y { + struct z { + template <typename> struct t : x {}; + }; + struct aj : s<z> {}; +}; +template <typename i> struct ak { + typedef y::aj al; + typedef typename al::m<al(i, int, int)>::o o; +}; +struct am { + enum { an }; +}; +template <typename> struct ao {}; +template <typename af> struct ap : af::aq {}; +template <> struct ae<int> { + template <typename> struct w; + template <typename ar, typename as, typename at> struct w<ar(as, at)> { + typedef typename as::p o; + }; +}; +enum { a = b::e<0>::f }; +template <typename> class au; +template <typename av> struct ac : ao<av> { typedef c::e<am::an> aq; }; +template <typename aw, typename i, typename ax> void ay(aw, i, ax) { + au<c::e<ap<typename ak<i>::o>::f> > az(); +} +void v() { + ad a; + void az(); + ay(az, a, v); +} |