Message ID | CADzB+2=XTCw7fZ6x3nnEtVHu9CpaeAnK72ZWFPKWho_+AZ3FFw@mail.gmail.com |
---|---|
State | New |
Headers | show |
Series | C++ PATCH for c++/83714, ICE checking return from template | expand |
Hi Jason, On 17/01/2018 00:04, Jason Merrill wrote: > Like my recent patch for 83186, we were missing a build_non_dependent_expr. > > Tested x86_64-pc-linux-gnu, applying to trunk. Lately I'm seeing (H.J. Lu too) a regression: FAIL: g++.dg/template/inherit4.C -std=c++11 (test for excess errors) FAIL: g++.dg/template/inherit4.C -std=c++14 (test for excess errors) which seems related to this change of yours: if I comment out the new build_non_dependent_expr call the test is accepted again. Could you please have a look? Thanks! Paolo.
On Wed, Jan 17, 2018 at 3:46 PM, Paolo Carlini <paolo.carlini@oracle.com> wrote: > Hi Jason, > > On 17/01/2018 00:04, Jason Merrill wrote: >> >> Like my recent patch for 83186, we were missing a >> build_non_dependent_expr. >> >> Tested x86_64-pc-linux-gnu, applying to trunk. > > Lately I'm seeing (H.J. Lu too) a regression: > > FAIL: g++.dg/template/inherit4.C -std=c++11 (test for excess errors) > FAIL: g++.dg/template/inherit4.C -std=c++14 (test for excess errors) > > which seems related to this change of yours: if I comment out the new > build_non_dependent_expr call the test is accepted again. Could you please > have a look? Hmm, wonder why I didn't see that in my testing. Checking a fix now. Jason
On Wed, Jan 17, 2018 at 4:31 PM, Jason Merrill <jason@redhat.com> wrote: > On Wed, Jan 17, 2018 at 3:46 PM, Paolo Carlini <paolo.carlini@oracle.com> wrote: >> Hi Jason, >> >> On 17/01/2018 00:04, Jason Merrill wrote: >>> >>> Like my recent patch for 83186, we were missing a >>> build_non_dependent_expr. >>> >>> Tested x86_64-pc-linux-gnu, applying to trunk. >> >> Lately I'm seeing (H.J. Lu too) a regression: >> >> FAIL: g++.dg/template/inherit4.C -std=c++11 (test for excess errors) >> FAIL: g++.dg/template/inherit4.C -std=c++14 (test for excess errors) >> >> which seems related to this change of yours: if I comment out the new >> build_non_dependent_expr call the test is accepted again. Could you please >> have a look? > > Hmm, wonder why I didn't see that in my testing. Checking a fix now. We were failing to treat A::foo_ as an instantiation-dependent SCOPE_REF, which it is because of the dependent base B<T>. Tested x86_64-pc-linux-gnu, applying to trunk. commit 1579ec4777b69f2fd55ce1b3e425d6222f1f015a Author: Jason Merrill <jason@redhat.com> Date: Wed Jan 17 16:29:45 2018 -0500 Fix template/inherit4.C. PR c++/83714 * search.c (any_dependent_bases_p): Handle null TREE_BINFO. * pt.c (instantiation_dependent_scope_ref_p): True if any_dependent_bases_p. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 3d7d45864c6..0296845a31b 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -23952,6 +23952,9 @@ 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 () && accessible_in_template_p (TREE_OPERAND (t, 0), TREE_OPERAND (t, 1))) return false; diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 477e9aef105..920fc15468a 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -2612,6 +2612,13 @@ any_dependent_bases_p (tree type) if (!type || !CLASS_TYPE_P (type) || !processing_template_decl) return false; + /* If we haven't set TYPE_BINFO yet, we don't know anything about the bases. + Return false because in this situation we aren't actually looking up names + in the scope of the class, so it doesn't matter whether it has dependent + bases. */ + if (!TYPE_BINFO (type)) + return false; + unsigned i; tree base_binfo; FOR_EACH_VEC_SAFE_ELT (BINFO_BASE_BINFOS (TYPE_BINFO (type)), i, base_binfo) diff --git a/gcc/testsuite/g++.dg/torture/pr83619.C b/gcc/testsuite/g++.dg/torture/pr83619.C index a5ca5372f18..5afd3ce0790 100644 --- a/gcc/testsuite/g++.dg/torture/pr83619.C +++ b/gcc/testsuite/g++.dg/torture/pr83619.C @@ -22,7 +22,7 @@ public: static void c (e *g) { - g->c (); + g->c (); // { dg-message "incomplete" } } }; };
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index f0dc03de111..d0adb798278 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -9333,6 +9333,9 @@ check_return_expr (tree retval, bool *no_warning) to undo it so we can try to treat it as an rvalue below. */ retval = maybe_undo_parenthesized_ref (retval); + if (processing_template_decl) + retval = build_non_dependent_expr (retval); + /* Under C++11 [12.8/32 class.copy], a returned lvalue is sometimes treated as an rvalue for the purposes of overload resolution to favor move constructors over copy constructors. diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-61.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-61.C new file mode 100644 index 00000000000..670d91a158c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-61.C @@ -0,0 +1,16 @@ +// PR c++/83714 +// { dg-do compile { target c++11 } } + +class a { + typedef int b; + operator b(); +}; +struct c { + using d = a; +}; +using e = c; + +template <class T> +e f(T) { + return e::d {}; // { dg-error "could not convert" } +}