From patchwork Mon Nov 22 09:23:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 47993 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 4B7633858425 for ; Mon, 22 Nov 2021 09:24:11 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4B7633858425 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1637573051; bh=wC1C2939ACz9zcPueJYzBx3253FUDwlNR5ASjnmjaWo=; h=Date:To:Subject:References:In-Reply-To:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=q8CDCcLClilgzSZi78ak02CILzyPQq5sVVLixZfhWHNP+FM7U8l2mGm3ARmrsg7mv gjtxx9DnmegvEYNpsRh/XgZcxq0O4yC1u3F/O5nz+g+YVCwwe7rNQNfiEydfTUVLmm FlstAQfGTM0CJvsyK3BFNqaY9fR7uMRg+C4n28AU= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 4FA093858406 for ; Mon, 22 Nov 2021 09:23:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 4FA093858406 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-233-x12P2ZwEPbulvoxAsRffiw-1; Mon, 22 Nov 2021 04:23:35 -0500 X-MC-Unique: x12P2ZwEPbulvoxAsRffiw-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 808EC100F942; Mon, 22 Nov 2021 09:23:34 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.39.192.23]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 04D8060C5F; Mon, 22 Nov 2021 09:23:33 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.16.1/8.16.1) with ESMTPS id 1AM9NUue2535431 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Mon, 22 Nov 2021 10:23:31 +0100 Received: (from jakub@localhost) by tucnak.zalov.cz (8.16.1/8.16.1/Submit) id 1AM9NUoO2535430; Mon, 22 Nov 2021 10:23:30 +0100 Date: Mon, 22 Nov 2021 10:23:29 +0100 To: Joseph Myers Subject: [PATCH] libcpp, v2: Fix _Pragma in #__VA_ARGS__ [PR103165] Message-ID: <20211122092329.GI2646553@tucnak> References: <5e77a918-1943-03dc-5bb7-20eebfc61226@codesourcery.com> <20211118112413.GR2710@tucnak> MIME-Version: 1.0 In-Reply-To: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-5.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, 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: , X-Patchwork-Original-From: Jakub Jelinek via Gcc-patches From: Jakub Jelinek Reply-To: Jakub Jelinek Cc: Tobias Burnus , gcc-patches Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" On Thu, Nov 18, 2021 at 09:55:52PM +0000, Joseph Myers wrote: > On Thu, 18 Nov 2021, Jakub Jelinek via Gcc-patches wrote: > > > Are we handling the pragma at a wrong phase of preprocessing? > > I think that converting it to a single preprocessing token (rather than > four separate preprocessing tokens), at a stage when stringizing might > still occur, does indicate it's being processed too soon, and it would be > better to do that only when it's known that the _Pragma preprocessing > token will actually occur in the results of preprocessing the source file. So like this? I.e. don't process _Pragma during expand_args where we can't know what the macro will do with it? Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2021-11-22 Jakub Jelinek Tobias Burnus PR preprocessor/103165 libcpp/ * internal.h (struct lexer_state): Add ignore__Pragma field. * macro.c (builtin_macro): Don't interpret _Pragma if pfile->state.ignore__Pragma. (expand_arg): Temporarily set pfile->state.ignore__Pragma to 1. gcc/testsuite/ * c-c++-common/gomp/pragma-3.c: New test. * c-c++-common/gomp/pragma-4.c: New test. * c-c++-common/gomp/pragma-5.c: New test. Jakub --- libcpp/internal.h.jj 2021-11-18 12:33:18.409679558 +0100 +++ libcpp/internal.h 2021-11-20 11:00:58.044399990 +0100 @@ -287,6 +287,9 @@ struct lexer_state /* Nonzero if the deferred pragma being handled allows macro expansion. */ unsigned char pragma_allow_expansion; + + /* Nonzero if _Pragma should not be interpreted. */ + unsigned char ignore__Pragma; }; /* Special nodes - identifiers with predefined significance. */ --- libcpp/macro.c.jj 2021-11-18 12:33:18.462678802 +0100 +++ libcpp/macro.c 2021-11-20 11:02:03.249478159 +0100 @@ -750,8 +750,10 @@ builtin_macro (cpp_reader *pfile, cpp_ha if (node->value.builtin == BT_PRAGMA) { /* Don't interpret _Pragma within directives. The standard is - not clear on this, but to me this makes most sense. */ - if (pfile->state.in_directive) + not clear on this, but to me this makes most sense. + Similarly, don't interpret _Pragma inside expand_args, we might + need to stringize it later on. */ + if (pfile->state.in_directive || pfile->state.ignore__Pragma) return 0; return _cpp_do__Pragma (pfile, loc); @@ -2648,6 +2650,7 @@ expand_arg (cpp_reader *pfile, macro_arg size_t capacity; bool saved_warn_trad; bool track_macro_exp_p = CPP_OPTION (pfile, track_macro_expansion); + bool saved_ignore__Pragma; if (arg->count == 0 || arg->expanded != NULL) @@ -2670,6 +2673,9 @@ expand_arg (cpp_reader *pfile, macro_arg push_ptoken_context (pfile, NULL, NULL, arg->first, arg->count + 1); + saved_ignore__Pragma = pfile->state.ignore__Pragma; + pfile->state.ignore__Pragma = 1; + for (;;) { const cpp_token *token; @@ -2692,6 +2698,7 @@ expand_arg (cpp_reader *pfile, macro_arg _cpp_pop_context (pfile); CPP_WTRADITIONAL (pfile) = saved_warn_trad; + pfile->state.ignore__Pragma = saved_ignore__Pragma; } /* Returns the macro associated to the current context if we are in --- gcc/testsuite/c-c++-common/gomp/pragma-3.c.jj 2021-11-20 11:04:27.636429378 +0100 +++ gcc/testsuite/c-c++-common/gomp/pragma-3.c 2021-11-20 11:27:46.892589048 +0100 @@ -0,0 +1,20 @@ +/* { dg-additional-options "-fdump-tree-original" } */ +/* PR preprocessor/103165 */ + +#define inner(...) #__VA_ARGS__ ; _Pragma("omp error severity(warning) message (\"Test\") at(compilation)") +#define outer(...) inner(__VA_ARGS__) + +void +f (void) +{ + const char *str = outer(inner(1,2)); /* { dg-warning "'pragma omp error' encountered: Test" } */ +} + +#if 0 +After preprocessing, the expected result are the following three lines: + const char *str = "\"1,2\" ; _Pragma(\"omp error severity(warning) message (\\\"Test\\\") at(compilation)\")" ; +#pragma omp error severity(warning) message ("Test") at(compilation) + ; +#endif + +/* { dg-final { scan-tree-dump "const char \\* str = \\(const char \\*\\) \"\\\\\"1,2\\\\\" ; _Pragma\\(\\\\\"omp error severity\\(warning\\) message \\(\\\\\\\\\\\\\"Test\\\\\\\\\\\\\"\\) at\\(compilation\\)\\\\\"\\)\";" "original" } } */ --- gcc/testsuite/c-c++-common/gomp/pragma-4.c.jj 2021-11-20 11:04:35.355319742 +0100 +++ gcc/testsuite/c-c++-common/gomp/pragma-4.c 2021-11-20 11:28:22.995078169 +0100 @@ -0,0 +1,20 @@ +/* { dg-additional-options "-fdump-tree-original -save-temps" } */ +/* PR preprocessor/103165 */ + +#define inner(...) #__VA_ARGS__ ; _Pragma("omp error severity(warning) message (\"Test\") at(compilation)") +#define outer(...) inner(__VA_ARGS__) + +void +f (void) +{ + const char *str = outer(inner(1,2)); /* { dg-warning "'pragma omp error' encountered: Test" } */ +} + +#if 0 +After preprocessing, the expected result are the following three lines: + const char *str = "\"1,2\" ; _Pragma(\"omp error severity(warning) message (\\\"Test\\\") at(compilation)\")" ; +#pragma omp error severity(warning) message ("Test") at(compilation) + ; +#endif + +/* { dg-final { scan-tree-dump "const char \\* str = \\(const char \\*\\) \"\\\\\"1,2\\\\\" ; _Pragma\\(\\\\\"omp error severity\\(warning\\) message \\(\\\\\\\\\\\\\"Test\\\\\\\\\\\\\"\\) at\\(compilation\\)\\\\\"\\)\";" "original" } } */ --- gcc/testsuite/c-c++-common/gomp/pragma-5.c.jj 2021-11-20 11:05:22.855645064 +0100 +++ gcc/testsuite/c-c++-common/gomp/pragma-5.c 2021-11-20 11:30:33.777227520 +0100 @@ -0,0 +1,20 @@ +/* { dg-additional-options "-fdump-tree-original" } */ +/* PR preprocessor/103165 */ + +#define inner(...) #__VA_ARGS__ ; _Pragma ( " omp error severity (warning) message (\"Test\") at(compilation)" ) +#define outer(...) inner(__VA_ARGS__) + +void +f (void) +{ + const char *str = outer(inner(1,2)); /* { dg-warning "'pragma omp error' encountered: Test" } */ +} + +#if 0 +After preprocessing, the expected result are the following three lines: + const char *str = "\"1,2\" ; _Pragma ( \" omp error severity (warning) message (\\\"Test\\\") at(compilation)\" )" ; +#pragma omp error severity(warning) message ("Test") at(compilation) + ; +#endif + +/* { dg-final { scan-tree-dump "const char \\* str = \\(const char \\*\\) \"\\\\\"1,2\\\\\" ; _Pragma \\( \\\\\" omp\\\\t\\\\terror severity \\(warning\\)\\\\tmessage \\(\\\\\\\\\\\\\"Test\\\\\\\\\\\\\"\\) at\\(compilation\\)\\\\\" \\)\";" "original" } } */