From patchwork Tue Sep 16 16:19:41 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: joergboe X-Patchwork-Id: 120369 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 449D63857706 for ; Tue, 16 Sep 2025 16:21:06 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 449D63857706 Authentication-Results: sourceware.org; dkim=fail reason="signature verification failed" (2048-bit key, unprotected) header.d=snafu.de header.i=@snafu.de header.a=rsa-sha256 header.s=sn header.b=RXOb+iMm X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from cosmopolitan.snafu.de (cosmopolitan.snafu.de [IPv6:2001:1560:3:255::151]) by sourceware.org (Postfix) with ESMTPS id 3CA223857737 for ; Tue, 16 Sep 2025 16:19:57 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 3CA223857737 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=snafu.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=snafu.de ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 3CA223857737 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2001:1560:3:255::151 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1758039597; cv=none; b=jRA2ew2FlEnwMC08BDXmP4tQq5sdcB/OSwzJwjrjwueUNqRwhWAZVEH83pjiHUfGjOgsoGMud7iDKx5BfxIFx3aOWKlpuud9HARS3w5rvdZ+TznHprphV+y2g/0y8G4IRtxtDtQ7K2lq35+p5/CdoXsHhwmV7WypDYXoqaw77fs= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1758039597; c=relaxed/simple; bh=4jUg9djV0thQWKlyGOe9p5QcOfeZWZK1j8jrMlcyOY8=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=h83QxQ/CMs0B9LtYaTROt6VjTsZH0R1J0HV+Ls8NOyM8hAlX/2MMwN88tQPsYdGVMFpYB/NFPJEllYSXCzkHfv7YIkN1pkf97CN5m+7UZxFB1hXZ2QJkMBt0qzvJpi3aXB9DT7rdoHs9j/eXwcKeEy6kjNkv2FBqvehZILdwSm0= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3CA223857737 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=snafu.de; s=sn; h=Content-Transfer-Encoding:Content-Type:MIME-Version:Message-ID:Date: Subject:Cc:To:From:Sender:Reply-To:Content-ID:Content-Description:Resent-Date :Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To: References:List-Id:List-Help:List-Unsubscribe:List-Subscribe:List-Post: List-Owner:List-Archive; bh=3gxO1JdmITCMROCMUjo5ckzTxitdcTnpNKJRUkcztsw=; b=R XOb+iMm4kiHBgiB3jBceJQQXxyGtQXspXTIUe28xoAJ6n3XyzmhZRDb5yo/TCyXYbuInc7oORuBvk B+au0ETQnLCAqlpDiqI06RlDdSCD0qwI/WqJD7z5Feq30j/cRBM/Il1H++F4MFmYnrwBenRXr08B+ BjSmOcji6ojueFgTqCyXBeGA4q6qvYG6wnemwnEMaxpKTWThN1ieGElrDwpc7hfGKu5DPsd4uaESD Ue70Qq7dDDoIpCe0EdQWlgOrKDMo9LeRGtkj7LPwejgGW5gjdBf/EKq9nxGk7mZQyxttn9F+CPB+C aHSCzOX1XmMDVkuW8G5IZsNRBbjo7TURA==; X-Trace: 507c6a6f657267626f6540736e6166752e64657c38352e3139312e32352e323335 7c31757959504b2d30303030303030303877312d317a6c767c3137353830333935 3934 Received: from cosmopolitan.snafu.de ([10.151.10.19] helo=localhost) by cosmopolitan.snafu.de with esmtpsa (Exim 4.98.2) id 1uyYPK-000000008w1-1zlv; Tue, 16 Sep 2025 18:19:55 +0200 From: Joerg Boehmer To: gcc-patches@gcc.gnu.org Cc: Joerg Boehmer Subject: [PATCH v4] preprocessor: More escapes for Makefile rules (-M option) [PR41329, PR121450] Date: Tue, 16 Sep 2025 18:19:41 +0200 Message-ID: <20250916161943.39675-1-joergboe@snafu.de> X-Mailer: git-send-email 2.51.0 MIME-Version: 1.0 X-VISP-ShouldScan: 1 X-VISP-Virus-Check: clean X-VISP-Spam-Score: -0.2 (/) X-VISP-Spam-Report: This message has been scanned on "cosmopolitan.snafu.de" to identify if it is considered spam or not. Contact the support hotline for details. Content analysis details: (-0.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -1.0 ALL_TRUSTED Passed through trusted hosts only via SMTP 0.8 BAYES_50 BODY: Bayes spam probability is 40 to 60% [score: 0.5000] X-VISP-Spam-Max-Score: +++++ X-SA-Exim-Connect-IP: 85.191.25.235 X-SA-Exim-Mail-From: joergboe@snafu.de X-SA-Exim-Scanned: No (on cosmopolitan.snafu.de); SAEximRunCond expanded to false X-Spam-Status: No, score=-10.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 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 This patch adds support for more characters that are special to GNU make in file-names. Especially GNU make expects in rules that #, %, :, *, ? and [ characters are preceded by a backslash to remove their special meaning. PR preprocessor/41329 PR preprocessor/121450 libcpp/ChangeLog: * mkdeps.cc (munge): Quote additional characters: %, :, *, ? and [ gcc/testsuite/ChangeLog: * g++.dg/modules/dep-1_a.C: Adapt tescase * g++.dg/modules/dep-1_b.C: Likewise * g++.dg/modules/dep-2.C: Likewise --- gcc/testsuite/g++.dg/modules/dep-1_a.C | 4 +- gcc/testsuite/g++.dg/modules/dep-1_b.C | 4 +- gcc/testsuite/g++.dg/modules/dep-2.C | 6 +-- libcpp/mkdeps.cc | 52 +++++++++++++++++++------- 4 files changed, 45 insertions(+), 21 deletions(-) diff --git a/gcc/testsuite/g++.dg/modules/dep-1_a.C b/gcc/testsuite/g++.dg/modules/dep-1_a.C index 3e92eeaef9f..f90c2378702 100644 --- a/gcc/testsuite/g++.dg/modules/dep-1_a.C +++ b/gcc/testsuite/g++.dg/modules/dep-1_a.C @@ -4,6 +4,6 @@ export module m:part; // { dg-module-cmi m:part } // All The Backslashes! -// { dg-final { scan-file dep-1_a.d {\nm:part\.c\+\+-module: gcm.cache/m-part\.gcm} } } +// { dg-final { scan-file dep-1_a.d {\nm\\:part\.c\+\+-module: gcm.cache/m-part\.gcm} } } // { dg-final { scan-file dep-1_a.d {\ngcm.cache/m-part\.gcm:| dep-1_a\.o} } } -// { dg-final { scan-file dep-1_a.d {\n\.PHONY: m:part\.c\+\+-module} } } +// { dg-final { scan-file dep-1_a.d {\n\.PHONY: m\\:part\.c\+\+-module} } } diff --git a/gcc/testsuite/g++.dg/modules/dep-1_b.C b/gcc/testsuite/g++.dg/modules/dep-1_b.C index 265ebfcda64..1ecb31c230e 100644 --- a/gcc/testsuite/g++.dg/modules/dep-1_b.C +++ b/gcc/testsuite/g++.dg/modules/dep-1_b.C @@ -3,8 +3,8 @@ export module m; // { dg-module-cmi m } export import :part; -// { dg-final { scan-file dep-1_b.d {\ndep-1_b\.s gcm.cache/m\.gcm: m:part\.c\+\+-module} } } +// { dg-final { scan-file dep-1_b.d {\ndep-1_b\.s gcm.cache/m\.gcm: m\\:part\.c\+\+-module} } } // { dg-final { scan-file dep-1_b.d {\nm\.c\+\+-module: gcm.cache/m\.gcm} } } // { dg-final { scan-file dep-1_b.d {\n\.PHONY: m\.c\+\+-module} } } // { dg-final { scan-file dep-1_b.d {\ngcm.cache/m\.gcm:| dep-1_b.o} } } -// { dg-final { scan-file dep-1_b.d {\nCXX_IMPORTS \+= m:part\.c\+\+-module} } } +// { dg-final { scan-file dep-1_b.d {\nCXX_IMPORTS \+= m\\:part\.c\+\+-module} } } diff --git a/gcc/testsuite/g++.dg/modules/dep-2.C b/gcc/testsuite/g++.dg/modules/dep-2.C index 3c869755785..eca5653f548 100644 --- a/gcc/testsuite/g++.dg/modules/dep-2.C +++ b/gcc/testsuite/g++.dg/modules/dep-2.C @@ -5,8 +5,8 @@ module m:part; // { dg-module-cmi !m:part } // All The Backslashes! -// { dg-final { scan-file dep-2.d {\nm:part\.c\+\+-module: gcm.cache/m-part\.gcm} } } -// { dg-final { scan-file dep-2.d {\ngcm.cache/m:part\.gcm:| dep-2\.o} } } -// { dg-final { scan-file dep-2.d {\n\.PHONY: m:part\.c\+\+-module} } } +// { dg-final { scan-file dep-2.d {\nm\\:part\.c\+\+-module: gcm.cache/m-part\.gcm} } } +// { dg-final { scan-file dep-2.d {\ngcm.cache/m\\:part\.gcm:| dep-2\.o} } } +// { dg-final { scan-file dep-2.d {\n\.PHONY: m\\:part\.c\+\+-module} } } // { dg-final { scan-file dep-2.i {\nmodule m:part;\n} } } diff --git a/libcpp/mkdeps.cc b/libcpp/mkdeps.cc index a4bea6e47d4..fe620e6c927 100644 --- a/libcpp/mkdeps.cc +++ b/libcpp/mkdeps.cc @@ -120,11 +120,30 @@ public: unsigned short quote_lwm; }; -/* Apply Make quoting to STR, TRAIL. Note that it's not possible to - quote all such characters - e.g. \n, %, *, ?, [, \ (in some - contexts), and ~ are not properly handled. It isn't possible to - get this right in any current version of Make. (??? Still true? - Old comment referred to 3.76.1.) */ +/* Apply Make quoting to STR, TRAIL. GNU make supports escape sequences in + rules for characters that are special to make. Note that it's not possible + to quote all such characters and some are not properly handled. The current + status with version 4.4.1 of GNU make is: + - No escape possible. The character always introduces a line break + or a continuation line. + , :, # - Escaped spaces are properly handled in targets and + prerequisites. + - Escaped tab-characters sometimes decay to a space in targets and + prerequisites. + =, ; - No escape possible. These characters always retain their special + meaning. + % - Quoting is required in targets. Quoting is not required in + prerequisites. + | - Quoting is required in prerequisites. Quoting is not required in + targets. + *, ?, [ - Quoting required in targets and prerequisites but not always + properly handled. See: https://savannah.gnu.org/bugs/?67517. + ~ - This character has no special meaning if it is not used at the beginning + of a word. + & - Quoting is not required. + $ - The special significance of ‘$’ is removed by writing ‘$$’. + \ - The quoting of the backslash character depends on the following + character. */ static const char * munge (const char *str, const char *trail = nullptr) @@ -157,18 +176,23 @@ munge (const char *str, const char *trail = nullptr) case ' ': case '\t': - /* GNU make uses a weird quoting scheme for white space. - A space or tab preceded by 2N+1 backslashes - represents N backslashes followed by space; a space - or tab preceded by 2N backslashes represents N - backslashes at the end of a file name; and - backslashes in other contexts should not be + case '#': + case ':': + case '*': + case '?': + case '[': + case '%': + /* GNU make uses a weird quoting scheme for those special + characters in the context of a target or prerequisite. + A special character preceded by 2N+1 backslashes + represents N backslashes and the following character + loses its special meaning; a special + character preceded by 2N backslashes represents N + backslashes and the special meaning of the character is + retained; and backslashes in other contexts should not be doubled. */ while (slashes--) buf[dst++] = '\\'; - /* FALLTHROUGH */ - - case '#': buf[dst++] = '\\'; /* FALLTHROUGH */