On Fri, 5 May 2023, Patrick Palka wrote: > Here we're neglecting to propagate parenthesized-ness when the member > access expression (this->m) resolves to a static member (and thus > finish_class_member_access_expr yields a VAR_DECL instead of a > COMPONENT_REF). > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does look OK for > trunk? > > PR c++/98283 > > gcc/cp/ChangeLog: > > * pt.cc (tsubst_copy_and_build) <case COMPONENT_REF>: Use > force_paren_expr on the result of finish_class_member_access_expr > if REF_PARENTHESIZED_P. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp1y/paren6.C: New test. > --- > gcc/cp/pt.cc | 4 ++-- > gcc/cp/semantics.cc | 4 ++-- > gcc/testsuite/g++.dg/cpp1y/paren6.C | 14 ++++++++++++++ > 3 files changed, 18 insertions(+), 4 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/cpp1y/paren6.C > > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc > index 5446b5058b7..9f5549e8f29 100644 > --- a/gcc/cp/pt.cc > +++ b/gcc/cp/pt.cc > @@ -21502,8 +21502,8 @@ tsubst_copy_and_build (tree t, > r = finish_class_member_access_expr (object, member, > /*template_p=*/false, > complain); > - if (TREE_CODE (r) == COMPONENT_REF) > - REF_PARENTHESIZED_P (r) = REF_PARENTHESIZED_P (t); > + if (REF_PARENTHESIZED_P (t)) > + r = force_paren_expr (r); > RETURN (r); > } > > diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc > index 474da71bff6..c4fea2f0f0f 100644 > --- a/gcc/cp/semantics.cc > +++ b/gcc/cp/semantics.cc > @@ -2069,8 +2069,8 @@ finish_mem_initializers (tree mem_inits) > that the call to finish_decltype in do_auto_deduction will give the > right result. If EVEN_UNEVAL, do this even in unevaluated context. */ > > -tree > -force_paren_expr (tree expr, bool even_uneval) > +static tree > +force_paren_expr (tree expr, bool even_uneval /* = false */)
Whoops, I managed to send the wrong amended patch (I opted to document this default arg as a drive-by change after the fact). The correct patch is: -- >8 -- Subject: [PATCH] c++: parenthesized -> resolving to static data member [PR98283] Here we're neglecting to propagate parenthesized-ness when the member access (this->m) resolves to a static data member (and thus finish_class_member_access_expr yields a VAR_DECL instead of a COMPONENT_REF). Bootstrapped and regtested on x86_64-pc-linux-gnu, does look OK for trunk? PR c++/98283 gcc/cp/ChangeLog: * pt.cc (tsubst_copy_and_build) <case COMPONENT_REF>: Use force_paren_expr on the result of finish_class_member_access_expr if REF_PARENTHESIZED_P. * semantics.cc (force_paren_expr): Document default argument. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/paren6.C: New test. --- gcc/cp/pt.cc | 4 ++-- gcc/cp/semantics.cc | 2 +- gcc/testsuite/g++.dg/cpp1y/paren6.C | 14 ++++++++++++++ 3 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1y/paren6.C diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 5446b5058b7..9f5549e8f29 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -21502,8 +21502,8 @@ tsubst_copy_and_build (tree t, r = finish_class_member_access_expr (object, member, /*template_p=*/false, complain); - if (TREE_CODE (r) == COMPONENT_REF) - REF_PARENTHESIZED_P (r) = REF_PARENTHESIZED_P (t); + if (REF_PARENTHESIZED_P (t)) + r = force_paren_expr (r); RETURN (r); } diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index 474da71bff6..13c6582b628 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -2070,7 +2070,7 @@ finish_mem_initializers (tree mem_inits) right result. If EVEN_UNEVAL, do this even in unevaluated context. */ tree -force_paren_expr (tree expr, bool even_uneval) +force_paren_expr (tree expr, bool even_uneval /* = false */) { /* This is only needed for decltype(auto) in C++14. */ if (cxx_dialect < cxx14) diff --git a/gcc/testsuite/g++.dg/cpp1y/paren6.C b/gcc/testsuite/g++.dg/cpp1y/paren6.C new file mode 100644 index 00000000000..812a99ca91c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/paren6.C @@ -0,0 +1,14 @@ +// PR c++/98283 +// { dg-do compile { target c++14 } } + +struct A { + static int m; +}; + +template<class T> +struct B : T { + decltype(auto) f() { return (this->m); } +}; + +using type = decltype(B<A>().f()); +using type = int&; -- 2.40.1.476.g69c786637d