From dd2799cc2212a72a1b31828918f9bb9287ab9780 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 9 Feb 2018 14:10:42 -0500 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 8 ++++ gcc/cp/pt.c | 28 +++++++++-- gcc/testsuite/g++.dg/template/scope5.C | 66 ++++++++++++++++++++++++++ 3 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/scope5.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ac53a74d35f..fa66e1bd363 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2018-02-09 Jason Merrill + + 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 Jakub Jelinek diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index a9e47701527..9c57709e7a7 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 00000000000..629225cd556 --- /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 struct e { static const int f = d; }; +} +template struct g; +template +struct g : h::template ab {}; +struct k { + template struct m { typedef typename g::n o; }; +}; +template struct ac; +struct r { + typedef ac p; +}; +template struct s : k { + template + struct ab : q::template t::template ab {}; +}; +struct ad { + typedef int u; +}; +template struct ae; +template struct ah { + typedef ae ai; + typedef typename ai::template w::o n; +}; +struct x { + template struct ab : ah {}; +}; +struct y { + struct z { + template struct t : x {}; + }; + struct aj : s {}; +}; +template struct ak { + typedef y::aj al; + typedef typename al::m::o o; +}; +struct am { + enum { an }; +}; +template struct ao {}; +template struct ap : af::aq {}; +template <> struct ae { + template struct w; + template struct w { + typedef typename as::p o; + }; +}; +enum { a = b::e<0>::f }; +template class au; +template struct ac : ao { typedef c::e aq; }; +template void ay(aw, i, ax) { + au::o>::f> > az(); +} +void v() { + ad a; + void az(); + ay(az, a, v); +} -- 2.30.2