From patchwork Thu Oct 28 15:51:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tobias Burnus X-Patchwork-Id: 46760 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id AE44F3857819 for ; Thu, 28 Oct 2021 15:53:07 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from esa2.mentor.iphmx.com (esa2.mentor.iphmx.com [68.232.141.98]) by sourceware.org (Postfix) with ESMTPS id D10DD3858405 for ; Thu, 28 Oct 2021 15:52:49 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org D10DD3858405 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=codesourcery.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=mentor.com IronPort-SDR: NsHaOaxJgyaTPTFJYeZrgf8IpXyh3/YuZteiPjoaVqPOlJOgE/vCAnOaSUQcfl/1jhi6vwf27U m9JnHX6B2QURw4jnGJBXjp5L880kwzAe8bWIYxJo9g7iq0T1lE08g/xrISFm3rBFXtFpPkVkUf LBbtKyDajvQFbmPZu9nAc1ZFO+sGyQPQ+VDNRMUMZC3iV9l/03pz8FA+dX0Bm/p7owWfTXWaRR +1s3nmUar49f7ykFKxaSvgVEVMsU5uRLx2WBMxcVoDMGRk2par4E/8Q2H5h+CNuCy4Cp5omD6+ 0Fq7QVHa1IQKqHVtgOcnRhLR X-IronPort-AV: E=Sophos;i="5.87,190,1631606400"; d="diff'?scan'208";a="67755158" Received: from orw-gwy-01-in.mentorg.com ([192.94.38.165]) by esa2.mentor.iphmx.com with ESMTP; 28 Oct 2021 07:52:47 -0800 IronPort-SDR: SeZg9ZDu6lc/HbHq3kDjYtJK/I9stdhe8xi4b9ER4GFImBFyFeohaCIpi3i9cTPl/rVlqLfxbO NPcXNzhKNzOmKJNyCRJpcYPV5Umo7JFBt/lKjycsrW6K1v1hGylJbGrJhqEO7NaH11p8/Zkid3 Gmu2WbJKzkHSbw2j+poWxaP+WnlMgzPFRQhnbRyBiKh7pp7ZDcDa7hxLlwu9YNPht4zemmBo1H 0S2Tho/mfPzQuACoAkfPwbecvfpx2/BjnDIJbMwft3J0iIlsVeWsJuGW8PB5Xs0sAhcOcsKhbK EYc= Message-ID: <012cb5da-5255-ac5e-c7dc-f7eb2bd34955@codesourcery.com> Date: Thu, 28 Oct 2021 17:51:59 +0200 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.2.1 Content-Language: en-US To: gcc-patches , Jakub Jelinek , Joseph Myers , David Malcolm From: Tobias Burnus Subject: [Patch] libcpp: Fix _Pragma expansion [PR102409] X-Originating-IP: [137.202.0.90] X-ClientProxiedBy: SVR-IES-MBX-04.mgc.mentorg.com (139.181.222.4) To svr-ies-mbx-01.mgc.mentorg.com (139.181.222.1) X-Spam-Status: No, score=-11.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, KAM_DMARC_STATUS, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Before this patch, running #define TEST(T) T #define PARALLEL(X) TEST(X) PARALLEL( for (int i = 0; i < N; i++) { \ _Pragma("omp ordered") \ S[0] += C[i] + D[i]; \ }) through 'gcc -E' yielded #pragma omp ordered for (int i = 0; i < N; i++) { S[0] += C[i] + D[i]; } Note that the '#pragma omp ordered' is now above the loop, i.e. before all macro arguments (and macro expansions). With the patch, the result is the following, which matches Clang and I assume GCC before 4.2 or 4.3, but I have no GCC 4.x available: for (int i = 0; i < N; i++) { #pragma omp ordered S[0] += C[i] + D[i]; } The reason seems to be the addition done for PR34692 in r131819, which added code to avoid an ICE with FOO( #pragma GCC diagnostic ) There is a length description in macro.c about what it does and the pragma_buff which is passed around, including to the now modified collect_args. Namely, the comment above enter_macro_context states: If there were additionally any unexpanded deferred #pragma directives among macro arguments, push another context containing the pragma tokens before the yet-to-be-rescanned replacement list and return two. While that seems to work fine with #pragma, it obviously does not do what it should for _Pragma. The solution in the patch was to add a flag to distinguish the CPP_PRAGMA coming from the _Pragma operator (alias BT_PRAGMA) from the CPP_PRAGMA coming from a user's #pragma. OK for mainline? – It is a long-standing regression, but it hasn't been reported for a while. Thus: how do you feel about backporting? I did test it with a full bootstrap + regtesting. I also tested omptests (cf. PR). Tobias PS: I had the hope that it would fix some of the other _Pragma related PRs (see e.g. refs in this PR102409 or search Bugzilla), but it does not seem to help for those. I do note that most of them are related to diagnostic. In particular, for PR91669, the output of gcc -E is the same for GCC 10, for a patched GCC and for clang-11, which makes the result (issue unaffected by this patch) not that surprising. ----------------- Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955 libcpp: Fix _Pragma expansion [PR102409] Both #pragma and _Pragma ended up as CPP_PRAGMA. Presumably since r131819 (2008, GCC 4.3) for PR34692, pragmas are not expanded in macro arguments but are output as is before. From the old bug report, that was to fix usage like FOO ( #pragma GCC diagnostic ) However, that change also affected _Pragma such that BAR ( "1"; _Pragma("omp ..."); ) yielded #pragma omp ... followed by what BAR expanded too, possibly including '"1";'. This commit adds a flag, PRAGMA_OP, to tokens to make the two distinguishable - and include again _Pragma in the expanded arguments. libcpp/ChangeLog: PR c++/102409 * directives.c (destringize_and_run): Add PRAGMA_OP to the CPP_PRAGMA token's flags to mark is as coming from _Pragma. * include/cpplib.h (PRAGMA_OP): #define, to be used with token flags. * macro.c (collect_args): Only handle CPP_PRAGMA special if PRAGMA_OP is set. libcpp/directives.c | 2 ++ libcpp/include/cpplib.h | 1 + libcpp/macro.c | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/libcpp/directives.c b/libcpp/directives.c index b4bc8b4df30..34f7677f718 100644 --- a/libcpp/directives.c +++ b/libcpp/directives.c @@ -1907,6 +1907,8 @@ destringize_and_run (cpp_reader *pfile, const cpp_string *in, save_directive = pfile->directive; pfile->directive = &dtable[T_PRAGMA]; do_pragma (pfile); + if (pfile->directive_result.type == CPP_PRAGMA) + pfile->directive_result.flags |= PRAGMA_OP; end_directive (pfile, 1); pfile->directive = save_directive; diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h index 6e2fcb6b1f2..56b07acc1d7 100644 --- a/libcpp/include/cpplib.h +++ b/libcpp/include/cpplib.h @@ -198,6 +198,7 @@ struct GTY(()) cpp_string { operator, or before this token after a # operator. */ #define NO_EXPAND (1 << 10) /* Do not macro-expand this token. */ +#define PRAGMA_OP (1 << 11) /* _Pragma token. */ /* Specify which field, if any, of the cpp_token union is used. */ diff --git a/libcpp/macro.c b/libcpp/macro.c index f214548de1e..b2f797cae35 100644 --- a/libcpp/macro.c +++ b/libcpp/macro.c @@ -1259,7 +1259,7 @@ collect_args (cpp_reader *pfile, const cpp_hashnode *node, else if (token->type == CPP_EOF || (token->type == CPP_HASH && token->flags & BOL)) break; - else if (token->type == CPP_PRAGMA) + else if (token->type == CPP_PRAGMA && !(token->flags & PRAGMA_OP)) { cpp_token *newtok = _cpp_temp_token (pfile);