From patchwork Fri Dec 3 10:27:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 48458 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 9E59B385DC09 for ; Fri, 3 Dec 2021 10:28:16 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9E59B385DC09 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1638527296; bh=meOWgT0HB5VU1FNqZjQMF1w8IVEbJCEuYiTmWJvQuBE=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=lGDWAE3VHm0EzetAtBbXGEK1zLoWxzXnVecu63zTfE5ziX73liDrQ7cjBnIjYiWhQ eBfKhb7LM1IfJFzK37HTboeXQTuI4mSMC7Xp2swFanc4qKuPiY306mWvt148Q6dF33 2kCMGYBOatfm+uNlHvUdW62ozeeXxdfIGcHu0z6s= 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 E899F385841A for ; Fri, 3 Dec 2021 10:27:46 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org E899F385841A 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-33-4xaAPo1OMJy1kFeJecwQXQ-1; Fri, 03 Dec 2021 05:27:43 -0500 X-MC-Unique: 4xaAPo1OMJy1kFeJecwQXQ-1 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 mimecast-mx01.redhat.com (Postfix) with ESMTPS id D555183DD21; Fri, 3 Dec 2021 10:27:41 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.39.194.188]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 14F9D10016F4; Fri, 3 Dec 2021 10:27:30 +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 1B3ARSGa2582478 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Fri, 3 Dec 2021 11:27:28 +0100 Received: (from jakub@localhost) by tucnak.zalov.cz (8.16.1/8.16.1/Submit) id 1B3ARRj52582477; Fri, 3 Dec 2021 11:27:27 +0100 Date: Fri, 3 Dec 2021 11:27:27 +0100 To: Jason Merrill , "Joseph S. Myers" , Marek Polacek Subject: [PATCH] libcpp: Fix up handling of deferred pragmas [PR102432] Message-ID: <20211203102727.GO2646553@tucnak> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-5.6 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, KAM_SHORT, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H3, 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: gcc-patches@gcc.gnu.org Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Hi! The https://gcc.gnu.org/pipermail/gcc-patches/2020-November/557903.html change broke the following testcases. The problem is when a pragma namespace allows expansion (i.e. p->is_nspace && p->allow_expansion), e.g. the omp or acc namespaces do, then when parsing the second pragma token we do it with pfile->state.in_directive set, pfile->state.prevent_expansion clear and pfile->state.in_deferred_pragma clear (the last one because we don't know yet if it will be a deferred pragma or not). If the pragma line only contains a single name and newline after it, and there exists a function-like macro with the same name, the preprocessor needs to peek in funlike_invocation_p the next token whether it isn't ( but in this case it will see a newline. As pfile->state.in_directive is set, we don't read anything after the newline, pfile->buffer->need_line is set and CPP_EOF is lexed, which funlike_invocation_p doesn't push back. Because name is a function-like macro and on the pragma line there is no ( after the name, it isn't expanded, and control flow returns to do_pragma. If name is valid deferred pragma, we set pfile->state.in_deferred_pragma (and really need it set so that e.g. end_directive later on doesn't eat all the tokens from the pragma line). Before Nathan's change (which unfortunately didn't contain rationale on why it is better to do it like that), this wasn't a problem, next _cpp_lex_direct called when we want next token would return CPP_PRAGMA_EOF when it saw buffer->need_line, which would turn off pfile->state.in_deferred_pragma and following get token would already read the next line. But Nathan's patch replaced it with an assertion failure that now triggers and CPP_PRAGMA_EOL is done only when lexing the '\n'. Except for this special case that works fine, but in this case it doesn't because when peeking the token we still didn't know that it will be a deferred pragma. I've tried to fix that up in do_pragma by detecting this and pushing CPP_PRAGMA_EOL as lookahead, but that doesn't work because end_directive still needs to see pfile->state.in_deferred_pragma set. So, this patch affectively reverts part of Nathan's change, CPP_PRAGMA_EOL addition isn't done only when parsing the '\n', but is now done in both places, in the first one instead of the assertion failure. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2021-12-03 Jakub Jelinek PR preprocessor/102432 * lex.c (_cpp_lex_direct): If buffer->need_line while pfile->state.in_deferred_pragma, return CPP_PRAGMA_EOL token instead of assertion failure. * c-c++-common/gomp/pr102432.c: New test. * c-c++-common/goacc/pr102432.c: New test. Jakub --- libcpp/lex.c.jj 2021-12-01 10:21:16.808869062 +0100 +++ libcpp/lex.c 2021-12-02 10:38:23.010621589 +0100 @@ -3530,7 +3530,21 @@ _cpp_lex_direct (cpp_reader *pfile) buffer = pfile->buffer; if (buffer->need_line) { - gcc_assert (!pfile->state.in_deferred_pragma); + if (pfile->state.in_deferred_pragma) + { + /* This can happen in cases like: + #define loop(x) whatever + #pragma omp loop + where when trying to expand loop we need to peek + next token after loop, but aren't still in_deferred_pragma + mode but are in in_directive mode, so buffer->need_line + is set, a CPP_EOF is peeked. */ + result->type = CPP_PRAGMA_EOL; + pfile->state.in_deferred_pragma = false; + if (!pfile->state.pragma_allow_expansion) + pfile->state.prevent_expansion--; + return result; + } if (!_cpp_get_fresh_line (pfile)) { result->type = CPP_EOF; --- gcc/testsuite/c-c++-common/gomp/pr102432.c.jj 2021-12-02 10:42:23.627138897 +0100 +++ gcc/testsuite/c-c++-common/gomp/pr102432.c 2021-12-02 10:41:54.163565353 +0100 @@ -0,0 +1,23 @@ +/* PR preprocessor/102432 */ + +#define loop(x) + +void +foo (void) +{ + int i; +#pragma omp parallel +#pragma omp loop + for (i = 0; i < 64; i++) + ; +} + +void +bar (void) +{ + int i; + _Pragma ("omp parallel") + _Pragma ("omp loop") + for (i = 0; i < 64; i++) + ; +} --- gcc/testsuite/c-c++-common/goacc/pr102432.c.jj 2021-12-02 10:43:10.663458092 +0100 +++ gcc/testsuite/c-c++-common/goacc/pr102432.c 2021-12-02 10:43:24.791253606 +0100 @@ -0,0 +1,23 @@ +/* PR preprocessor/102432 */ + +#define loop(x) + +void +foo (void) +{ + int i; +#pragma acc parallel +#pragma acc loop + for (i = 0; i < 64; i++) + ; +} + +void +bar (void) +{ + int i; + _Pragma ("acc parallel") + _Pragma ("acc loop") + for (i = 0; i < 64; i++) + ; +}