From: Patrick Palka Date: Sun, 7 May 2023 15:57:22 +0000 (-0400) Subject: c++: parenthesized -> resolving to static data member [PR98283] X-Git-Tag: basepoints/gcc-15~9579 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e4f1ea5d8b96fc9fbe4fc0e0e0a4938ceeef092f;p=thirdparty%2Fgcc.git 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). PR c++/98283 gcc/cp/ChangeLog: * pt.cc (tsubst_copy_and_build) : Propagate REF_PARENTHESIZED_P more generally via force_paren_expr. * semantics.cc (force_paren_expr): Document default argument. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/paren6.C: New test. --- diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index ee4a2f313430..de95e128c729 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -21520,8 +21520,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 474da71bff62..13c6582b6289 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 000000000000..812a99ca91cf --- /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 +struct B : T { + decltype(auto) f() { return (this->m); } +}; + +using type = decltype(B().f()); +using type = int&;