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:
+ <newline> - No escape possible. The character always introduces a line
break
+ or a continuation line.
+ <space>, :, # - Escaped spaces are properly handled in targets and
+ prerequisites.
+ <tab> - 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 */
--
2.51.0