From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 61715 invoked by alias); 8 Feb 2019 07:15:59 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 61557 invoked by uid 89); 8 Feb 2019 07:15:42 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=knowledge X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 08 Feb 2019 07:15:39 +0000 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 67E03C057F36; Fri, 8 Feb 2019 07:15:23 +0000 (UTC) Received: from free.home (ovpn04.gateway.prod.ext.phx2.redhat.com [10.5.9.4]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 2D1921001942; Fri, 8 Feb 2019 07:15:19 +0000 (UTC) Received: from livre (livre.home [172.31.160.2]) by free.home (8.15.2/8.15.2) with ESMTP id x187F6io746315; Fri, 8 Feb 2019 05:15:06 -0200 From: Alexandre Oliva To: Jason Merrill Cc: gcc-patches List , Nathan Sidwell Subject: Re: [C++PATCH] [PR86379] do not use TREE_TYPE for USING_DECL_SCOPE References: <54a97dd0-58e0-d799-5297-fccb6801ae5f@redhat.com> <48b96c6b-d525-18ef-75f8-6ed829009dea@redhat.com> Date: Fri, 08 Feb 2019 07:15:00 -0000 In-Reply-To: <48b96c6b-d525-18ef-75f8-6ed829009dea@redhat.com> (Jason Merrill's message of "Thu, 7 Feb 2019 11:36:23 -0500") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.1 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-SW-Source: 2019-02/txt/msg00423.txt.bz2 On Feb 7, 2019, Jason Merrill wrote: > OK, that makes sense; it isn't always clear what the right handling of > a USING_DECL is. Indeed. Like, in shared_member_p, I'm wondering if we shouldn't recurse if the USING_DECL maps to an overload, that IIUC might contain static and non-static functions, other using decls, and maybe even types. > In protected_accessible_p and shared_member_p, if we're left with a > USING_DECL after strip_using_decl, we can't give a meaningful answer, > and should probably abort; we shouldn't get here with a dependent > expression. Ah, that's good knowledge to have. I've added asserts and comments. Here's what I'm testing. [PR86379] do not use TREE_TYPE for USING_DECL_SCOPE From: Alexandre Oliva It's too risk to reuse the type field for USING_DECL_SCOPE. Language-independent parts of the compiler, such as location and non-lvalue wrappers, happily take the TREE_TYPE of a USING_DECL as if it was a type rather than an unrelated scope. For better or worse, USING_DECLs use the non-common struct so we can use the otherwise unused result field. Adjust fallout, from uses of TREE_TYPE that were supposed to be USING_DECL_SCOPE, to other accidental uses of TREE_TYPE of a USING_DECL. for gcc/cp/ChangeLog PR c++/86379 * cp-tree.h (USING_DECL_SCOPE): Use result rather than type. * name-lookup.c (strip_using_decl): Use USING_DECL_SCOPE. * search.c (protected_accessible_p): Follow USING_DECL_DECLS. (shared_member_p): Likewise. (lookup_member): Likewise. * decl.c (grok_special_member_properties): Skip USING_DECLs. * semantics.c (finish_omp_declare_simd_methods): Likewise. for gcc/testsuite/ChangeLog PR c++/86379 * g++.dg/cpp0x/pr86379.C: New. --- gcc/cp/cp-tree.h | 2=20 gcc/cp/decl.c | 3=20 gcc/cp/name-lookup.c | 2=20 gcc/cp/search.c | 19 +++ gcc/cp/semantics.c | 3=20 gcc/testsuite/g++.dg/cpp0x/pr86379.C | 207 ++++++++++++++++++++++++++++++= ++++ 6 files changed, 229 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/pr86379.C diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index dada3a6aa410..44a3620a539f 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3293,7 +3293,7 @@ struct GTY(()) lang_decl { #define DECL_DEPENDENT_P(NODE) DECL_LANG_FLAG_0 (USING_DECL_CHECK (NODE)) =20 /* The scope named in a using decl. */ -#define USING_DECL_SCOPE(NODE) TREE_TYPE (USING_DECL_CHECK (NODE)) +#define USING_DECL_SCOPE(NODE) DECL_RESULT_FLD (USING_DECL_CHECK (NODE)) =20 /* The decls named by a using decl. */ #define USING_DECL_DECLS(NODE) DECL_INITIAL (USING_DECL_CHECK (NODE)) diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 65ba812deb67..373b79b844dc 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -13297,7 +13297,8 @@ grok_special_member_properties (tree decl) { tree class_type; =20 - if (!DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)) + if (TREE_CODE (decl) =3D=3D USING_DECL + || !DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)) return; =20 class_type =3D DECL_CONTEXT (decl); diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index d7b9029b0a3a..959f43b02384 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -2100,7 +2100,7 @@ strip_using_decl (tree decl) =20=09=20=20=20=20=20 using typename :: [opt] nested-name-specifier unqualified-id ; */ - decl =3D make_typename_type (TREE_TYPE (decl), + decl =3D make_typename_type (USING_DECL_SCOPE (decl), DECL_NAME (decl), typename_type, tf_error); if (decl !=3D error_mark_node) diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 0367e4952138..4c3fffda717c 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -623,6 +623,11 @@ protected_accessible_p (tree decl, tree derived, tree = type, tree otype) if (!DERIVED_FROM_P (type, derived)) return 0; =20 + /* DECL_NONSTATIC_MEMBER_P won't work for USING_DECLs. */ + decl =3D strip_using_decl (decl); + /* We don't expect or support dependent decls. */ + gcc_assert (TREE_CODE (decl) !=3D USING_DECL); + /* [class.protected] =20 When a friend or a member function of a derived class references @@ -928,8 +933,13 @@ shared_member_p (tree t) if (is_overloaded_fn (t)) { for (ovl_iterator iter (get_fns (t)); iter; ++iter) - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (*iter)) - return 0; + { + tree decl =3D strip_using_decl (*iter); + /* We don't expect or support dependent decls. */ + gcc_assert (TREE_CODE (decl) !=3D USING_DECL); + if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)) + return 0; + } return 1; } return 0; @@ -1177,7 +1187,10 @@ lookup_member (tree xbasetype, tree name, int protec= t, bool want_type, && !really_overloaded_fn (rval)) { tree decl =3D is_overloaded_fn (rval) ? get_first_fn (rval) : rval; - if (!DECL_NONSTATIC_MEMBER_FUNCTION_P (decl) + decl =3D strip_using_decl (decl); + /* A dependent USING_DECL will be checked after tsubsting. */ + if (TREE_CODE (decl) !=3D USING_DECL + && !DECL_NONSTATIC_MEMBER_FUNCTION_P (decl) && !perform_or_defer_access_check (basetype_path, decl, decl, complain, afi)) rval =3D error_mark_node; diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 786f18ab0c8b..2009a10b4e85 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -5867,7 +5867,8 @@ finish_omp_declare_simd_methods (tree t) =20 for (tree x =3D TYPE_FIELDS (t); x; x =3D DECL_CHAIN (x)) { - if (TREE_CODE (TREE_TYPE (x)) !=3D METHOD_TYPE) + if (TREE_CODE (x) =3D=3D USING_DECL + || !DECL_NONSTATIC_MEMBER_FUNCTION_P (x)) continue; tree ods =3D lookup_attribute ("omp declare simd", DECL_ATTRIBUTES (= x)); if (!ods || !TREE_VALUE (ods)) diff --git a/gcc/testsuite/g++.dg/cpp0x/pr86379.C b/gcc/testsuite/g++.dg/cp= p0x/pr86379.C new file mode 100644 index 000000000000..82282eae8e52 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/pr86379.C @@ -0,0 +1,207 @@ +// { dg-do compile { target c++11 } } + +// Reduced from Mozilla SpiderMonkey, licensed under MPL-2.0. + +template +class Vector +{ + public: + Vector() {} + unsigned length() const { return 0; } +}; + +class TokenStreamShared +{ +}; + +template +class TokenStreamSpecific; + +class TokenStreamAnyChars + : public TokenStreamShared +{ + public: + TokenStreamAnyChars() {} +}; + +template +class SourceUnits +{ + public: + SourceUnits() {} + + bool atEnd() const { return true; } + unsigned offset() const { return 0; } + bool matchCodeUnit(CharT c) { return true; } +}; + +class TokenStreamCharsShared +{ + using CharBuffer =3D Vector; + + protected: + CharBuffer charBuffer; + + protected: + explicit TokenStreamCharsShared() {} +}; + +template +class TokenStreamCharsBase + : public TokenStreamCharsShared +{ + public: + TokenStreamCharsBase() + : TokenStreamCharsShared(), sourceUnits() + {} + + using SourceUnits =3D ::SourceUnits; + + bool matchCodeUnit(int expect) { return true; } + + protected: + SourceUnits sourceUnits; +}; + +template +class GeneralTokenStreamChars + : public TokenStreamCharsBase +{ + using CharsBase =3D TokenStreamCharsBase; + + protected: + using CharsBase::CharsBase; + + TokenStreamAnyChars& anyCharsAccess(); + const TokenStreamAnyChars& anyCharsAccess() const; +}; + +template class TokenStreamChars; + +template +class TokenStreamChars + : public GeneralTokenStreamChars +{ + private: + using CharsBase =3D TokenStreamCharsBase; + using GeneralCharsBase =3D GeneralTokenStreamChars; + using Self =3D TokenStreamChars; + + protected: + using GeneralCharsBase::anyCharsAccess; + using CharsBase::sourceUnits; + + using typename GeneralCharsBase::SourceUnits; + + protected: + using GeneralCharsBase::GeneralCharsBase; + + bool getFullAsciiCodePoint(int lead, int* codePoint) { + if (lead =3D=3D '\r') { + bool isAtEnd =3D sourceUnits.atEnd(); + if (!isAtEnd) + sourceUnits.matchCodeUnit('\n'); + } else if (lead !=3D '\n') { + *codePoint =3D lead; + return true; + } + + *codePoint =3D '\n'; + return true; + } +}; + +template +class TokenStreamSpecific + : public TokenStreamChars, + public TokenStreamShared +{ + public: + using CharsBase =3D TokenStreamCharsBase; + using GeneralCharsBase =3D GeneralTokenStreamChars; + using SpecializedCharsBase =3D TokenStreamChars; + + public: + using GeneralCharsBase::anyCharsAccess; + + private: + using typename CharsBase::SourceUnits; + + private: + using TokenStreamCharsShared::charBuffer; + using CharsBase::sourceUnits; + + public: + TokenStreamSpecific() + : SpecializedCharsBase() + {} + + public: + bool advance(unsigned position) { + bool t =3D charBuffer.length() + 1 > 0; + auto offs =3D sourceUnits.offset(); + return t && offs > 0; + } +}; + +class TokenStreamAnyCharsAccess +{ +}; + +class TokenStream final + : public TokenStreamAnyChars, + public TokenStreamSpecific +{ + using CharT =3D char16_t; + + public: + TokenStream() + : TokenStreamAnyChars(), + TokenStreamSpecific() + {} +}; + +class SyntaxParseHandler {}; + +class ParserBase +{ + public: + TokenStreamAnyChars anyChars; +}; + +template class GeneralParser; + +template +class PerHandlerParser : public ParserBase +{ +}; + +template +class ParserAnyCharsAccess +{ +}; + +template +class Parser; + +template +class GeneralParser + : public PerHandlerParser +{ + public: + TokenStreamSpecific> tokenS= tream; + + public: + GeneralParser(); +}; + + +template class TokenStreamCharsBase; + +template class TokenStreamChars; + +template class +TokenStreamChars>>; + +template class +TokenStreamSpecific>>; --=20 Alexandre Oliva, freedom fighter https://FSFLA.org/blogs/lxo Be the change, be Free! FSF Latin America board member GNU Toolchain Engineer Free Software Evangelist Hay que enGNUrecerse, pero sin perder la terGNUra jam=C3=A1s-GNUChe