On this testcase, finish_class_member_access_expr unpacked the SCOPE_REF, changing the name variable, and then used that variable to return a dependent COMPONENT_REF. We are already holding onto the original value of name, we should use that instead.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit c3d8ecaeee56d1d7009a6484db66f84ef6031a66 Author: Jason Merrill <ja...@redhat.com> Date: Wed Aug 3 17:20:31 2016 -0400 PR c++/72796 - wrong resolution of scoped method call. * typeck.c (finish_class_member_access_expr): Avoid stripping SCOPE_REF to dependent base. diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index d4bfb11..78d443b 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -2683,7 +2683,7 @@ finish_class_member_access_expr (cp_expr object, tree name, bool template_p, { dependent: return build_min_nt_loc (UNKNOWN_LOCATION, COMPONENT_REF, - orig_object, name, NULL_TREE); + orig_object, orig_name, NULL_TREE); } object = build_non_dependent_expr (object); } diff --git a/gcc/testsuite/g++.dg/template/dependent-base2.C b/gcc/testsuite/g++.dg/template/dependent-base2.C new file mode 100644 index 0000000..b418832 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dependent-base2.C @@ -0,0 +1,18 @@ +// PR c++/72796 +// { dg-do compile { target c++11 } } + +struct a; +template <int> struct b { typedef a c; }; +struct d { + void e(int); +}; +struct a : d { + void e(int) = delete; +}; +template <int f> struct g : b<f>::c { + g(int) { this->d::e(0); } +}; +struct h : g<0> { + using i = g; + h() : i(0) {} +};