[PATCH v2] fixinc: don't "fix" machine names in __has_include(...) [PR91085]

Xi Ruoyao xry111@mengyan1223.wang
Mon Jun 28 06:07:16 GMT 2021


v2: match for __has_include explicitly, as it may contains
header name in <...> form.

fixincludes/

	* fixfixes.c (machine_name_fix): Don't replace header names in
	  __has_include(...).
	* inclhack.def (machine_name): Adjust test.
	* tests/base/testing.h: Update.
---
 fixincludes/fixfixes.c           | 29 +++++++++++++++++++++++++++--
 fixincludes/inclhack.def         |  3 ++-
 fixincludes/tests/base/testing.h |  2 +-
 3 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/fixincludes/fixfixes.c b/fixincludes/fixfixes.c
index 5b23a8b640d..147cba716c7 100644
--- a/fixincludes/fixfixes.c
+++ b/fixincludes/fixfixes.c
@@ -488,7 +488,7 @@ FIX_PROC_HEAD( char_macro_def_fix )
 FIX_PROC_HEAD( machine_name_fix )
 {
   regmatch_t match[2];
-  const char *line, *base, *limit, *p, *q;
+  const char *line, *base, *limit, *p, *q, *r;
   regex_t *label_re, *name_re;
   char scratch[SCRATCHSZ];
   size_t len;
@@ -524,7 +524,7 @@ FIX_PROC_HEAD( machine_name_fix )
       /* If the 'name_pat' matches in between base and limit, we have
          a bogon.  It is not worth the hassle of excluding comments
          because comments on #if/#ifdef lines are rare, and strings on
-         such lines are illegal.
+         such lines are only legal in a "__has_include" directive.
 
          REG_NOTBOL means 'base' is not at the beginning of a line, which
          shouldn't matter since the name_re has no ^ anchor, but let's
@@ -544,6 +544,31 @@ FIX_PROC_HEAD( machine_name_fix )
             break;
 
           p = base + match[0].rm_so;
+
+          /* Check if the match is in __has_include(...) (PR 91085). */
+          for (q = base; q < p; q++)
+            if (!strncmp (q, "__has_include", 13))
+              {
+                r = q + 13;
+                while (r < p && ISSPACE (*r))
+                  r++;
+
+                /* "__has_include" may appear as "defined(__has_include)",
+                   search for the next appearance then.  */
+                if (*r != '(')
+                  continue;
+
+                /* To avoid too much complexity, just hope there is never a
+                   ')' in a header name.  */
+                while (r < limit && *r != ')')
+                  r++;
+                if (r >= base + match[0].rm_eo)
+                  {
+                    base = r;
+                    goto again;
+                  }
+              }
+
           base += match[0].rm_eo;
 
           /* One more test: if on the same line we have the same string
diff --git a/fixincludes/inclhack.def b/fixincludes/inclhack.def
index 3a4cfe06542..31389396af6 100644
--- a/fixincludes/inclhack.def
+++ b/fixincludes/inclhack.def
@@ -3151,7 +3151,8 @@ fix = {
     c_fix     = machine_name;
 
     test_text = "/* MACH_DIFF: */\n"
-    "#if defined( i386 ) || defined( sparc ) || defined( vax )"
+    "#if defined( i386 ) || defined( sparc ) || defined( vax ) || "
+    "defined( linux ) || __has_include ( <linux.h> ) || defined ( linux )"
     "\n/* no uniform test, so be careful  :-) */";
 };
 
diff --git a/fixincludes/tests/base/testing.h b/fixincludes/tests/base/testing.h
index cf95321fb86..00e8dde003e 100644
--- a/fixincludes/tests/base/testing.h
+++ b/fixincludes/tests/base/testing.h
@@ -64,7 +64,7 @@ BSD43__IOWR('T', 1) /* Some are multi-line */
 
 #if defined( MACHINE_NAME_CHECK )
 /* MACH_DIFF: */
-#if defined( i386 ) || defined( sparc ) || defined( vax )
+#if defined( i386 ) || defined( sparc ) || defined( vax ) || defined( linux ) || __has_include ( <linux.h> ) || defined ( linux )
 /* no uniform test, so be careful  :-) */
 #endif  /* MACHINE_NAME_CHECK */
 
-- 
2.32.0





More information about the Gcc-patches mailing list