diff mbox series

c-family: Use strcmp to compare location file names

Message ID 9c569d77-7467-6b25-cd77-5e7648be0a03@acm.org
State New
Headers show
Series c-family: Use strcmp to compare location file names | expand

Commit Message

Nathan Sidwell July 27, 2020, 8:13 p.m. UTC
The logic to figure out where a missing #include should be inserted uses 
pointer equality to check filenames -- the routine even says so. But 
cpplib makes no such guarantee.  It happens to be true for input that it 
preprocesses[* see line zero below], but is not true for source that has 
already been preprocessed -- all those '# ...' line directives produce 
disctinct filename strings.  That renders using -fdirectives-only as a 
prescanning stage (as I understand some people do), broken.

This patch changes to string comparisons, and explicitly rejects any 
line-zero location map that occurs at the beginning of a file.  The very 
first map of a file has a different string to the remaining maps, and we 
never tripped on that because of the pointer comparison.  The second 
testcase deploys -save-temps to cause an intermediate preprocessed 
output that is read back.

             gcc/c-family/
             * c-common.c (try_to_locate_new_include_insertion_point): Use
             strcmp, not pointer equality.
             gcc/testsuite/
             * g++.dg/lookup/missing-std-include-10.h: New.
             * g++.dg/lookup/missing-std-include-10.C: New.
             * g++.dg/lookup/missing-std-include-11.C: New.

pushing ...
diff mbox series

Patch

diff --git c/gcc/c-family/c-common.c w/gcc/c-family/c-common.c
index 51ecde69f2d..98b80d56cae 100644
--- c/gcc/c-family/c-common.c
+++ w/gcc/c-family/c-common.c
@@ -8764,8 +8764,7 @@  c_family_tests (void)
 #endif /* #if CHECKING_P */
 
 /* Attempt to locate a suitable location within FILE for a
-   #include directive to be inserted before.  FILE should
-   be a string from libcpp (pointer equality is used).
+   #include directive to be inserted before.  
    LOC is the location of the relevant diagnostic.
 
    Attempt to return the location within FILE immediately
@@ -8800,13 +8799,17 @@  try_to_locate_new_include_insertion_point (const char *file, location_t loc)
 
       if (const line_map_ordinary *from
 	  = linemap_included_from_linemap (line_table, ord_map))
-	if (from->to_file == file)
+	/* We cannot use pointer equality, because with preprocessed
+	   input all filename strings are unique.  */
+	if (0 == strcmp (from->to_file, file))
 	  {
 	    last_include_ord_map = from;
 	    last_ord_map_after_include = NULL;
 	  }
 
-      if (ord_map->to_file == file)
+      /* Likewise, use strcmp, and reject any line-zero introductory
+	 map.  */
+      if (ord_map->to_line && 0 == strcmp (ord_map->to_file, file))
 	{
 	  if (!first_ord_map_in_file)
 	    first_ord_map_in_file = ord_map;
diff --git c/gcc/testsuite/g++.dg/lookup/missing-std-include-10.C w/gcc/testsuite/g++.dg/lookup/missing-std-include-10.C
new file mode 100644
index 00000000000..9dfa78fb60e
--- /dev/null
+++ w/gcc/testsuite/g++.dg/lookup/missing-std-include-10.C
@@ -0,0 +1,43 @@ 
+// { dg-do compile }
+// { dg-additional-options -fdiagnostics-show-caret }
+// comment
+
+
+
+
+
+
+// Intentional blank lines
+
+
+
+
+
+
+
+
+#include "missing-std-include-10.h"
+// HERE
+
+
+
+
+
+
+// Intentional blank lines
+
+
+
+
+
+
+
+
+
+int main ()
+{
+  return strcmp ("", "");
+}
+// { dg-additional-files "missing-std-include-10.h" }
+// { dg-regexp {[^\n]*: error: 'strcmp' was not declared in this scope\n *return strcmp [^\n]*;\n *\^~*\n} }
+// { dg-regexp {[^\n]* note: 'strcmp' is defined in header[^\n]*\n #include "missing-std-include-10.h"\n\+#include <cstring>\n // HERE\n} }
diff --git c/gcc/testsuite/g++.dg/lookup/missing-std-include-10.h w/gcc/testsuite/g++.dg/lookup/missing-std-include-10.h
new file mode 100644
index 00000000000..40a8c178f10
--- /dev/null
+++ w/gcc/testsuite/g++.dg/lookup/missing-std-include-10.h
@@ -0,0 +1 @@ 
+/* empty */
diff --git c/gcc/testsuite/g++.dg/lookup/missing-std-include-11.C w/gcc/testsuite/g++.dg/lookup/missing-std-include-11.C
new file mode 100644
index 00000000000..ec2c494c557
--- /dev/null
+++ w/gcc/testsuite/g++.dg/lookup/missing-std-include-11.C
@@ -0,0 +1,43 @@ 
+// { dg-do compile }
+// { dg-additional-options {-fdiagnostics-show-caret -save-temps} }
+// comment  save-temps causes us to compile preprocessed output
+
+
+
+
+
+
+// Intentional blank lines
+
+
+
+
+
+
+
+
+#include "missing-std-include-10.h"
+// HERE
+
+
+
+
+
+
+// Intentional blank lines
+
+
+
+
+
+
+
+
+
+int main ()
+{
+  return strcmp ("", "");
+}
+// { dg-additional-files "missing-std-include-10.h" }
+// { dg-regexp {[^\n]*: error: 'strcmp' was not declared in this scope\n *return strcmp [^\n]*;\n *\^~*\n} }
+// { dg-regexp {[^\n]* note: 'strcmp' is defined in header[^\n]*\n #include "missing-std-include-10.h"\n\+#include <cstring>\n // HERE\n} }