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.

Bug 41329 - -M does not properly escape special characters.

Bug 121450 - Generated dependency fragment for module partitions cause make failure
---
 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                       | 28 ++++++++++++++++----------
 4 files changed, 24 insertions(+), 18 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..40fd5062a8a 100644
--- a/libcpp/mkdeps.cc
+++ b/libcpp/mkdeps.cc
@@ -121,10 +121,11 @@ public:
 };

 /* Apply Make quoting to STR, TRAIL.  Note that it's not possible to
-   quote all such characters - e.g. \n, %, *, ?, [, \ (in some
+   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.)  */
+   Old comment referred to 4.4.1.) However there are still issues with
+   this special characters in some contexts.  */

 static const char *
 munge (const char *str, const char *trail = nullptr)
@@ -157,18 +158,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.50.1


Reply via email to