From 06aa77035c9debda88c1841dc34e188154a95963 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Mon, 27 Jul 2020 13:05:28 -0700 Subject: [PATCH] common: Use strcmp to compare location file names 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. --- gcc/c-family/c-common.c | 11 ++++-- .../g++.dg/lookup/missing-std-include-10.C | 43 ++++++++++++++++++++++ .../g++.dg/lookup/missing-std-include-10.h | 1 + .../g++.dg/lookup/missing-std-include-11.C | 43 ++++++++++++++++++++++ 4 files changed, 94 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/lookup/missing-std-include-10.C create mode 100644 gcc/testsuite/g++.dg/lookup/missing-std-include-10.h create mode 100644 gcc/testsuite/g++.dg/lookup/missing-std-include-11.C diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index e2569c6..116867a 100644 --- a/gcc/c-family/c-common.c +++ b/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 a/gcc/testsuite/g++.dg/lookup/missing-std-include-10.C b/gcc/testsuite/g++.dg/lookup/missing-std-include-10.C new file mode 100644 index 0000000..9dfa78f --- /dev/null +++ b/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 \n // HERE\n} } diff --git a/gcc/testsuite/g++.dg/lookup/missing-std-include-10.h b/gcc/testsuite/g++.dg/lookup/missing-std-include-10.h new file mode 100644 index 0000000..40a8c17 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/missing-std-include-10.h @@ -0,0 +1 @@ +/* empty */ diff --git a/gcc/testsuite/g++.dg/lookup/missing-std-include-11.C b/gcc/testsuite/g++.dg/lookup/missing-std-include-11.C new file mode 100644 index 0000000..ec2c494 --- /dev/null +++ b/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 \n // HERE\n} } -- 2.7.4