[gcc r15-1785] build: Fix "make install" for MinGW
https://gcc.gnu.org/g:bd9c550acc42c5b04a61be3c8d981359b2093357 commit r15-1785-gbd9c550acc42c5b04a61be3c8d981359b2093357 Author: Lewis Hyatt Date: Thu Jun 27 16:11:27 2024 -0400 build: Fix "make install" for MinGW Since r8-4925, the "make install" recipe generates a path which can start with "//", causing problems for some Windows environments. Fix by removing the redundant slash. gcc/cp/ChangeLog: * Make-lang.in: Remove redundant slash. Diff: --- gcc/cp/Make-lang.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in index 026cf8d7088..e792ea4ddf3 100644 --- a/gcc/cp/Make-lang.in +++ b/gcc/cp/Make-lang.in @@ -344,7 +344,7 @@ c++.install-plugin: installdirs # Install import library. ifeq ($(plugin_implib),yes) $(mkinstalldirs) $(DESTDIR)$(plugin_resourcesdir) - $(INSTALL_DATA) cc1plus$(exeext).a $(DESTDIR)/$(plugin_resourcesdir)/cc1plus$(exeext).a + $(INSTALL_DATA) cc1plus$(exeext).a $(DESTDIR)$(plugin_resourcesdir)/cc1plus$(exeext).a endif c++.uninstall:
[gcc r15-1803] preprocessor: Create the parser before handling command-line includes [PR115312]
https://gcc.gnu.org/g:038d64f62271ddc62aa35d0a5dfd3843fdb9e6d7 commit r15-1803-g038d64f62271ddc62aa35d0a5dfd3843fdb9e6d7 Author: Lewis Hyatt Date: Sat Jun 15 21:09:01 2024 -0400 preprocessor: Create the parser before handling command-line includes [PR115312] Since r14-2893, we create a parser object in preprocess-only mode for the purpose of parsing #pragma while preprocessing. The parser object was formerly created after calling c_finish_options(), which leads to problems on platforms that don't use stdc-predef.h (such as MinGW, as reported in the PR). On such platforms, the call to c_finish_options() will process the first command-line-specified include file. If that includes a PCH, then c-ppoutput.cc will encounter a state it did not anticipate. Fix it by creating the parser prior to calling c_finish_options(). gcc/c-family/ChangeLog: PR pch/115312 * c-opts.cc (c_common_init): Call c_init_preprocess() before c_finish_options() so that a parser is available to process any includes specified on the command line. gcc/testsuite/ChangeLog: PR pch/115312 * g++.dg/pch/pr115312.C: New test. * g++.dg/pch/pr115312.Hs: New test. Diff: --- gcc/c-family/c-opts.cc | 2 +- gcc/testsuite/g++.dg/pch/pr115312.C | 2 ++ gcc/testsuite/g++.dg/pch/pr115312.Hs | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/gcc/c-family/c-opts.cc b/gcc/c-family/c-opts.cc index 33114f13c8d..b7789b707e6 100644 --- a/gcc/c-family/c-opts.cc +++ b/gcc/c-family/c-opts.cc @@ -1296,8 +1296,8 @@ c_common_init (void) if (flag_preprocess_only) { - c_finish_options (); c_init_preprocess (); + c_finish_options (); preprocess_file (parse_in); return false; } diff --git a/gcc/testsuite/g++.dg/pch/pr115312.C b/gcc/testsuite/g++.dg/pch/pr115312.C new file mode 100644 index 000..9074ad4a5ad --- /dev/null +++ b/gcc/testsuite/g++.dg/pch/pr115312.C @@ -0,0 +1,2 @@ +/* { dg-additional-options "-include pr115312.H -save-temps" } */ +#error "suppress PCH assembly comparison, which does not work with -save-temps" /* { dg-error "." } */ diff --git a/gcc/testsuite/g++.dg/pch/pr115312.Hs b/gcc/testsuite/g++.dg/pch/pr115312.Hs new file mode 100644 index 000..6e7c6bcac2f --- /dev/null +++ b/gcc/testsuite/g++.dg/pch/pr115312.Hs @@ -0,0 +1 @@ +// This space intentionally left blank.
[gcc r14-10374] preprocessor: Create the parser before handling command-line includes [PR115312]
https://gcc.gnu.org/g:3389a23fd492b7920a62de6af298251b3cdab617 commit r14-10374-g3389a23fd492b7920a62de6af298251b3cdab617 Author: Lewis Hyatt Date: Sat Jun 15 21:09:01 2024 -0400 preprocessor: Create the parser before handling command-line includes [PR115312] Since r14-2893, we create a parser object in preprocess-only mode for the purpose of parsing #pragma while preprocessing. The parser object was formerly created after calling c_finish_options(), which leads to problems on platforms that don't use stdc-predef.h (such as MinGW, as reported in the PR). On such platforms, the call to c_finish_options() will process the first command-line-specified include file. If that includes a PCH, then c-ppoutput.cc will encounter a state it did not anticipate. Fix it by creating the parser prior to calling c_finish_options(). gcc/c-family/ChangeLog: PR pch/115312 * c-opts.cc (c_common_init): Call c_init_preprocess() before c_finish_options() so that a parser is available to process any includes specified on the command line. gcc/testsuite/ChangeLog: PR pch/115312 * g++.dg/pch/pr115312.C: New test. * g++.dg/pch/pr115312.Hs: New test. Diff: --- gcc/c-family/c-opts.cc | 2 +- gcc/testsuite/g++.dg/pch/pr115312.C | 2 ++ gcc/testsuite/g++.dg/pch/pr115312.Hs | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/gcc/c-family/c-opts.cc b/gcc/c-family/c-opts.cc index be3058dca63..f4dced8d826 100644 --- a/gcc/c-family/c-opts.cc +++ b/gcc/c-family/c-opts.cc @@ -1285,8 +1285,8 @@ c_common_init (void) if (flag_preprocess_only) { - c_finish_options (); c_init_preprocess (); + c_finish_options (); preprocess_file (parse_in); return false; } diff --git a/gcc/testsuite/g++.dg/pch/pr115312.C b/gcc/testsuite/g++.dg/pch/pr115312.C new file mode 100644 index 000..9074ad4a5ad --- /dev/null +++ b/gcc/testsuite/g++.dg/pch/pr115312.C @@ -0,0 +1,2 @@ +/* { dg-additional-options "-include pr115312.H -save-temps" } */ +#error "suppress PCH assembly comparison, which does not work with -save-temps" /* { dg-error "." } */ diff --git a/gcc/testsuite/g++.dg/pch/pr115312.Hs b/gcc/testsuite/g++.dg/pch/pr115312.Hs new file mode 100644 index 000..6e7c6bcac2f --- /dev/null +++ b/gcc/testsuite/g++.dg/pch/pr115312.Hs @@ -0,0 +1 @@ +// This space intentionally left blank.
[gcc r14-9464] libcpp: Fix __has_include_next ICE in the last directory of the path [PR80755]
https://gcc.gnu.org/g:6c166e55b15894ceb07dcc7b55f900e50e24ec5b commit r14-9464-g6c166e55b15894ceb07dcc7b55f900e50e24ec5b Author: Lewis Hyatt Date: Wed Dec 20 16:27:42 2023 -0500 libcpp: Fix __has_include_next ICE in the last directory of the path [PR80755] In libcpp/files.cc, the function _cpp_has_header(), which implements __has_include and __has_include_next, does not check for a NULL return value from search_path_head(), leading to an ICE tripping an assert when _cpp_find_file() tries to use it. Fix it by checking for that case and silently returning false instead. As suggested by the PR author, it is easiest to make a testcase by using the -idirafter option. To enable that, also modify the dg-additional-options testsuite procedure to make the global $srcdir available, since -idirafter requires the full path. libcpp/ChangeLog: PR preprocessor/80755 * files.cc (search_path_head): Add SUPPRESS_DIAGNOSTIC argument defaulting to false. (_cpp_has_header): Silently return false if the search path has been exhausted, rather than issuing a diagnostic and then hitting an assert. gcc/testsuite/ChangeLog: * lib/gcc-defs.exp (dg-additional-options): Make $srcdir usable in a dg-additional-options directive. * c-c++-common/cpp/has-include-next-2-dir/has-include-next-2.h: New test. * c-c++-common/cpp/has-include-next-2.c: New test. Diff: --- .../cpp/has-include-next-2-dir/has-include-next-2.h | 3 +++ gcc/testsuite/c-c++-common/cpp/has-include-next-2.c | 4 gcc/testsuite/lib/gcc-defs.exp | 1 + libcpp/files.cc | 12 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/gcc/testsuite/c-c++-common/cpp/has-include-next-2-dir/has-include-next-2.h b/gcc/testsuite/c-c++-common/cpp/has-include-next-2-dir/has-include-next-2.h new file mode 100644 index 000..1e4be6ce7a3 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/has-include-next-2-dir/has-include-next-2.h @@ -0,0 +1,3 @@ +#if __has_include_next() +/* This formerly led to an ICE when the current directory was the last one in the path. */ +#endif diff --git a/gcc/testsuite/c-c++-common/cpp/has-include-next-2.c b/gcc/testsuite/c-c++-common/cpp/has-include-next-2.c new file mode 100644 index 000..4928d3e992c --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/has-include-next-2.c @@ -0,0 +1,4 @@ +/* PR preprocessor/80755 */ +/* { dg-do preprocess } */ +/* { dg-additional-options "-idirafter $srcdir/c-c++-common/cpp/has-include-next-2-dir" } */ +#include diff --git a/gcc/testsuite/lib/gcc-defs.exp b/gcc/testsuite/lib/gcc-defs.exp index 56851f4a082..70215ed4905 100644 --- a/gcc/testsuite/lib/gcc-defs.exp +++ b/gcc/testsuite/lib/gcc-defs.exp @@ -280,6 +280,7 @@ if { [info exists env(GCC_RUNTEST_PARALLELIZE_DIR)] \ proc dg-additional-options { args } { upvar dg-extra-tool-flags extra-tool-flags +global srcdir if { [llength $args] > 3 } { error "[lindex $args 0]: too many arguments" diff --git a/libcpp/files.cc b/libcpp/files.cc index e66eef46534..c61df339e20 100644 --- a/libcpp/files.cc +++ b/libcpp/files.cc @@ -181,7 +181,8 @@ static bool read_file_guts (cpp_reader *pfile, _cpp_file *file, static bool read_file (cpp_reader *pfile, _cpp_file *file, location_t loc); static struct cpp_dir *search_path_head (cpp_reader *, const char *fname, -int angle_brackets, enum include_type); +int angle_brackets, enum include_type, +bool suppress_diagnostic = false); static const char *dir_name_of_file (_cpp_file *file); static void open_file_failed (cpp_reader *pfile, _cpp_file *file, int, location_t); @@ -1041,7 +1042,7 @@ _cpp_mark_file_once_only (cpp_reader *pfile, _cpp_file *file) nothing left in the path, returns NULL. */ static struct cpp_dir * search_path_head (cpp_reader *pfile, const char *fname, int angle_brackets, - enum include_type type) + enum include_type type, bool suppress_diagnostic) { cpp_dir *dir; _cpp_file *file; @@ -1070,7 +1071,7 @@ search_path_head (cpp_reader *pfile, const char *fname, int angle_brackets, return make_cpp_dir (pfile, dir_name_of_file (file), pfile->buffer ? pfile->buffer->sysp : 0); - if (dir == NULL) + if (dir == NULL && !suppress_diagnostic) cpp_error (pfile, CPP_DL_ERROR, "no include path in which to search for %s", fname); @@ -2164,7 +2165,10 @@ bool _cpp_has_header (cpp_reader *pfile, const char *fname, int angle_brackets, enum include_type type) { - cpp_dir *start_dir = search_path_h
[gcc r14-9465] libcpp: Fix macro expansion for argument of __has_include [PR110558]
https://gcc.gnu.org/g:942497ad74272e0ef16020d628e471c5f21474b0 commit r14-9465-g942497ad74272e0ef16020d628e471c5f21474b0 Author: Lewis Hyatt Date: Tue Dec 12 17:46:36 2023 -0500 libcpp: Fix macro expansion for argument of __has_include [PR110558] When the file name for a #include directive is the result of stringifying a macro argument, libcpp needs to take some care to get the whitespace correct; in particular stringify_arg() needs to see a CPP_PADDING token between macro tokens so that it can figure out when to output space between tokens. The CPP_PADDING tokens are not normally generated when handling a preprocessor directive, but for #include-like directives, libcpp sets the state variable pfile->state.directive_wants_padding to TRUE so that the CPP_PADDING tokens will be output, and then everything works fine for computed includes. As the PR points out, things do not work fine for __has_include. Fix that by setting the state variable the same as is done for #include. libcpp/ChangeLog: PR preprocessor/110558 * macro.cc (builtin_has_include): Set pfile->state.directive_wants_padding prior to lexing the file name, in case it comes from macro expansion. gcc/testsuite/ChangeLog: PR preprocessor/110558 * c-c++-common/cpp/has-include-2.c: New test. * c-c++-common/cpp/has-include-2.h: New test. Diff: --- gcc/testsuite/c-c++-common/cpp/has-include-2.c | 12 gcc/testsuite/c-c++-common/cpp/has-include-2.h | 1 + libcpp/macro.cc| 3 +++ 3 files changed, 16 insertions(+) diff --git a/gcc/testsuite/c-c++-common/cpp/has-include-2.c b/gcc/testsuite/c-c++-common/cpp/has-include-2.c new file mode 100644 index 000..5cd00cb3fb5 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/has-include-2.c @@ -0,0 +1,12 @@ +/* PR preprocessor/110558 */ +/* { dg-do preprocess } */ +#define STRINGIZE(x) #x +#define GET_INCLUDE(i) STRINGIZE(has-include-i.h) +/* Spaces surrounding the macro args previously caused a problem for __has_include(). */ +#if __has_include(GET_INCLUDE(2)) && __has_include(GET_INCLUDE( 2)) && __has_include(GET_INCLUDE( 2 )) +#include GET_INCLUDE(2) +#include GET_INCLUDE( 2) +#include GET_INCLUDE( 2 ) +#else +#error "__has_include did not handle padding properly" /* { dg-bogus "__has_include" } */ +#endif diff --git a/gcc/testsuite/c-c++-common/cpp/has-include-2.h b/gcc/testsuite/c-c++-common/cpp/has-include-2.h new file mode 100644 index 000..57c402b32a8 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/has-include-2.h @@ -0,0 +1 @@ +/* PR preprocessor/110558 */ diff --git a/libcpp/macro.cc b/libcpp/macro.cc index a3d2c159f8c..352eb2e4fd9 100644 --- a/libcpp/macro.cc +++ b/libcpp/macro.cc @@ -398,6 +398,8 @@ builtin_has_include (cpp_reader *pfile, cpp_hashnode *op, bool has_next) NODE_NAME (op)); pfile->state.angled_headers = true; + const auto sav_padding = pfile->state.directive_wants_padding; + pfile->state.directive_wants_padding = true; const cpp_token *token = cpp_get_token_no_padding (pfile); bool paren = token->type == CPP_OPEN_PAREN; if (paren) @@ -406,6 +408,7 @@ builtin_has_include (cpp_reader *pfile, cpp_hashnode *op, bool has_next) cpp_error (pfile, CPP_DL_ERROR, "missing '(' before \"%s\" operand", NODE_NAME (op)); pfile->state.angled_headers = false; + pfile->state.directive_wants_padding = sav_padding; bool bracket = token->type != CPP_STRING; char *fname = NULL;
[gcc r14-9561] diagnostics: Fix behavior of permerror options after diagnostic pop [PR111918]
https://gcc.gnu.org/g:44ba7bcb752a40ec7490dea53d3a472ce633371d commit r14-9561-g44ba7bcb752a40ec7490dea53d3a472ce633371d Author: Lewis Hyatt Date: Wed Nov 8 16:13:14 2023 -0500 diagnostics: Fix behavior of permerror options after diagnostic pop [PR111918] When a diagnostic pragma changes the classification of a given diagnostic, the global options flags (such as warn_narrowing, etc.) may get changed too. Specifically, if a warning was not enabled initially and was later enabled by a pragma, then the corresponding global flag will change from false to true when the pragma is processed. That change is permanent and is not undone by a subsequent `#pragma GCC diagnostic pop'; the warning flag needs to remain enabled since a diagnostic could be generated later on for a source location prior to the pop. So in order to support popping to the initial classification, given that the global options flags no longer reflect that state, the diagnostic_context object itself remembers the way things were before it changed anything. The current implementation works fine for diagnostics that are always errors or always warnings, but it doesn't do the right thing for diagnostics that could be either, such as -Wnarrowing. The classification of that diagnostic (or any permerror diagnostic) depends on the state of -fpermissive; for the particular case of -Wnarrowing it also matters whether a compile-time or run-time narrowing is being diagnosed. The problem is that the current implementation insists on recording whether an enabled diagnostic should be a DK_WARNING or a DK_ERROR, and then, after popping to the initial state, it overrides it always to that type only. Fix that up by adding a new internal diagnostic type DK_ANY. This just indicates that the diagnostic is enabled without mandating exactly what type of diagnostic it should be. Then the diagnostic can be emitted with whatever type the frontend asks for. Incidentally, while making this change, I noticed that classify_diagnostic() spends some time computing a return value (the old classification kind) that is not used anywhere. The computed value seems to have some problems, mainly that it does not take into account `#pragma GCC diagnostic pop' at all, and so the returned value doesn't seem like it could make sense in many contexts. Given it would also not be desirable to leak the new internal-only DK_ANY type to outside callers, I think it would make sense in a subsequent cleanup patch to remove the return value altogether. gcc/ChangeLog: PR c++/111918 * diagnostic-core.h (enum diagnostic_t): Add DK_ANY special flag. * diagnostic.cc (diagnostic_option_classifier::classify_diagnostic): Make use of DK_ANY to indicate a diagnostic was initially enabled. (diagnostic_context::diagnostic_enabled): Do not change the type of a diagnostic if the saved classification is type DK_ANY. gcc/testsuite/ChangeLog: PR c++/111918 * g++.dg/cpp0x/Wnarrowing21a.C: New test. * g++.dg/cpp0x/Wnarrowing21b.C: New test. * g++.dg/cpp0x/Wnarrowing21c.C: New test. * g++.dg/cpp0x/Wnarrowing21d.C: New test. Diff: --- gcc/diagnostic-core.h | 5 - gcc/diagnostic.cc | 13 ++--- gcc/testsuite/g++.dg/cpp0x/Wnarrowing21a.C | 14 ++ gcc/testsuite/g++.dg/cpp0x/Wnarrowing21b.C | 9 + gcc/testsuite/g++.dg/cpp0x/Wnarrowing21c.C | 9 + gcc/testsuite/g++.dg/cpp0x/Wnarrowing21d.C | 9 + 6 files changed, 55 insertions(+), 4 deletions(-) diff --git a/gcc/diagnostic-core.h b/gcc/diagnostic-core.h index f5e1e500dc3..8071cc1f69b 100644 --- a/gcc/diagnostic-core.h +++ b/gcc/diagnostic-core.h @@ -33,7 +33,10 @@ typedef enum DK_LAST_DIAGNOSTIC_KIND, /* This is used for tagging pragma pops in the diagnostic classification history chain. */ - DK_POP + DK_POP, + /* This is used internally to note that a diagnostic is enabled + without mandating any specific type. */ + DK_ANY, } diagnostic_t; /* RAII-style class for grouping related diagnostics. */ diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc index 8e4621f8031..6ffd6236146 100644 --- a/gcc/diagnostic.cc +++ b/gcc/diagnostic.cc @@ -1136,8 +1136,7 @@ classify_diagnostic (const diagnostic_context *context, if (old_kind == DK_UNSPECIFIED) { old_kind = !context->option_enabled_p (option_index) - ? DK_IGNORED : (context->warning_as_error_requested_p () - ? DK_ERROR : DK_WARNING); + ? DK_IGNORED : DK_ANY; m_classify_diagnostic[option_index] = old_kind; } @@ -1472,7 +1471,15 @@ diagnostic_context::diagnostic_enabled (diagnostic_info *diagnostic)
[gcc r15-4505] diagnostics: libcpp: Improve locations for _Pragma lexing diagnostics [PR114423]
https://gcc.gnu.org/g:65c5bbe1c92f9c08e99d3a37c136f2ef9804a37f commit r15-4505-g65c5bbe1c92f9c08e99d3a37c136f2ef9804a37f Author: Lewis Hyatt Date: Fri Mar 22 12:55:27 2024 -0400 diagnostics: libcpp: Improve locations for _Pragma lexing diagnostics [PR114423] libcpp is not currently set up to be able to generate valid locations for tokens lexed from a _Pragma string. Instead, after obtaining the tokens, it sets their locations all to the location of the _Pragma operator itself. This makes things like _Pragma("GCC diagnostic") work well enough, but if any diagnostics are issued during lexing, prior to resetting the token locations, those diagnostics get issued at the invalid locations. Fix that up by adding a new field pfile->diagnostic_override_loc that instructs libcpp to issue diagnostics at the alternate location. libcpp/ChangeLog: PR preprocessor/114423 * internal.h (struct cpp_reader): Add DIAGNOSTIC_OVERRIDE_LOC field. * directives.cc (destringize_and_run): Set the new field to the location of the _Pragma operator. * errors.cc (cpp_diagnostic_at): Support DIAGNOSTIC_OVERRIDE_LOC to temporarily issue diagnostics at a different location. (cpp_diagnostic_with_line): Likewise. gcc/testsuite/ChangeLog: PR preprocessor/114423 * c-c++-common/cpp/pragma-diagnostic-loc.c: New test. * c-c++-common/cpp/diagnostic-pragma-1.c: Adjust expected output. * g++.dg/pch/operator-1.C: Likewise. Diff: --- gcc/testsuite/c-c++-common/cpp/diagnostic-pragma-1.c | 9 - .../c-c++-common/cpp/pragma-diagnostic-loc.c | 17 + gcc/testsuite/g++.dg/pch/operator-1.C| 8 +++- libcpp/directives.cc | 7 +++ libcpp/errors.cc | 20 ++-- libcpp/internal.h| 4 6 files changed, 53 insertions(+), 12 deletions(-) diff --git a/gcc/testsuite/c-c++-common/cpp/diagnostic-pragma-1.c b/gcc/testsuite/c-c++-common/cpp/diagnostic-pragma-1.c index 9867c94a8ddc..6e37294fd2ba 100644 --- a/gcc/testsuite/c-c++-common/cpp/diagnostic-pragma-1.c +++ b/gcc/testsuite/c-c++-common/cpp/diagnostic-pragma-1.c @@ -3,9 +3,8 @@ #pragma GCC warning "warn-a" // { dg-warning warn-a } #pragma GCC error "err-b" // { dg-error err-b } -#define CONST1 _Pragma("GCC warning \"warn-c\"") 1 -#define CONST2 _Pragma("GCC error \"err-d\"") 2 - -char a[CONST1]; // { dg-warning warn-c } -char b[CONST2]; // { dg-error err-d } +#define CONST1 _Pragma("GCC warning \"warn-c\"") 1 // { dg-warning warn-c } +#define CONST2 _Pragma("GCC error \"err-d\"") 2 // { dg-error err-d } +char a[CONST1]; // { dg-note "in expansion of macro 'CONST1'" } +char b[CONST2]; // { dg-note "in expansion of macro 'CONST2'" } diff --git a/gcc/testsuite/c-c++-common/cpp/pragma-diagnostic-loc.c b/gcc/testsuite/c-c++-common/cpp/pragma-diagnostic-loc.c new file mode 100644 index ..4ef40420cdd3 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/pragma-diagnostic-loc.c @@ -0,0 +1,17 @@ +/* { dg-do preprocess } */ +/* PR preprocessor/114423 */ +/* Check that we now issue diagnostics at the location of the _Pragma + instead of an invalid location. If we someday manage to issue + diagnostics at better locations in the future, this will need + updating. */ +_Pragma("GCC warning \"warning1\"") /* { dg-warning "1:warning1" } */ +#define P _Pragma("GCC warning \"warning2\"") /* { dg-warning "11:warning2" } */ +P /* { dg-note "in expansion of macro" } */ +#define S "GCC warning \"warning3\"" +/**/ _Pragma(S) /* { dg-warning "6:warning3" } */ + +/* This diagnostic uses a different code path (cpp_diagnostic_at() rather + than cpp_error_with_line()). Also make sure that the dg-note location + does not get overridden to the _Pragma location. */ +#pragma GCC poison xyz /* { dg-note "poisoned here" } */ +/* */ _Pragma("xyz") /* { dg-error "7:attempt to use poisoned" } */ diff --git a/gcc/testsuite/g++.dg/pch/operator-1.C b/gcc/testsuite/g++.dg/pch/operator-1.C index 290b5f7ab210..1138a9695361 100644 --- a/gcc/testsuite/g++.dg/pch/operator-1.C +++ b/gcc/testsuite/g++.dg/pch/operator-1.C @@ -1,2 +1,8 @@ #include "operator-1.H" -int main(void){ major(0);} /* { dg-warning "Did not Work" } */ +int main(void){ major(0);} /* { dg-note "in expansion of macro 'major'" } */ +/* Line numbers below pertain to the header file. */ +/* { dg-warning "Did not Work" "" { target *-*-* } 1 } */ +/* { dg-note "in expansion of macro '__glibc_macro_warning1'" "" { target *-*-* } 3 } */ +/* { dg-note "in expansion of macro '__glibc_macro_warning'" "" { target *-*-* } 4 } */ +/* { dg-note "in expansion of macro '__SYSMACROS_DM1'" "" { target *-*-* } 6 } */ +/* { dg-note "in expansion of macro '__SYSMACROS_DM'" "" { targe
[gcc r15-4330] libcpp: Support extended characters for #pragma {push, pop}_macro [PR109704]
https://gcc.gnu.org/g:998eb2a126d33ab622a6f12c7e1faccf4429835c commit r15-4330-g998eb2a126d33ab622a6f12c7e1faccf4429835c Author: Lewis Hyatt Date: Fri Jan 12 13:26:06 2024 -0500 libcpp: Support extended characters for #pragma {push,pop}_macro [PR109704] The implementation of #pragma push_macro and #pragma pop_macro has to date made use of an ad-hoc function, _cpp_lex_identifier(), which lexes an identifier out of a string. When support was added for extended characters in identifiers ($, UCNs, or UTF-8), that support was added only for the "normal" way of lexing identifiers out of a cpp_buffer (_cpp_lex_direct) and not for the ad-hoc way. Consequently, extended identifiers are not usable with these pragmas. The logic for lexing identifiers has become more complicated than it was when _cpp_lex_identifier() was written -- it now handles things like \N{} escapes in C++, for instance -- and it no longer seems practical to maintain a redundant code path for lexing identifiers. Address the issue by changing the implementation of #pragma {push,pop}_macro to lex identifiers in the expected way, i.e. by pushing a cpp_buffer and lexing the identifier from there. The existing implementation has some quirks because of the ad-hoc parsing logic. For example: #pragma push_macro("X ") ... #pragma pop_macro("X") will not restore macro X (note the extra space in the first string). However: #pragma push_macro("X ") ... #pragma pop_macro("X ") actually does sucessfully restore "X". This is because the key for looking up the saved macro on the push stack is the original string passed, so the string passed to pop_macro needs to match it exactly. It is not that easy to reproduce this logic in the world of extended characters, given that for example it should be valid to pass a UCN to push_macro, and the corresponding UTF-8 to pop_macro. Given that this aspect of the existing behavior seems unintentional and has no tests (and does not match other implementations), I opted to make the new logic more straightforward. The string passed needs to lex to one token, which must be a valid identifier, or else no action is taken and no error is generated. Any diagnostics encountered during lexing (e.g., due to a UTF-8 character not permitted to appear in an identifier) are also suppressed. It could be nice (for GCC 15) to also add a warning if a pop_macro does not match a previous push_macro. libcpp/ChangeLog: PR preprocessor/109704 * include/cpplib.h (class cpp_auto_suppress_diagnostics): New class. * errors.cc (cpp_auto_suppress_diagnostics::cpp_auto_suppress_diagnostics): New function. (cpp_auto_suppress_diagnostics::~cpp_auto_suppress_diagnostics): New function. * charset.cc (noop_diagnostic_cb): Remove. (cpp_interpret_string_ranges): Refactor diagnostic suppression logic into new class cpp_auto_suppress_diagnostics. (count_source_chars): Likewise. * directives.cc (cpp_pop_definition): Add cpp_hashnode argument. (lex_identifier_from_string): New static helper function. (push_pop_macro_common): Refactor common logic from do_pragma_push_macro and do_pragma_pop_macro; use lex_identifier_from_string instead of _cpp_lex_identifier. (do_pragma_push_macro): Reimplement using push_pop_macro_common. (do_pragma_pop_macro): Likewise. * internal.h (_cpp_lex_identifier): Remove. * lex.cc (lex_identifier_intern): Remove. (_cpp_lex_identifier): Remove. gcc/testsuite/ChangeLog: PR preprocessor/109704 * c-c++-common/cpp/pragma-push-pop-utf8.c: New test. * g++.dg/pch/pushpop-2.C: New test. * g++.dg/pch/pushpop-2.Hs: New test. * gcc.dg/pch/pushpop-2.c: New test. * gcc.dg/pch/pushpop-2.hs: New test. Diff: --- .../c-c++-common/cpp/pragma-push-pop-utf8.c| 203 + gcc/testsuite/g++.dg/pch/pushpop-2.C | 18 ++ gcc/testsuite/g++.dg/pch/pushpop-2.Hs | 9 + gcc/testsuite/gcc.dg/pch/pushpop-2.c | 18 ++ gcc/testsuite/gcc.dg/pch/pushpop-2.hs | 9 + libcpp/charset.cc | 34 +--- libcpp/directives.cc | 175 +- libcpp/errors.cc | 16 ++ libcpp/include/cpplib.h| 13 ++ libcpp/internal.h | 1 - libcpp/lex.cc | 33 11 files changed, 378 insertions(+), 151 deletions(-) diff --git a/gcc/testsuite/c-c++-common/cpp/pragma-p
[gcc r15-4331] libcpp: Fix _Pragma("GCC system_header") [PR114436]
https://gcc.gnu.org/g:8c56d697b35d3d2ef802d068cad6b3bd026a2a1a commit r15-4331-g8c56d697b35d3d2ef802d068cad6b3bd026a2a1a Author: Lewis Hyatt Date: Fri Mar 22 15:42:43 2024 -0400 libcpp: Fix _Pragma("GCC system_header") [PR114436] _Pragma("GCC system_header") currently takes effect only partially. It does succeed in updating the line_map, so that checks like in_system_header_at() return correctly, but it does not update pfile->buffer->sysp. One result is that a subsequent #include does not set up the system header state properly for the newly included file, as pointed out in the PR. Fix by propagating the new system header state back to the buffer after processing the pragma. libcpp/ChangeLog: PR preprocessor/114436 * directives.cc (destringize_and_run): If the _Pragma changed the buffer system header state (e.g. because it was "GCC system_header"), propagate that change back to the actual buffer too. gcc/testsuite/ChangeLog: PR preprocessor/114436 * c-c++-common/cpp/pragma-system-header-1.h: New test. * c-c++-common/cpp/pragma-system-header-2.h: New test. * c-c++-common/cpp/pragma-system-header.c: New test. Diff: --- gcc/testsuite/c-c++-common/cpp/pragma-system-header-1.h | 1 + gcc/testsuite/c-c++-common/cpp/pragma-system-header-2.h | 5 + gcc/testsuite/c-c++-common/cpp/pragma-system-header.c | 3 +++ libcpp/directives.cc| 11 --- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/gcc/testsuite/c-c++-common/cpp/pragma-system-header-1.h b/gcc/testsuite/c-c++-common/cpp/pragma-system-header-1.h new file mode 100644 index ..bd9ff0cb1385 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/pragma-system-header-1.h @@ -0,0 +1 @@ +#pragma GCC warning "this warning should not be output (1)" diff --git a/gcc/testsuite/c-c++-common/cpp/pragma-system-header-2.h b/gcc/testsuite/c-c++-common/cpp/pragma-system-header-2.h new file mode 100644 index ..a62d9e2685a6 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/pragma-system-header-2.h @@ -0,0 +1,5 @@ +_Pragma("GCC system_header") +#include "pragma-system-header-1.h" +#pragma GCC warning "this warning should not be output (2)" +_Pragma("unknown") +#include "pragma-system-header-1.h" diff --git a/gcc/testsuite/c-c++-common/cpp/pragma-system-header.c b/gcc/testsuite/c-c++-common/cpp/pragma-system-header.c new file mode 100644 index ..fdea12009e13 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/pragma-system-header.c @@ -0,0 +1,3 @@ +#include "pragma-system-header-2.h" /* { dg-bogus "this warning should not be output" } */ +/* { dg-do preprocess } */ +/* PR preprocessor/114436 */ diff --git a/libcpp/directives.cc b/libcpp/directives.cc index bc4a95b66feb..9d235fa1b057 100644 --- a/libcpp/directives.cc +++ b/libcpp/directives.cc @@ -2424,9 +2424,11 @@ destringize_and_run (cpp_reader *pfile, const cpp_string *in, until we've read all of the tokens that we want. */ cpp_push_buffer (pfile, (const uchar *) result, dest - result, /* from_stage3 */ true); - /* ??? Antique Disgusting Hack. What does this do? */ - if (pfile->buffer->prev) -pfile->buffer->file = pfile->buffer->prev->file; + + /* This is needed for _Pragma("once") and _Pragma("GCC system_header") to work + properly. */ + pfile->buffer->file = pfile->buffer->prev->file; + pfile->buffer->sysp = pfile->buffer->prev->sysp; start_directive (pfile); _cpp_clean_line (pfile); @@ -2491,6 +2493,9 @@ destringize_and_run (cpp_reader *pfile, const cpp_string *in, /* Finish inlining run_directive. */ pfile->buffer->file = NULL; + /* If the system header state changed due to #pragma GCC system_header, then + make that applicable to the real buffer too. */ + pfile->buffer->prev->sysp = pfile->buffer->sysp; _cpp_pop_buffer (pfile); /* Reset the old macro state before ... */
[gcc r15-5067] c++: Fix tree_contains_struct for TRAIT_EXPR
https://gcc.gnu.org/g:d7ef7d1258d8ef715be29dea0788a3e410c1d279 commit r15-5067-gd7ef7d1258d8ef715be29dea0788a3e410c1d279 Author: Lewis Hyatt Date: Sat Nov 2 21:59:24 2024 -0400 c++: Fix tree_contains_struct for TRAIT_EXPR CODE_CONTAINS_STRUCT () currently reports that a TRAIT_EXPR contains a TS_EXP struct, but it does not actually start with a TS_EXP as an initial sequence. In modules.cc, when we stream out a tree, we explicitly check for the TS_EXP case and call note_location(t->exp.locus) if so. Currently, this actually queries the tree_common::chain field of a tree_trait_expr, which seems not to be used, returning 0, which is interpreted as UNKNOWN_LOCATION and does no harm. If location_t will change to be 64 bytes, as is under discussion, then on 32-bit platforms (well those, such as sparc, on which uint64_t has higher alignment requirement than a pointer), reading t->exp.locus will end up reading a different field (tree_trait_expr::type1) due to padding offsets. That field is not generally 0, and the resulting bogus location_t is sufficiently problematic to cause an ICE in the line_map code. Pretty much any modules testcase displays the issue, such as partial-2_a.C. Resolve by initializing tree_contains_struct with the correct value for TRAIT_EXPR, namely TS_TYPED. gcc/cp/ChangeLog: * cp-objcp-common.cc (cp_common_init_ts): Change TRAIT_EXPR from TS_EXP to TS_TYPED. Diff: --- gcc/cp/cp-objcp-common.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/cp/cp-objcp-common.cc b/gcc/cp/cp-objcp-common.cc index 7a0636f16532..1e43db31db8c 100644 --- a/gcc/cp/cp-objcp-common.cc +++ b/gcc/cp/cp-objcp-common.cc @@ -617,6 +617,7 @@ cp_common_init_ts (void) MARK_TS_TYPED (PTRMEM_CST); MARK_TS_TYPED (LAMBDA_EXPR); MARK_TS_TYPED (TYPE_ARGUMENT_PACK); + MARK_TS_TYPED (TRAIT_EXPR); /* Random new trees. */ MARK_TS_COMMON (BASELINK); @@ -684,7 +685,6 @@ cp_common_init_ts (void) MARK_TS_EXP (TAG_DEFN); MARK_TS_EXP (TEMPLATE_ID_EXPR); MARK_TS_EXP (THROW_EXPR); - MARK_TS_EXP (TRAIT_EXPR); MARK_TS_EXP (TYPEID_EXPR); MARK_TS_EXP (TYPE_EXPR); MARK_TS_EXP (UNARY_PLUS_EXPR);
[gcc r14-10980] libcpp: Fix ICE lexing invalid raw string in a deferred pragma [PR117118]
https://gcc.gnu.org/g:9214e3fdf914dd2b687f13980c39ac2db7b1565f commit r14-10980-g9214e3fdf914dd2b687f13980c39ac2db7b1565f Author: Lewis Hyatt Date: Mon Oct 14 17:59:46 2024 -0400 libcpp: Fix ICE lexing invalid raw string in a deferred pragma [PR117118] The PR shows that we ICE after lexing an invalid unterminated raw string, because lex_raw_string() pops the main buffer unexpectedly. Resolve by handling this case the same way as for other directives. libcpp/ChangeLog: PR preprocessor/117118 * lex.cc (lex_raw_string): Treat an unterminated raw string the same way for a deferred pragma as is done for other directives. gcc/testsuite/ChangeLog: PR preprocessor/117118 * c-c++-common/raw-string-directive-3.c: New test. * c-c++-common/raw-string-directive-4.c: New test. Diff: --- gcc/testsuite/c-c++-common/raw-string-directive-3.c | 8 gcc/testsuite/c-c++-common/raw-string-directive-4.c | 8 libcpp/lex.cc | 3 ++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/gcc/testsuite/c-c++-common/raw-string-directive-3.c b/gcc/testsuite/c-c++-common/raw-string-directive-3.c new file mode 100644 index ..fa4fa979fcef --- /dev/null +++ b/gcc/testsuite/c-c++-common/raw-string-directive-3.c @@ -0,0 +1,8 @@ +/* { dg-options "-std=gnu99" { target c } } */ +/* { dg-options "-std=c++11" { target c++ } } */ + +/* { dg-error "invalid new-line in raw string delimiter" "" { target *-*-* } .+4 } */ +/* { dg-error "unterminated raw string" "" { target *-*-* } .+3 } */ +/* { dg-error "stray 'R' in program" "" { target *-*-* } .+2 } */ +/* { dg-warning "expected a string" "" { target *-*-* } .+1 } */ +#pragma message R"" diff --git a/gcc/testsuite/c-c++-common/raw-string-directive-4.c b/gcc/testsuite/c-c++-common/raw-string-directive-4.c new file mode 100644 index ..935e3a1a9911 --- /dev/null +++ b/gcc/testsuite/c-c++-common/raw-string-directive-4.c @@ -0,0 +1,8 @@ +/* { dg-options "-std=gnu99" { target c } } */ +/* { dg-options "-std=c++11" { target c++ } } */ + +/* { dg-error "invalid new-line in raw string delimiter" "" { target *-*-* } .+4 } */ +/* { dg-error "unterminated raw string" "" { target *-*-* } .+3 } */ +/* { dg-error "stray 'R' in program" "" { target *-*-* } .+2 } */ +/* { dg-warning "expected a string" "" { target *-*-* } .+1 } */ +_Pragma("message R\"\"") diff --git a/libcpp/lex.cc b/libcpp/lex.cc index c9e44e6f..a6c97e35f443 100644 --- a/libcpp/lex.cc +++ b/libcpp/lex.cc @@ -2768,7 +2768,8 @@ lex_raw_string (cpp_reader *pfile, cpp_token *token, const uchar *base) { pos--; pfile->buffer->cur = pos; - if ((pfile->state.in_directive || pfile->state.parsing_args) + if ((pfile->state.in_directive || pfile->state.parsing_args + || pfile->state.in_deferred_pragma) && pfile->buffer->next_line >= pfile->buffer->rlimit) { cpp_error_with_line (pfile, CPP_DL_ERROR, token->src_loc, 0,
[gcc r15-5535] tree-cfg: Fix call to next_discriminator_for_locus()
https://gcc.gnu.org/g:81c29232b6f36235693ec12b319f5786ba83de03 commit r15-5535-g81c29232b6f36235693ec12b319f5786ba83de03 Author: Lewis Hyatt Date: Fri Oct 25 14:55:09 2024 -0400 tree-cfg: Fix call to next_discriminator_for_locus() While testing future 64-bit location_t support, I ran into an -fcompare-debug issue that was traced back here. Despite the name, next_discriminator_for_locus() is meant to take an integer line number argument, not a location_t. There is one call site which has been passing a location_t instead. For the most part that is harmless, although in case there are two CALL stmts on the same line with different location_t, it may fail to generate a unique discriminator where it should. If/when location_t changes to be 64-bit, however, it will produce an -fcompare-debug failure. Fix it by passing the line number rather than the location_t. I am not aware of a testcase that demonstrates any observable wrong behavior, but the file debug/pr53466.C is an example where the discriminator assignment is indeed different before and after this change. gcc/ChangeLog: * tree-cfg.cc (assign_discriminators): Fix incorrect value passed to next_discriminator_for_locus(). Diff: --- gcc/tree-cfg.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc index 3eede0d61cdc..c2100a51a7a5 100644 --- a/gcc/tree-cfg.cc +++ b/gcc/tree-cfg.cc @@ -1251,7 +1251,7 @@ assign_discriminators (void) } /* Allocate a new discriminator for CALL stmt. */ if (gimple_code (stmt) == GIMPLE_CALL) - curr_discr = next_discriminator_for_locus (curr_locus); + curr_discr = next_discriminator_for_locus (curr_locus_e.line); } gimple *last = last_nondebug_stmt (bb);
[gcc r13-9214] libcpp: Fix ICE lexing invalid raw string in a deferred pragma [PR117118]
https://gcc.gnu.org/g:9f0c207d4534a909ec04f9ffa306718154e67d70 commit r13-9214-g9f0c207d4534a909ec04f9ffa306718154e67d70 Author: Lewis Hyatt Date: Mon Oct 14 17:59:46 2024 -0400 libcpp: Fix ICE lexing invalid raw string in a deferred pragma [PR117118] The PR shows that we ICE after lexing an invalid unterminated raw string, because lex_raw_string() pops the main buffer unexpectedly. Resolve by handling this case the same way as for other directives. libcpp/ChangeLog: PR preprocessor/117118 * lex.cc (lex_raw_string): Treat an unterminated raw string the same way for a deferred pragma as is done for other directives. gcc/testsuite/ChangeLog: PR preprocessor/117118 * c-c++-common/raw-string-directive-3.c: New test. * c-c++-common/raw-string-directive-4.c: New test. Diff: --- gcc/testsuite/c-c++-common/raw-string-directive-3.c | 8 gcc/testsuite/c-c++-common/raw-string-directive-4.c | 8 libcpp/lex.cc | 3 ++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/gcc/testsuite/c-c++-common/raw-string-directive-3.c b/gcc/testsuite/c-c++-common/raw-string-directive-3.c new file mode 100644 index ..fa4fa979fcef --- /dev/null +++ b/gcc/testsuite/c-c++-common/raw-string-directive-3.c @@ -0,0 +1,8 @@ +/* { dg-options "-std=gnu99" { target c } } */ +/* { dg-options "-std=c++11" { target c++ } } */ + +/* { dg-error "invalid new-line in raw string delimiter" "" { target *-*-* } .+4 } */ +/* { dg-error "unterminated raw string" "" { target *-*-* } .+3 } */ +/* { dg-error "stray 'R' in program" "" { target *-*-* } .+2 } */ +/* { dg-warning "expected a string" "" { target *-*-* } .+1 } */ +#pragma message R"" diff --git a/gcc/testsuite/c-c++-common/raw-string-directive-4.c b/gcc/testsuite/c-c++-common/raw-string-directive-4.c new file mode 100644 index ..935e3a1a9911 --- /dev/null +++ b/gcc/testsuite/c-c++-common/raw-string-directive-4.c @@ -0,0 +1,8 @@ +/* { dg-options "-std=gnu99" { target c } } */ +/* { dg-options "-std=c++11" { target c++ } } */ + +/* { dg-error "invalid new-line in raw string delimiter" "" { target *-*-* } .+4 } */ +/* { dg-error "unterminated raw string" "" { target *-*-* } .+3 } */ +/* { dg-error "stray 'R' in program" "" { target *-*-* } .+2 } */ +/* { dg-warning "expected a string" "" { target *-*-* } .+1 } */ +_Pragma("message R\"\"") diff --git a/libcpp/lex.cc b/libcpp/lex.cc index 8951ac56ee2d..d2d71761b231 100644 --- a/libcpp/lex.cc +++ b/libcpp/lex.cc @@ -2704,7 +2704,8 @@ lex_raw_string (cpp_reader *pfile, cpp_token *token, const uchar *base) { pos--; pfile->buffer->cur = pos; - if ((pfile->state.in_directive || pfile->state.parsing_args) + if ((pfile->state.in_directive || pfile->state.parsing_args + || pfile->state.in_deferred_pragma) && pfile->buffer->next_line >= pfile->buffer->rlimit) { cpp_error_with_line (pfile, CPP_DL_ERROR, token->src_loc, 0,
[gcc r15-5830] Support for 64-bit location_t: Internal parts
https://gcc.gnu.org/g:2ae0566243c8dacec17ff233e41688f05366d886 commit r15-5830-g2ae0566243c8dacec17ff233e41688f05366d886 Author: Lewis Hyatt Date: Mon Oct 28 12:52:31 2024 -0400 Support for 64-bit location_t: Internal parts Several of the selftests in diagnostic-show-locus.cc and input.cc are sensitive to linemap internals. Adjust them here so they will support 64-bit location_t if configured. Likewise, handle 64-bit location_t in the support for -fdump-internal-locations. As was done with the analyzer, convert to (unsigned long long) explicitly so that 32- and 64-bit can be handled with the same printf formats. gcc/ChangeLog: * diagnostic-show-locus.cc (test_one_liner_fixit_validation_adhoc_locations): Adapt so it can effectively test 7-bit ranges instead of 5-bit ranges. (test_one_liner_fixit_validation_adhoc_locations_utf8): Likewise. * input.cc (get_end_location): Adjust types to support 64-bit location_t. (write_digit_row): Likewise. (dump_location_range): Likewise. (dump_location_info): Likewise. (class line_table_case): Likewise. (test_accessing_ordinary_linemaps): Replace some hard-coded constants with the values defined in line-map.h. (for_each_line_table_case): Likewise. Diff: --- gcc/diagnostic-show-locus.cc | 128 --- gcc/input.cc | 100 + 2 files changed, 157 insertions(+), 71 deletions(-) diff --git a/gcc/diagnostic-show-locus.cc b/gcc/diagnostic-show-locus.cc index ef866acc253e..712b5153e673 100644 --- a/gcc/diagnostic-show-locus.cc +++ b/gcc/diagnostic-show-locus.cc @@ -4017,12 +4017,12 @@ test_one_liner_fixit_validation_adhoc_locations () { /* Generate a range that's too long to be packed, so must be stored as an ad-hoc location (given the defaults - of 5 bits or 0 bits of packed range); 41 columns > 2**5. */ + of 5 or 7 bits or 0 bits of packed range); 150 columns > 2**7. */ const location_t c7 = linemap_position_for_column (line_table, 7); - const location_t c47 = linemap_position_for_column (line_table, 47); - const location_t loc = make_location (c7, c7, c47); + const location_t c157 = linemap_position_for_column (line_table, 157); + const location_t loc = make_location (c7, c7, c157); - if (c47 > LINE_MAP_MAX_LOCATION_WITH_COLS) + if (c157 > LINE_MAP_MAX_LOCATION_WITH_COLS) return; ASSERT_TRUE (IS_ADHOC_LOC (loc)); @@ -4036,7 +4036,18 @@ test_one_liner_fixit_validation_adhoc_locations () test_diagnostic_context dc; ASSERT_STREQ (" foo = bar.field;\n" - " ^~ \n" + " ^~ " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " \n" " test\n", dc.test_show_locus (richloc)); } @@ -4044,29 +4055,62 @@ test_one_liner_fixit_validation_adhoc_locations () /* Remove. */ { rich_location richloc (line_table, loc); -source_range range = source_range::from_locations (loc, c47); +source_range range = source_range::from_locations (loc, c157); richloc.add_fixit_remove (range); /* It should not have been discarded by the validator. */ ASSERT_EQ (1, richloc.get_num_fixit_hints ()); test_diagnostic_context dc; ASSERT_STREQ (" foo = bar.field;\n" - " ^~ \n" - " -\n", + " ^~ " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " \n" + " -" + "--" + "--" + "--" + "--" + "--" + "--" + "--" + "--" + "--" + "--" + "--\n", dc.test_show_locus (richloc)); } /* Replace. */ { rich_location richloc (line_table, loc); -source_range range = source_range::from_lo
[gcc r15-5828] Support for 64-bit location_t: Backend parts
https://gcc.gnu.org/g:9bba9067598dd92dc7bae3bca242a6d350f5b799 commit r15-5828-g9bba9067598dd92dc7bae3bca242a6d350f5b799 Author: Lewis Hyatt Date: Sat Oct 26 11:13:30 2024 -0400 Support for 64-bit location_t: Backend parts A few targets have been using "unsigned int" function arguments that need to receive a "location_t". Change to "location_t" to prepare for the possibility that location_t can be configured to be a different type. gcc/ChangeLog: * config/aarch64/aarch64-c.cc (aarch64_resolve_overloaded_builtin): Change "unsigned int" argument to "location_t". * config/avr/avr-c.cc (avr_resolve_overloaded_builtin): Likewise. * config/riscv/riscv-c.cc (riscv_resolve_overloaded_builtin): Likewise. * target.def: Likewise. * doc/tm.texi: Regenerate. Diff: --- gcc/config/aarch64/aarch64-c.cc | 3 +-- gcc/config/avr/avr-c.cc | 3 +-- gcc/config/riscv/riscv-c.cc | 3 +-- gcc/doc/tm.texi | 2 +- gcc/target.def | 2 +- 5 files changed, 5 insertions(+), 8 deletions(-) diff --git a/gcc/config/aarch64/aarch64-c.cc b/gcc/config/aarch64/aarch64-c.cc index 3cc2c97c6d8e..dba103a7fb15 100644 --- a/gcc/config/aarch64/aarch64-c.cc +++ b/gcc/config/aarch64/aarch64-c.cc @@ -382,11 +382,10 @@ aarch64_pragma_aarch64 (cpp_reader *) /* Implement TARGET_RESOLVE_OVERLOADED_BUILTIN. */ static tree -aarch64_resolve_overloaded_builtin (unsigned int uncast_location, +aarch64_resolve_overloaded_builtin (location_t location, tree fndecl, void *uncast_arglist) { vec empty = {}; - location_t location = (location_t) uncast_location; vec *arglist = (uncast_arglist ? (vec *) uncast_arglist : &empty); diff --git a/gcc/config/avr/avr-c.cc b/gcc/config/avr/avr-c.cc index 7db88a8c77a1..5d7dad5a5ed8 100644 --- a/gcc/config/avr/avr-c.cc +++ b/gcc/config/avr/avr-c.cc @@ -48,11 +48,10 @@ enum avr_builtin_id /* Implement `TARGET_RESOLVE_OVERLOADED_PLUGIN'. */ static tree -avr_resolve_overloaded_builtin (unsigned int iloc, tree fndecl, void *vargs) +avr_resolve_overloaded_builtin (location_t loc, tree fndecl, void *vargs) { tree type0, type1, fold = NULL_TREE; avr_builtin_id id = AVR_BUILTIN_COUNT; - location_t loc = (location_t) iloc; vec &args = * (vec *) vargs; switch (DECL_MD_FUNCTION_CODE (fndecl)) diff --git a/gcc/config/riscv/riscv-c.cc b/gcc/config/riscv/riscv-c.cc index c59f408d3a8e..7f78e2cf019f 100644 --- a/gcc/config/riscv/riscv-c.cc +++ b/gcc/config/riscv/riscv-c.cc @@ -312,11 +312,10 @@ riscv_check_builtin_call (location_t loc, vec arg_loc, tree fndecl, /* Implement TARGET_RESOLVE_OVERLOADED_BUILTIN. */ static tree -riscv_resolve_overloaded_builtin (unsigned int uncast_location, tree fndecl, +riscv_resolve_overloaded_builtin (location_t loc, tree fndecl, void *uncast_arglist) { vec empty = {}; - location_t loc = (location_t) uncast_location; vec *arglist = (vec *) uncast_arglist; unsigned int code = DECL_MD_FUNCTION_CODE (fndecl); unsigned int subcode = code >> RISCV_BUILTIN_SHIFT; diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 05f85f83858f..64f9d7850638 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -12131,7 +12131,7 @@ ignored. This function should return the result of the call to the built-in function. @end deftypefn -@deftypefn {Target Hook} tree TARGET_RESOLVE_OVERLOADED_BUILTIN (unsigned int @var{loc}, tree @var{fndecl}, void *@var{arglist}) +@deftypefn {Target Hook} tree TARGET_RESOLVE_OVERLOADED_BUILTIN (location_t @var{loc}, tree @var{fndecl}, void *@var{arglist}) Select a replacement for a machine specific built-in function that was set up by @samp{TARGET_INIT_BUILTINS}. This is done @emph{before} regular type checking, and so allows the target to diff --git a/gcc/target.def b/gcc/target.def index cda3d4f4b8ff..413fed9bff2d 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -2497,7 +2497,7 @@ arguments passed to the built-in function. The result is a\n\ complete expression that implements the operation, usually\n\ another @code{CALL_EXPR}.\n\ @var{arglist} really has type @samp{VEC(tree,gc)*}", - tree, (unsigned int /*location_t*/ loc, tree fndecl, void *arglist), NULL) + tree, (location_t loc, tree fndecl, void *arglist), NULL) DEFHOOK (check_builtin_call,
[gcc r15-5829] Support for 64-bit location_t: toplev parts
https://gcc.gnu.org/g:8cc9d27e2db7d9f4867061c848c2d2c46a101371 commit r15-5829-g8cc9d27e2db7d9f4867061c848c2d2c46a101371 Author: Lewis Hyatt Date: Tue Nov 26 11:53:36 2024 -0500 Support for 64-bit location_t: toplev parts With the upcoming move from 32-bit to 64-bit location_t, the recommended number of range bits will change from 5 to 7. line-map.h now exports the recommended setting, so use that instead of hard-coding 5. gcc/ChangeLog: * toplev.cc (general_init): Replace hard-coded constant with line_map_suggested_range_bits. Diff: --- gcc/toplev.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/toplev.cc b/gcc/toplev.cc index 7eb7733c2761..d4a4add29f92 100644 --- a/gcc/toplev.cc +++ b/gcc/toplev.cc @@ -1136,7 +1136,7 @@ general_init (const char *argv0, bool init_signals, unique_argv original_argv) linemap_init (line_table, BUILTINS_LOCATION); line_table->m_reallocator = realloc_for_line_map; line_table->m_round_alloc_size = ggc_round_alloc_size; - line_table->default_range_bits = 5; + line_table->default_range_bits = line_map_suggested_range_bits; init_ttree (); /* Initialize register usage now so switches may override. */
[gcc r15-6016] Support for 64-bit location_t: Activate 64-bit location_t
https://gcc.gnu.org/g:d9cdc500c1e86b1218a24d1e8469930f000528d0 commit r15-6016-gd9cdc500c1e86b1218a24d1e8469930f000528d0 Author: Lewis Hyatt Date: Sat Nov 16 13:45:22 2024 -0500 Support for 64-bit location_t: Activate 64-bit location_t Change location_t to be a 64-bit integer instead of a 32-bit integer in libcpp. Also included in this change are the two other patches in the original series which depended on this one; I am committing them all at once in case it needs to be reverted later: -Support for 64-bit location_t: gimple parts The size of struct gimple increased by 8 bytes with the change in size of location_t from 32- to 64-bit; adjust the WORD markings in the comments accordingly. It seems that most of the WORD markings were off by one already, probably not having been updated after a previous reduction in the size of a gimple, so they have become retroactively correct again, and only a couple needed adjustment actually. Also add a comment that there is now 32 bits of unused padding available in struct gimple for 64-bit hosts. -Support for 64-bit location_t: Remove -flarge-source-files The option -flarge-source-files became unnecessary with 64-bit location_t and harms performance compared to the new default setting, so silently ignore it. libcpp/ChangeLog: * include/cpplib.h (struct cpp_token): Adjust comment about the struct size. * include/line-map.h (location_t): Change typedef from 32-bit to 64-bit integer. (LINE_MAP_MAX_COLUMN_NUMBER): Increase size to be appropriate for 64-bit location_t. (LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES): Likewise. (LINE_MAP_MAX_LOCATION_WITH_COLS): Likewise. (LINE_MAP_MAX_LOCATION): Likewise. (MAX_LOCATION_T): Likewise. (line_map_suggested_range_bits): Likewise. (struct line_map): Adjust comment about the struct size. (struct line_map_macro): Likewise. (struct line_map_ordinary): Likewise. Rearrange fields to optimize padding. gcc/testsuite/ChangeLog: * g++.dg/diagnostic/pr77949.C: Adapt the test for 64-bit location_t, when the previously expected failure doesn't actually happen. * g++.dg/modules/loc-prune-4.C: Adjust the expected output for the 64-bit location_t case. * gcc.dg/plugin/expensive_selftests_plugin.cc: Don't try to test the maximum supported column number in 64-bit location_t mode. * gcc.dg/plugin/location_overflow_plugin.cc: Adjust the base_location so it can effectively test 64-bit location_t. gcc/ChangeLog: * gimple.h (struct gphi): Update word marking comments to reflect the new size of location_t. (struct gimple): Likewise. Add a comment about padding. * common.opt: Mark -flarge-source-files as Ignored. * common.opt.urls: Regenerate. * doc/invoke.texi: Remove -flarge-source-files. * toplev.cc (process_options): Remove support for -flarge-source-files. Diff: --- gcc/common.opt | 5 +-- gcc/common.opt.urls| 3 -- gcc/doc/invoke.texi| 17 +--- gcc/gimple.h | 21 + gcc/testsuite/g++.dg/diagnostic/pr77949.C | 5 ++- gcc/testsuite/g++.dg/modules/loc-prune-4.C | 6 +-- .../gcc.dg/plugin/expensive_selftests_plugin.cc| 10 ++--- .../gcc.dg/plugin/location_overflow_plugin.cc | 5 +++ gcc/toplev.cc | 3 -- libcpp/include/cpplib.h| 6 ++- libcpp/include/line-map.h | 50 +- 11 files changed, 64 insertions(+), 67 deletions(-) diff --git a/gcc/common.opt b/gcc/common.opt index a42537c5f1ed..dc39f164facc 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -1808,9 +1808,8 @@ Common Undocumented Var(flag_keep_gc_roots_live) Optimization ; Always keep a pointer to a live memory block flarge-source-files -Common Var(flag_large_source_files) Init(0) -Improve GCC's ability to track column numbers in large source files, -at the expense of slower compilation. +Common Ignore +Does nothing. Preserved for backward compatibility. flate-combine-instructions Common Var(flag_late_combine_instructions) Optimization Init(0) diff --git a/gcc/common.opt.urls b/gcc/common.opt.urls index 01033a90795b..773c021dd942 100644 --- a/gcc/common.opt.urls +++ b/gcc/common.opt.urls @@ -721,9 +721,6 @@ UrlSuffix(gcc/Optimize-Options.html#index-fgraphite-identity) fhoist-adjacent-loads UrlSuffix(gcc/Optimize-Options.html#index-fhoist-adjacent-loads) -flarge-source-fil
[gcc r15-6462] tree-optimization: Fix ICE in tree-parloops.cc reduction_phi() [PR118205]
https://gcc.gnu.org/g:83e291014fff0b3ce1baedf59292390726d67335 commit r15-6462-g83e291014fff0b3ce1baedf59292390726d67335 Author: Lewis Hyatt Date: Thu Dec 26 10:58:57 2024 -0500 tree-optimization: Fix ICE in tree-parloops.cc reduction_phi() [PR118205] Prior to r15-6001, reduction_phi() could be called with the PHI parameter not actually being a gphi*. The search through reduction_list would fail and return NULL. r15-6001 added a requirement that PHI actually be a gphi*, but did not add a check for this. The PR shows an example where the check is needed; fix by explicitly returning NULL in this case. gcc/ChangeLog: PR tree-optimization/118205 * tree-parloops.cc (reduction_phi): Return NULL if PHI parameter is not a phi node. gcc/testsuite/ChangeLog: PR tree-optimization/118205 * c-c++-common/pr118205.c: New test. Diff: --- gcc/testsuite/c-c++-common/pr118205.c | 25 + gcc/tree-parloops.cc | 2 +- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/gcc/testsuite/c-c++-common/pr118205.c b/gcc/testsuite/c-c++-common/pr118205.c new file mode 100644 index ..c98f8d84a1b5 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr118205.c @@ -0,0 +1,25 @@ +/* PR tree-optimization/118205 */ + +/* { dg-do compile } */ +/* { dg-require-effective-target fgraphite } */ +/* { dg-require-effective-target pthread } */ +/* { dg-options "-O -floop-parallelize-all -ftree-parallelize-loops=2" } */ + +int x; +void g(int); +int f() { + unsigned res = 0; + int arr[] = {}; + int y = 0; + for (unsigned int i = 1; i; i++) +{ + for (int n = 0; n < 2; n++) + { + g(arr[i]); + res = y > x ? y : x; + y = res; +} + g(arr[i]); +} + return res; +} diff --git a/gcc/tree-parloops.cc b/gcc/tree-parloops.cc index 8427c287a6a7..421832973994 100644 --- a/gcc/tree-parloops.cc +++ b/gcc/tree-parloops.cc @@ -948,7 +948,7 @@ reduction_phi (reduction_info_table_type *reduction_list, gimple *phi) { struct reduction_info tmpred, *red; - if (reduction_list->is_empty () || phi == NULL) + if (reduction_list->is_empty () || phi == NULL || !is_a (phi)) return NULL; if (gimple_uid (phi) == (unsigned int)-1
[gcc r12-10942] options: Adjust cl_optimization_compare to avoid checking ICE [PR115913]
https://gcc.gnu.org/g:251f6ba9131ebc8deab463c052e099a065796c2a commit r12-10942-g251f6ba9131ebc8deab463c052e099a065796c2a Author: Lewis Hyatt Date: Sun Jan 26 18:57:00 2025 -0500 options: Adjust cl_optimization_compare to avoid checking ICE [PR115913] At the end of a sequence like: #pragma GCC push_options ... #pragma GCC pop_options the handler for pop_options calls cl_optimization_compare() (as generated by optc-save-gen.awk) to make sure that all global state has been restored to the value it had prior to the push_options call. The verification is performed for almost all entries in the global_options struct. This leads to unexpected checking asserts, as discussed in the PR, in case the state of warnings-related options has been intentionally modified in between push_options and pop_options via a call to #pragma GCC diagnostic. Address that by skipping the verification for CL_WARNING-flagged options. gcc/ChangeLog: PR middle-end/115913 * optc-save-gen.awk (cl_optimization_compare): Skip options with CL_WARNING flag. gcc/testsuite/ChangeLog: PR middle-end/115913 * c-c++-common/cpp/pr115913.c: New test. Diff: --- gcc/optc-save-gen.awk | 5 + gcc/testsuite/c-c++-common/cpp/pr115913.c | 7 +++ 2 files changed, 12 insertions(+) diff --git a/gcc/optc-save-gen.awk b/gcc/optc-save-gen.awk index 76e9b3cb9402..dd09fd38c87b 100644 --- a/gcc/optc-save-gen.awk +++ b/gcc/optc-save-gen.awk @@ -1451,6 +1451,11 @@ for (i = 0; i < n_opts; i++) { if (name == "") continue; + # We do not want to compare warning-related options, since they + # might have been modified by a #pragma GCC diagnostic. + if (flag_set_p("Warning", flags[i])) + continue; + if (name in checked_options) continue; checked_options[name]++ diff --git a/gcc/testsuite/c-c++-common/cpp/pr115913.c b/gcc/testsuite/c-c++-common/cpp/pr115913.c new file mode 100644 index ..b9d10cda8d24 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/pr115913.c @@ -0,0 +1,7 @@ +/* { dg-do preprocess } */ +/* PR middle-end/115913 */ +#pragma GCC push_options +#pragma GCC diagnostic warning "-Wundef" +/* The call to cl_optimization_compare performed by pop_options should not + lead to a checking failure. */ +#pragma GCC pop_options
[gcc r15-7323] options: Adjust cl_optimization_compare to avoid checking ICE [PR115913]
https://gcc.gnu.org/g:c0008df2118233f1afbed76ce308b4dfb6e6fc1a commit r15-7323-gc0008df2118233f1afbed76ce308b4dfb6e6fc1a Author: Lewis Hyatt Date: Sun Jan 26 18:57:00 2025 -0500 options: Adjust cl_optimization_compare to avoid checking ICE [PR115913] At the end of a sequence like: #pragma GCC push_options ... #pragma GCC pop_options the handler for pop_options calls cl_optimization_compare() (as generated by optc-save-gen.awk) to make sure that all global state has been restored to the value it had prior to the push_options call. The verification is performed for almost all entries in the global_options struct. This leads to unexpected checking asserts, as discussed in the PR, in case the state of warnings-related options has been intentionally modified in between push_options and pop_options via a call to #pragma GCC diagnostic. Address that by skipping the verification for CL_WARNING-flagged options. gcc/ChangeLog: PR middle-end/115913 * optc-save-gen.awk (cl_optimization_compare): Skip options with CL_WARNING flag. gcc/testsuite/ChangeLog: PR middle-end/115913 * c-c++-common/cpp/pr115913.c: New test. Diff: --- gcc/optc-save-gen.awk | 5 + gcc/testsuite/c-c++-common/cpp/pr115913.c | 7 +++ 2 files changed, 12 insertions(+) diff --git a/gcc/optc-save-gen.awk b/gcc/optc-save-gen.awk index fa9218472edc..a3d7e5a478e4 100644 --- a/gcc/optc-save-gen.awk +++ b/gcc/optc-save-gen.awk @@ -1484,6 +1484,11 @@ for (i = 0; i < n_opts; i++) { if (name == "") continue; + # We do not want to compare warning-related options, since they + # might have been modified by a #pragma GCC diagnostic. + if (flag_set_p("Warning", flags[i])) + continue; + if (name in checked_options) continue; checked_options[name]++ diff --git a/gcc/testsuite/c-c++-common/cpp/pr115913.c b/gcc/testsuite/c-c++-common/cpp/pr115913.c new file mode 100644 index ..b9d10cda8d24 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/pr115913.c @@ -0,0 +1,7 @@ +/* { dg-do preprocess } */ +/* PR middle-end/115913 */ +#pragma GCC push_options +#pragma GCC diagnostic warning "-Wundef" +/* The call to cl_optimization_compare performed by pop_options should not + lead to a checking failure. */ +#pragma GCC pop_options
[gcc r14-11269] options: Adjust cl_optimization_compare to avoid checking ICE [PR115913]
https://gcc.gnu.org/g:1e77549e1860249abafb8fc325fc4c1885b0d8c4 commit r14-11269-g1e77549e1860249abafb8fc325fc4c1885b0d8c4 Author: Lewis Hyatt Date: Sun Jan 26 18:57:00 2025 -0500 options: Adjust cl_optimization_compare to avoid checking ICE [PR115913] At the end of a sequence like: #pragma GCC push_options ... #pragma GCC pop_options the handler for pop_options calls cl_optimization_compare() (as generated by optc-save-gen.awk) to make sure that all global state has been restored to the value it had prior to the push_options call. The verification is performed for almost all entries in the global_options struct. This leads to unexpected checking asserts, as discussed in the PR, in case the state of warnings-related options has been intentionally modified in between push_options and pop_options via a call to #pragma GCC diagnostic. Address that by skipping the verification for CL_WARNING-flagged options. gcc/ChangeLog: PR middle-end/115913 * optc-save-gen.awk (cl_optimization_compare): Skip options with CL_WARNING flag. gcc/testsuite/ChangeLog: PR middle-end/115913 * c-c++-common/cpp/pr115913.c: New test. Diff: --- gcc/optc-save-gen.awk | 5 + gcc/testsuite/c-c++-common/cpp/pr115913.c | 7 +++ 2 files changed, 12 insertions(+) diff --git a/gcc/optc-save-gen.awk b/gcc/optc-save-gen.awk index a3af88e37760..2d36e58677b6 100644 --- a/gcc/optc-save-gen.awk +++ b/gcc/optc-save-gen.awk @@ -1467,6 +1467,11 @@ for (i = 0; i < n_opts; i++) { if (name == "") continue; + # We do not want to compare warning-related options, since they + # might have been modified by a #pragma GCC diagnostic. + if (flag_set_p("Warning", flags[i])) + continue; + if (name in checked_options) continue; checked_options[name]++ diff --git a/gcc/testsuite/c-c++-common/cpp/pr115913.c b/gcc/testsuite/c-c++-common/cpp/pr115913.c new file mode 100644 index ..b9d10cda8d24 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/pr115913.c @@ -0,0 +1,7 @@ +/* { dg-do preprocess } */ +/* PR middle-end/115913 */ +#pragma GCC push_options +#pragma GCC diagnostic warning "-Wundef" +/* The call to cl_optimization_compare performed by pop_options should not + lead to a checking failure. */ +#pragma GCC pop_options
[gcc r13-9361] options: Adjust cl_optimization_compare to avoid checking ICE [PR115913]
https://gcc.gnu.org/g:e097b376f170d531b86e6e6dc763db0ab5a8700d commit r13-9361-ge097b376f170d531b86e6e6dc763db0ab5a8700d Author: Lewis Hyatt Date: Sun Jan 26 18:57:00 2025 -0500 options: Adjust cl_optimization_compare to avoid checking ICE [PR115913] At the end of a sequence like: #pragma GCC push_options ... #pragma GCC pop_options the handler for pop_options calls cl_optimization_compare() (as generated by optc-save-gen.awk) to make sure that all global state has been restored to the value it had prior to the push_options call. The verification is performed for almost all entries in the global_options struct. This leads to unexpected checking asserts, as discussed in the PR, in case the state of warnings-related options has been intentionally modified in between push_options and pop_options via a call to #pragma GCC diagnostic. Address that by skipping the verification for CL_WARNING-flagged options. gcc/ChangeLog: PR middle-end/115913 * optc-save-gen.awk (cl_optimization_compare): Skip options with CL_WARNING flag. gcc/testsuite/ChangeLog: PR middle-end/115913 * c-c++-common/cpp/pr115913.c: New test. Diff: --- gcc/optc-save-gen.awk | 5 + gcc/testsuite/c-c++-common/cpp/pr115913.c | 7 +++ 2 files changed, 12 insertions(+) diff --git a/gcc/optc-save-gen.awk b/gcc/optc-save-gen.awk index d2cb53c477fd..05bb408d 100644 --- a/gcc/optc-save-gen.awk +++ b/gcc/optc-save-gen.awk @@ -1467,6 +1467,11 @@ for (i = 0; i < n_opts; i++) { if (name == "") continue; + # We do not want to compare warning-related options, since they + # might have been modified by a #pragma GCC diagnostic. + if (flag_set_p("Warning", flags[i])) + continue; + if (name in checked_options) continue; checked_options[name]++ diff --git a/gcc/testsuite/c-c++-common/cpp/pr115913.c b/gcc/testsuite/c-c++-common/cpp/pr115913.c new file mode 100644 index ..b9d10cda8d24 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/pr115913.c @@ -0,0 +1,7 @@ +/* { dg-do preprocess } */ +/* PR middle-end/115913 */ +#pragma GCC push_options +#pragma GCC diagnostic warning "-Wundef" +/* The call to cl_optimization_compare performed by pop_options should not + lead to a checking failure. */ +#pragma GCC pop_options
[gcc r15-6315] c++: modules: Fix 32-bit overflow with 64-bit location_t [PR117970]
https://gcc.gnu.org/g:88aa69f8126db9a2d5f93b5c6c54cc01d21d1c6e commit r15-6315-g88aa69f8126db9a2d5f93b5c6c54cc01d21d1c6e Author: Lewis Hyatt Date: Tue Dec 17 21:26:18 2024 -0500 c++: modules: Fix 32-bit overflow with 64-bit location_t [PR117970] With the move to 64-bit location_t in r15-6016, I missed a spot in module.cc where a location_t was still being stored in a 32-bit int. Fixed. The xtreme-header* tests in modules.exp were still passing fine on lots of architectures that were tested (x86-64, i686, aarch64, sparc, riscv64), but the PR shows that they were failing in some particular risc-v multilib configurations. They pass now. gcc/cp/ChangeLog: PR c++/117970 * module.cc (module_state::read_ordinary_maps): Change argument to line_map_uint_t instead of unsigned int. Diff: --- gcc/cp/module.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index c3800b0f1256..f2a4fb16c078 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -3823,7 +3823,7 @@ class GTY((chain_next ("%h.parent"), for_user)) module_state { void write_ordinary_maps (elf_out *to, range_t &, bool, unsigned *crc_ptr); - bool read_ordinary_maps (unsigned, unsigned); + bool read_ordinary_maps (line_map_uint_t, unsigned); void write_macro_maps (elf_out *to, range_t &, unsigned *crc_ptr); bool read_macro_maps (line_map_uint_t); @@ -17093,7 +17093,8 @@ module_state::write_macro_maps (elf_out *to, range_t &info, unsigned *crc_p) } bool -module_state::read_ordinary_maps (unsigned num_ord_locs, unsigned range_bits) +module_state::read_ordinary_maps (line_map_uint_t num_ord_locs, + unsigned range_bits) { bytes_in sec;
[gcc r15-5612] Support for 64-bit location_t: libcpp preliminaries
https://gcc.gnu.org/g:927625d007f47377a091d541de42c7840a4a5af6 commit r15-5612-g927625d007f47377a091d541de42c7840a4a5af6 Author: Lewis Hyatt Date: Mon Oct 28 13:19:40 2024 -0400 Support for 64-bit location_t: libcpp preliminaries Prepare libcpp to support 64-bit location_t, without yet making any functional changes, by adding new typedefs that enable code to be written such that it works with any size location_t. Update the usage of line maps within libcpp accordingly. Subsequent patches will prepare the rest of the codebase similarly, and then afterwards, location_t will be changed to uint64_t. libcpp/ChangeLog: * include/line-map.h (line_map_uint_t): New typedef, the same type as location_t. (location_diff_t): New typedef. (line_map_suggested_range_bits): New constant. (struct maps_info_ordinary): Change member types from "unsigned int" to "line_map_uint_t". (struct maps_info_macro): Likewise. (struct location_adhoc_data_map): Likewise. (LINEMAPS_ALLOCATED): Change return type from "unsigned int" to "line_map_uint_t". (LINEMAPS_ORDINARY_ALLOCATED): Likewise. (LINEMAPS_MACRO_ALLOCATED): Likewise. (LINEMAPS_USED): Likewise. (LINEMAPS_ORDINARY_USED): Likewise. (LINEMAPS_MACRO_USED): Likewise. (linemap_lookup_macro_index): Likewise. (LINEMAPS_MAP_AT): Change argument type from "unsigned int" to "line_map_uint_t". (LINEMAPS_ORDINARY_MAP_AT): Likewise. (LINEMAPS_MACRO_MAP_AT): Likewise. (line_map_new_raw): Likewise. (linemap_module_restore): Likewise. (linemap_dump): Likewise. (line_table_dump): Likewise. (LINEMAPS_LAST_MAP): Add a linemap_assert() for safety. (SOURCE_COLUMN): Use a cast to ensure correctness if location_t becomes a 64-bit type. * line-map.cc (location_adhoc_data_hash): Don't truncate to 32-bit prematurely when hashing. (line_maps::get_or_create_combined_loc): Adapt types to support potentially 64-bit location_t. Use MAX_LOCATION_T rather than a hard-coded constant. (line_maps::get_range_from_loc): Adapt types and constants to support potentially 64-bit location_t. (line_maps::pure_location_p): Likewise. (line_maps::get_pure_location): Likewise. (line_map_new_raw): Likewise. (LAST_SOURCE_LINE_LOCATION): Likewise. (linemap_add): Likewise. (linemap_module_restore): Likewise. (linemap_line_start): Likewise. (linemap_position_for_column): Likewise. (linemap_position_for_line_and_column): Likewise. (linemap_position_for_loc_and_offset): Likewise. (linemap_ordinary_map_lookup): Likewise. (linemap_lookup_macro_index): Likewise. (linemap_dump): Likewise. (linemap_dump_location): Likewise. (linemap_get_file_highest_location): Likewise. (line_table_dump): Likewise. (linemap_compare_locations): Avoid signed int overflow in the result. * macro.cc (num_expanded_macros_counter): Change type of global variable from "unsigned int" to "line_map_uint_t". (num_macro_tokens_counter): Likewise. Diff: --- libcpp/include/line-map.h | 86 - libcpp/line-map.cc| 137 ++ libcpp/macro.cc | 4 +- 3 files changed, 129 insertions(+), 98 deletions(-) diff --git a/libcpp/include/line-map.h b/libcpp/include/line-map.h index 732ec5e64452..96fdf60644f2 100644 --- a/libcpp/include/line-map.h +++ b/libcpp/include/line-map.h @@ -87,9 +87,9 @@ enum lc_reason gcc there is a single line_maps instance: "line_table", declared in gcc/input.h and defined in gcc/input.cc. - The values of the keys are intended to be internal to libcpp, - but for ease-of-understanding the implementation, they are currently - assigned as follows: + The values of the keys are intended to be internal to libcpp, but for + ease-of-understanding the implementation, they are currently assigned as + follows in the case of 32-bit location_t: Actual | Value | Meaning ---+---+--- @@ -292,6 +292,12 @@ enum lc_reason To further see how location_t works in practice, see the worked example in libcpp/location-example.txt. */ typedef unsigned int location_t; +typedef int64_t location_diff_t; + +/* Sometimes we need a type that has the same size as location_t but that does + not represent a location. This typedef provides more clarity in those + cases. *
[gcc r15-5617] gimple: Handle tail padding when computing gimple_ops_offset
https://gcc.gnu.org/g:af6665e1fdcc6bcd42db51845d7cb2f19fbda650 commit r15-5617-gaf6665e1fdcc6bcd42db51845d7cb2f19fbda650 Author: Lewis Hyatt Date: Tue Oct 29 16:57:12 2024 -0400 gimple: Handle tail padding when computing gimple_ops_offset The array gimple_ops_offset_[], which is used to find the trailing op[] array for a given gimple struct, is computed assuming that op[] will be found at sizeof(tree) bytes away from the end of the struct. This is only correct if the alignment requirement of a pointer is the same as the alignment requirement of the struct, otherwise there will be padding bytes that invalidate the calculation. On 64-bit platforms, this generally works fine because a pointer has 8-byte alignment and none of the structs make use of more than that. On 32-bit platforms, it also currently works fine because there are no 64-bit integers in the gimple structs. There are 32-bit platforms (e.g. sparc) on which a pointer has 4-byte alignment and a uint64_t has 8-byte alignment. On such platforms, adding a uint64_t to the gimple structs (as will take place when location_t is changed to be 64-bit) causes gimple_ops_offset_ to be 4 bytes too large. It would be nice to use offsetof() to compute the offset exactly, but offsetof() is not guaranteed to work for these types, because they use inheritance and so are not standard layout types. This patch attempts to detect the presence of tail padding by detecting when such padding is reused by inheritance; the padding should generally be reused for the same reason that offsetof() is not available, namely that all the relevant types use inheritance. One could envision systems on which this fix does not go far enough (e.g., if the ABI forbids reuse of tail padding), but it makes things better without affecting anything that currently works. gcc/ChangeLog: * gimple.cc (get_tail_padding_adjustment): New function. (DEFGSSTRUCT): Adjust the computation of gimple_ops_offset_ to be correct in the presence of tail padding. Diff: --- gcc/gimple.cc | 34 +- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/gcc/gimple.cc b/gcc/gimple.cc index b31c8dc9b716..c6d0991ded90 100644 --- a/gcc/gimple.cc +++ b/gcc/gimple.cc @@ -51,12 +51,36 @@ along with GCC; see the file COPYING3. If not see #include "ipa-modref.h" #include "dbgcnt.h" -/* All the tuples have their operand vector (if present) at the very bottom - of the structure. Therefore, the offset required to find the - operands vector the size of the structure minus the size of the 1 - element tree array at the end (see gimple_ops). */ +/* All the tuples have their operand vector (if present) at the very bottom of + the structure. Therefore, the offset required to find the operands vector is + the size of the structure minus the size of the 1-element tree array at the + end (see gimple_ops). An adjustment may be required if there is tail + padding, as may happen on a host (e.g. sparc) where a pointer has 4-byte + alignment while a uint64_t has 8-byte alignment. + + Unfortunately, we can't use offsetof to do this computation 100% + straightforwardly, because these structs use inheritance and so are not + standard layout types. However, the fact that they are not standard layout + types also means that tail padding will be reused in inheritance, which makes + it possible to check for the problematic case with the following logic + instead. If tail padding is detected, the offset should be decreased + accordingly. */ + +template +static constexpr size_t +get_tail_padding_adjustment () +{ + struct padding_check : G + { +tree t; + }; + return sizeof (padding_check) == sizeof (G) ? sizeof (tree) : 0; +} + #define DEFGSSTRUCT(SYM, STRUCT, HAS_TREE_OP) \ - (HAS_TREE_OP ? sizeof (struct STRUCT) - sizeof (tree) : 0), + (HAS_TREE_OP \ + ? sizeof (STRUCT) - sizeof (tree) - get_tail_padding_adjustment () \ + : 0), EXPORTED_CONST size_t gimple_ops_offset_[] = { #include "gsstruct.def" };
[gcc r15-5613] libcpp: Fix potential unaligned access in cpp_buffer
https://gcc.gnu.org/g:c93eb81c9edbf9bec6a12a2125037ec29d1cd4d2 commit r15-5613-gc93eb81c9edbf9bec6a12a2125037ec29d1cd4d2 Author: Lewis Hyatt Date: Mon Oct 28 17:57:41 2024 -0400 libcpp: Fix potential unaligned access in cpp_buffer libcpp makes use of the cpp_buffer pfile->a_buff to store things while it is handling macros. It uses it to store pointers (cpp_hashnode*, for macro arguments) and cpp_macro objects. This works fine because a cpp_hashnode* and a cpp_macro have the same alignment requirement on either 32-bit or 64-bit systems (namely, the same alignment as a pointer.) When 64-bit location_t is enabled on a 32-bit sytem, the alignment requirement may cease to be the same, because the alignment requirement of a cpp_macro object changes to that of a uint64_t, which be larger than that of a pointer. It's not the case for x86 32-bit, but for example, on sparc, a pointer has 4-byte alignment while a uint64_t has 8. In that case, intermixing the two within the same cpp_buffer leads to a misaligned access. The code path that triggers this is the one in _cpp_commit_buff in which a hash table with its own allocator (i.e. ggc) is not being used, so it doesn't happen within the compiler itself, but it happens in the other libcpp clients, such as genmatch. Fix that up by ensuring _cpp_commit_buff commits a fully aligned chunk of the buffer, so it's ready for anything it may be used for next. Also modify CPP_ALIGN so that it guarantees to return an alignment at least the size of location_t. Currently it returns the max of a pointer and a double. I am not aware of any platform where a double may have smaller alignment than a uint64_t, but it does not hurt to add location_t here to be sure. libcpp/ChangeLog: * lex.cc (_cpp_commit_buff): Make sure that the buffer is properly aligned for the next allocation. * internal.h (struct dummy): Make sure alignment is large enough for a location_t, just in case. Diff: --- libcpp/internal.h | 1 + libcpp/lex.cc | 10 -- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/libcpp/internal.h b/libcpp/internal.h index ad4e5909cfae..5f4d9cb1fa73 100644 --- a/libcpp/internal.h +++ b/libcpp/internal.h @@ -85,6 +85,7 @@ struct dummy { double d; int *p; +location_t l; } u; }; diff --git a/libcpp/lex.cc b/libcpp/lex.cc index 849447eb4d79..858970b5d171 100644 --- a/libcpp/lex.cc +++ b/libcpp/lex.cc @@ -4997,7 +4997,8 @@ _cpp_aligned_alloc (cpp_reader *pfile, size_t len) void * _cpp_commit_buff (cpp_reader *pfile, size_t size) { - void *ptr = BUFF_FRONT (pfile->a_buff); + const auto buff = pfile->a_buff; + void *ptr = BUFF_FRONT (buff); if (pfile->hash_table->alloc_subobject) { @@ -5006,7 +5007,12 @@ _cpp_commit_buff (cpp_reader *pfile, size_t size) ptr = copy; } else -BUFF_FRONT (pfile->a_buff) += size; +{ + BUFF_FRONT (buff) += size; + /* Make sure the remaining space is maximally aligned for whatever this +buffer holds next. */ + BUFF_FRONT (buff) += BUFF_ROOM (buff) % DEFAULT_ALIGNMENT; +} return ptr; }
[gcc r15-5614] Support for 64-bit location_t: Frontend parts
https://gcc.gnu.org/g:9262b6e4e5f65ec3ea49a0ecc4b3ace91cc8b388 commit r15-5614-g9262b6e4e5f65ec3ea49a0ecc4b3ace91cc8b388 Author: Lewis Hyatt Date: Mon Oct 28 12:52:23 2024 -0400 Support for 64-bit location_t: Frontend parts The C/C++ frontend code contains a couple instances where a callback receiving a "location_t" argument is prototyped to take "unsigned int" instead. This will make a difference once location_t can be configured to a different type, so adjust that now. Also remove a comment about -flarge-source-files, which will be removed shortly. gcc/c-family/ChangeLog: * c-indentation.cc (should_warn_for_misleading_indentation): Remove comment about -flarge-source-files. * c-lex.cc (cb_ident): Change "unsigned int" argument to type "location_t". (cb_def_pragma): Likewise. (cb_define): Likewise. (cb_undef): Likewise. Diff: --- gcc/c-family/c-indentation.cc | 5 - gcc/c-family/c-lex.cc | 10 +- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/gcc/c-family/c-indentation.cc b/gcc/c-family/c-indentation.cc index 6f0900032a2a..1745ec4e42eb 100644 --- a/gcc/c-family/c-indentation.cc +++ b/gcc/c-family/c-indentation.cc @@ -321,11 +321,6 @@ should_warn_for_misleading_indentation (const token_indent_info &guard_tinfo, "%<-Wmisleading-indentation%> is disabled from this point" " onwards, since column-tracking was disabled due to" " the size of the code/headers"); - if (!flag_large_source_files) - inform (guard_loc, - "adding %<-flarge-source-files%> will allow for more" - " column-tracking support, at the expense of compilation" - " time and memory"); } return false; } diff --git a/gcc/c-family/c-lex.cc b/gcc/c-family/c-lex.cc index 32f19702c79d..90ae4caa2251 100644 --- a/gcc/c-family/c-lex.cc +++ b/gcc/c-family/c-lex.cc @@ -54,10 +54,10 @@ static tree lex_charconst (const cpp_token *); static void update_header_times (const char *); static int dump_one_header (splay_tree_node, void *); static void cb_line_change (cpp_reader *, const cpp_token *, int); -static void cb_ident (cpp_reader *, unsigned int, const cpp_string *); -static void cb_def_pragma (cpp_reader *, unsigned int); -static void cb_define (cpp_reader *, unsigned int, cpp_hashnode *); -static void cb_undef (cpp_reader *, unsigned int, cpp_hashnode *); +static void cb_ident (cpp_reader *, location_t, const cpp_string *); +static void cb_def_pragma (cpp_reader *, location_t); +static void cb_define (cpp_reader *, location_t, cpp_hashnode *); +static void cb_undef (cpp_reader *, location_t, cpp_hashnode *); void init_c_lex (void) @@ -164,7 +164,7 @@ dump_time_statistics (void) static void cb_ident (cpp_reader * ARG_UNUSED (pfile), - unsigned int ARG_UNUSED (line), + location_t ARG_UNUSED (line), const cpp_string * ARG_UNUSED (str)) { if (!flag_no_ident)
[gcc r15-5618] libcpp: Fix ICE lexing invalid raw string in a deferred pragma [PR117118]
https://gcc.gnu.org/g:18cace467402a35fa2344f6b48890b2e986ad2a5 commit r15-5618-g18cace467402a35fa2344f6b48890b2e986ad2a5 Author: Lewis Hyatt Date: Mon Oct 14 17:59:46 2024 -0400 libcpp: Fix ICE lexing invalid raw string in a deferred pragma [PR117118] The PR shows that we ICE after lexing an invalid unterminated raw string, because lex_raw_string() pops the main buffer unexpectedly. Resolve by handling this case the same way as for other directives. libcpp/ChangeLog: PR preprocessor/117118 * lex.cc (lex_raw_string): Treat an unterminated raw string the same way for a deferred pragma as is done for other directives. gcc/testsuite/ChangeLog: PR preprocessor/117118 * c-c++-common/raw-string-directive-3.c: New test. * c-c++-common/raw-string-directive-4.c: New test. Diff: --- gcc/testsuite/c-c++-common/raw-string-directive-3.c | 8 gcc/testsuite/c-c++-common/raw-string-directive-4.c | 8 libcpp/lex.cc | 3 ++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/gcc/testsuite/c-c++-common/raw-string-directive-3.c b/gcc/testsuite/c-c++-common/raw-string-directive-3.c new file mode 100644 index ..fa4fa979fcef --- /dev/null +++ b/gcc/testsuite/c-c++-common/raw-string-directive-3.c @@ -0,0 +1,8 @@ +/* { dg-options "-std=gnu99" { target c } } */ +/* { dg-options "-std=c++11" { target c++ } } */ + +/* { dg-error "invalid new-line in raw string delimiter" "" { target *-*-* } .+4 } */ +/* { dg-error "unterminated raw string" "" { target *-*-* } .+3 } */ +/* { dg-error "stray 'R' in program" "" { target *-*-* } .+2 } */ +/* { dg-warning "expected a string" "" { target *-*-* } .+1 } */ +#pragma message R"" diff --git a/gcc/testsuite/c-c++-common/raw-string-directive-4.c b/gcc/testsuite/c-c++-common/raw-string-directive-4.c new file mode 100644 index ..935e3a1a9911 --- /dev/null +++ b/gcc/testsuite/c-c++-common/raw-string-directive-4.c @@ -0,0 +1,8 @@ +/* { dg-options "-std=gnu99" { target c } } */ +/* { dg-options "-std=c++11" { target c++ } } */ + +/* { dg-error "invalid new-line in raw string delimiter" "" { target *-*-* } .+4 } */ +/* { dg-error "unterminated raw string" "" { target *-*-* } .+3 } */ +/* { dg-error "stray 'R' in program" "" { target *-*-* } .+2 } */ +/* { dg-warning "expected a string" "" { target *-*-* } .+1 } */ +_Pragma("message R\"\"") diff --git a/libcpp/lex.cc b/libcpp/lex.cc index 858970b5d171..9964f5194d4f 100644 --- a/libcpp/lex.cc +++ b/libcpp/lex.cc @@ -2762,7 +2762,8 @@ lex_raw_string (cpp_reader *pfile, cpp_token *token, const uchar *base) { pos--; pfile->buffer->cur = pos; - if ((pfile->state.in_directive || pfile->state.parsing_args) + if ((pfile->state.in_directive || pfile->state.parsing_args + || pfile->state.in_deferred_pragma) && pfile->buffer->next_line >= pfile->buffer->rlimit) { cpp_error_with_line (pfile, CPP_DL_ERROR, token->src_loc, 0,
[gcc r15-5615] Support for 64-bit location_t: Analyzer parts
https://gcc.gnu.org/g:cd86dd5f43f7b9ea688a404840ef9d5e0f5e4cf0 commit r15-5615-gcd86dd5f43f7b9ea688a404840ef9d5e0f5e4cf0 Author: Lewis Hyatt Date: Mon Oct 28 12:55:24 2024 -0400 Support for 64-bit location_t: Analyzer parts The analyzer occasionally prints internal location_t values for debugging; adjust those parts so they will work if location_t is 64-bit. For simplicity, to avoid hassling with the printf format string, just convert to (unsigned long long) in either case. gcc/analyzer/ChangeLog: * checker-event.cc (checker_event::dump): Support printing either 32- or 64-bit location_t values. * checker-path.cc (checker_path::inject_any_inlined_call_events): Likewise. Diff: --- gcc/analyzer/checker-event.cc | 4 ++-- gcc/analyzer/checker-path.cc | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/gcc/analyzer/checker-event.cc b/gcc/analyzer/checker-event.cc index a7098ae19a13..0ba2a2477382 100644 --- a/gcc/analyzer/checker-event.cc +++ b/gcc/analyzer/checker-event.cc @@ -187,8 +187,8 @@ checker_event::dump (pretty_printer *pp) const if (m_effective_fndecl != m_original_fndecl) pp_printf (pp, " corrected from %qE", m_original_fndecl); } - pp_printf (pp, ", m_loc=%x)", -get_location ()); + pp_printf (pp, ", m_loc=%llx)", +(unsigned long long) get_location ()); } /* Dump this event to stderr (for debugging/logging purposes). */ diff --git a/gcc/analyzer/checker-path.cc b/gcc/analyzer/checker-path.cc index fd3d6efae67e..649eb23ca17f 100644 --- a/gcc/analyzer/checker-path.cc +++ b/gcc/analyzer/checker-path.cc @@ -280,8 +280,9 @@ checker_path::inject_any_inlined_call_events (logger *logger) logger->log_partial (" %qE", iter.get_block ()); if (!flag_dump_noaddr) logger->log_partial (" (%p)", iter.get_block ()); - logger->log_partial (", fndecl: %qE, callsite: 0x%x", - iter.get_fndecl (), iter.get_callsite ()); + logger->log_partial (", fndecl: %qE, callsite: 0x%llx", + iter.get_fndecl (), + (unsigned long long) iter.get_callsite ()); if (iter.get_callsite ()) dump_location (logger->get_printer (), iter.get_callsite ()); logger->end_log_line ();
[gcc r15-5616] Support for 64-bit location_t: C++ modules parts
https://gcc.gnu.org/g:c488e23f66388a684f4a7e7e38f97d3358225488 commit r15-5616-gc488e23f66388a684f4a7e7e38f97d3358225488 Author: Lewis Hyatt Date: Fri Oct 25 10:18:12 2024 -0400 Support for 64-bit location_t: C++ modules parts The modules implementation is necessarily sensitive to the internal workings of class line_map, and so it needed changes in order to handle a 64-bit location_t. The changes mostly boil down to supporting that in the debug dumping routines (which is accomplished by using a new custom code %K for that purpose), and supporting that when streaming in and out from the module (which is accomplished by using a new loc() function to go along with existing abstractions like u() or z() for streaming in and out different data types). gcc/cp/ChangeLog: * module.cc (bytes_out::loc): New function. (bytes_in::loc): New function. (struct span): Change int fields to location_diff_t. (range_t): Change from "unsigned int" to "line_map_uint_t". (struct ord_loc_info): Likewise. (struct macro_loc_info): Likewise. (class module_state): Likewise. (dumper::operator()): Add new code 'K' for dumping a location_t. (loc_spans::init): Use %K instead of %u for location_t dumps. (loc_spans::open): Likewise. (loc_spans::close): Likewise. Adjust bitwise expressions to support 64-bit location_t as well. (struct module_state_config): Change ordinary_locs and macro_locs from "unsigned int" to "line_map_uint_t". Reorder fields to improve packing. Rather than changing the constructor initializer list to match the new order, switch to NSDMI instead. (module_state::note_location): Adjust to support 64-bit location_t. (module_state::write_location): Use %K instead of %u for location_t dumps. Use loc() instead of u() for streaming location_t. (module_state::read_location): Likewise. (module_state::write_ordinary_maps): Likewise. (module_state::write_macro_maps): Likewise. (module_state::write_config): Likewise. (module_state::read_config): Likewise. (module_state::write_prepare_maps): Use %K instead of %u for location_t dumps. Adjust variable types and bitwise expressions to support 64-bit location_t. (module_state::read_ordinary_maps): Likewise. (module_state::read_macro_maps): Likewise. (preprocess_module): Adjust data types to support 64-bit number of line maps. Diff: --- gcc/cp/module.cc | 227 +++ 1 file changed, 128 insertions(+), 99 deletions(-) diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 95efed1e3c17..e5955081d4d3 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -349,6 +349,9 @@ typedef hash_map ptr_int_hash_map; /* Variable length buffer. */ namespace { + +constexpr line_map_uint_t loc_one = 1; + class data { public: class allocator { @@ -548,6 +551,7 @@ public: int i ();/* Read a signed int. */ unsigned u (); /* Read an unsigned int. */ size_t z (); /* Read a size_t. */ + location_t loc ();/* Read a location_t. */ HOST_WIDE_INT wi (); /* Read a HOST_WIDE_INT. */ unsigned HOST_WIDE_INT wu (); /* Read an unsigned HOST_WIDE_INT. */ const char *str (size_t * = NULL); /* Read a string. */ @@ -632,6 +636,7 @@ public: void i (int);/* Write signed int. */ void u (unsigned); /* Write unsigned int. */ void z (size_t s); /* Write size_t. */ + void loc (location_t); /* Write location_t. */ void wi (HOST_WIDE_INT); /* Write HOST_WIDE_INT. */ void wu (unsigned HOST_WIDE_INT); /* Write unsigned HOST_WIDE_INT. */ void str (const char *ptr) @@ -1056,6 +1061,24 @@ bytes_in::z () return wu (); } +/* location_t written as 32- or 64-bit as needed. */ + +inline void bytes_out::loc (location_t l) +{ + if (sizeof (location_t) > sizeof (unsigned)) +wu (l); + else +u (l); +} + +inline location_t bytes_in::loc () +{ + if (sizeof (location_t) > sizeof (unsigned)) +return wu (); + else +return u (); +} + /* Buffer simply memcpied. */ void * bytes_out::buf (size_t len) @@ -3209,7 +3232,7 @@ trees_out::~trees_out () /* I use half-open [first,second) ranges. */ -typedef std::pair range_t; +typedef std::pair range_t; /* A range of locations. */ typedef std::pair loc_range_t; @@ -3226,8 +3249,9 @@ public: struct span { loc_range_t ordinary; /* Ordinary map location range. */ loc_range_t macro; /* Macro map location range. */ -int ordinary_delta;/* Add to ordinary loc to get serialized loc. */ -int macro_delta; /* Likewise for macro loc. */ +/* Ad
[gcc r15-6003] Support for 64-bit location_t: RTL parts
https://gcc.gnu.org/g:5c8b978817539c5a254fc778ed926a1095aab721 commit r15-6003-g5c8b978817539c5a254fc778ed926a1095aab721 Author: Lewis Hyatt Date: Fri Dec 6 19:01:34 2024 -0500 Support for 64-bit location_t: RTL parts Some RTL objects need to store a location_t. Currently, they store it in the rt_int field of union rtunion, but in a world where location_t could be 64-bit, they need to store it in a larger variable. Unfortunately, rtunion does not currently have a 64-bit int type for that purpose, so add one. In order to avoid increasing any overhead when 64-bit locations are not in use, the new field is dedicated for location_t storage only and has type "location_t" so it will only be 64-bit if necessary. This necessitates adding a new RTX format code 'L' for locations. There are very many switch statements in the codebase that inspect the RTX format code. I took the approach of finding all of them that handle code 'i' or 'n' and making sure they handle 'L' too. I am sure that some of these call sites can never see an 'L' code, but I thought it would be safer and more future-proof to handle as many as possible, given it's just a line or two to add in most cases. gcc/ChangeLog: * rtl.def (DEBUG_INSN): Use new format code 'L' for location_t fields. (INSN): Likewise. (JUMP_INSN): Likewise. (CALL_INSN): Likewise. (ASM_INPUT): Likewise. (ASM_OPERANDS): Likewise. * rtl.h (union rtunion): Add new location_t RT_LOC member for use by the 'L' format. (struct rtx_debug_insn): Adjust comment. (struct rtx_nonjump_insn): Adjust comment. (struct rtx_call_insn): Adjust comment. (XLOC): New accessor macro for rtunion::rt_loc. (X0LOC): Likewise. (XCLOC): Likewise. (INSN_LOCATION): Use XLOC instead of XUINT to retrieve a location_t. (NOTE_MARKER_LOCATION): Likewise for XCUINT -> XCLOC. (ASM_OPERANDS_SOURCE_LOCATION): Likewise. (ASM_INPUT_SOURCE_LOCATION):Likewise. (gen_rtx_ASM_INPUT): Adjust to use sL format instead of si. (gen_rtx_INSN): Adjust prototype to use location_r rather than int for the location. * cfgrtl.cc (force_nonfallthru_and_redirect): Change type of LOC local variable from int to location_t. * rtlhash.cc (add_rtx): Support 'L' format in the switch statement. * var-tracking.cc (loc_cmp): Likewise. * alias.cc (rtx_equal_for_memref_p): Likewise. * config/alpha/alpha.cc (summarize_insn): Likewise. * config/ia64/ia64.cc (rtx_needs_barrier): Likewise. * config/rs6000/rs6000.cc (rs6000_hash_constant): Likewise. * cse.cc (hash_rtx): Likewise. (exp_equiv_p): Likewise. * cselib.cc (rtx_equal_for_cselib_1): Likewise. (cselib_hash_rtx): Likewise. (cselib_expand_value_rtx_1): Likewise. * emit-rtl.cc (copy_insn_1): Likewise. (gen_rtx_INSN): Change the location argument from int to location_t, and call the corresponding gen_rtf_fmt_* function. * final.cc (leaf_renumber_regs_insn): Support 'L' format in the switch statement. * genattrtab.cc (attr_rtx_1): Likewise. * genemit.cc (gen_exp): Likewise. * gengenrtl.cc (type_from_format): Likewise. (accessor_from_format): Likewise. * gengtype.cc (adjust_field_rtx_def): Likewise. * genpeep.cc (match_rtx): Likewise; just mark gcc_unreachable() for now. * genrecog.cc (find_operand): Support 'L' format in the switch statement. (find_matching_operand): Likewise. (validate_pattern): Likewise. * gensupport.cc (subst_pattern_match): Likewise. (get_alternatives_number): Likewise. (collect_insn_data): Likewise. (alter_predicate_for_insn): Likewise. (alter_constraints): Likewise. (subst_dup): Likewise. * jump.cc (rtx_renumbered_equal_p): Likewise. * loop-invariant.cc (hash_invariant_expr_1): Likewise. * lra-constraints.cc (operands_match_p): Likewise. * lra.cc (lra_rtx_hash): Likewise. * print-rtl.cc (rtx_writer::print_rtx_operand_code_i): Refactor location_t-relevant code to... (rtx_writer::print_rtx_operand_code_L): ...new function here. (rtx_writer::print_rtx_operand): Support 'L' format in the switch statement. * print-rtl.h (rtx_writer::print_rtx_operand_code_L): Add prototype for new function. * read-rtl-function.cc (function_reader::read_rtx_operand): Support 'L' format in the switch statement. (functio
[gcc r15-6001] middle-end: Handle resized PHI nodes in loop_version()
https://gcc.gnu.org/g:568b3b30218715ff0b2b8f6404fc8bce819d6153 commit r15-6001-g568b3b30218715ff0b2b8f6404fc8bce819d6153 Author: Lewis Hyatt Date: Fri Dec 6 19:01:27 2024 -0500 middle-end: Handle resized PHI nodes in loop_version() While testing upcoming support for 64-bit location_t, I came across some test failures on sparc (32-bit) that trigger when location_t is changed to be 64-bit. The reason is that several call sites that make use of loop_version() for performing loop optimizations assume that a gphi* obtained prior to calling loop_version() will remain valid afterwards, but this is not the case for a PHI that needs to be resized. It doesn't happen usually, because PHI nodes usually have room for at least 4 arguments and this is usually more than are needed, but this is not guaranteed. Fix the affected callers by avoiding the assumption that a PHI node pointer remains valid. For most cases, this is done by remembering instead the gphi->result pointer, which contains a pointer back to the PHI node that is kept up to date when the PHI is moved to a new address. gcc/ChangeLog: * tree-parloops.cc (struct reduction_info): Store the result of the reduction PHI rather than the PHI itself. (reduction_info::reduc_phi): New member function. (reduction_hasher::equal): Adapt to the change in struct reduction_info. (reduction_phi): Likewise. (initialize_reductions): Likewise. (create_call_for_reduction_1): Likewise. (transform_to_exit_first_loop_alt): Likewise. (transform_to_exit_first_loop): Likewise. (build_new_reduction): Likewise. (set_reduc_phi_uids): Likewise. (try_create_reduction_list): Likewise. * tree-ssa-loop-split.cc (split_loop): Remember the PHI result variable so that the PHI can be found in case it is resized and move to a new address. * tree-vect-loop-manip.cc (vect_loop_versioning): After calling loop_version(), fix up stored PHI pointers in case they have changed. * tree-vectorizer.cc (vec_info::resync_stmt_addr): New function. * tree-vectorizer.h (vec_info::resync_stmt_addr): Declare. Diff: --- gcc/tree-parloops.cc| 40 +--- gcc/tree-ssa-loop-split.cc | 7 +++ gcc/tree-vect-loop-manip.cc | 8 gcc/tree-vectorizer.cc | 23 +++ gcc/tree-vectorizer.h | 1 + 5 files changed, 64 insertions(+), 15 deletions(-) diff --git a/gcc/tree-parloops.cc b/gcc/tree-parloops.cc index 13d8e84bc8f3..8427c287a6a7 100644 --- a/gcc/tree-parloops.cc +++ b/gcc/tree-parloops.cc @@ -895,7 +895,7 @@ parloops_force_simple_reduction (loop_vec_info loop_info, stmt_vec_info phi_info struct reduction_info { gimple *reduc_stmt; /* reduction statement. */ - gimple *reduc_phi; /* The phi node defining the reduction. */ + tree reduc_phi_name; /* The result of the phi node defining the reduction. */ enum tree_code reduction_code;/* code for the reduction operation. */ unsigned reduc_version; /* SSA_NAME_VERSION of original reduc_phi result. */ @@ -910,6 +910,12 @@ struct reduction_info will be passed to the atomic operation. Represents the local result each thread computed for the reduction operation. */ + + gphi * + reduc_phi () const + { +return as_a (SSA_NAME_DEF_STMT (reduc_phi_name)); + } }; /* Reduction info hashtable helpers. */ @@ -925,7 +931,7 @@ struct reduction_hasher : free_ptr_hash inline bool reduction_hasher::equal (const reduction_info *a, const reduction_info *b) { - return (a->reduc_phi == b->reduc_phi); + return (a->reduc_phi_name == b->reduc_phi_name); } inline hashval_t @@ -949,10 +955,10 @@ reduction_phi (reduction_info_table_type *reduction_list, gimple *phi) || gimple_uid (phi) == 0) return NULL; - tmpred.reduc_phi = phi; + tmpred.reduc_phi_name = gimple_phi_result (phi); tmpred.reduc_version = gimple_uid (phi); red = reduction_list->find (&tmpred); - gcc_assert (red == NULL || red->reduc_phi == phi); + gcc_assert (red == NULL || red->reduc_phi () == phi); return red; } @@ -1294,7 +1300,7 @@ initialize_reductions (reduction_info **slot, class loop *loop) from the preheader with the reduction initialization value. */ /* Initialize the reduction. */ - type = TREE_TYPE (PHI_RESULT (reduc->reduc_phi)); + type = TREE_TYPE (reduc->reduc_phi_name); init = omp_reduction_init_op (gimple_location (reduc->reduc_stmt), reduc->reduction_code, type); reduc->init = init; @@ -1308,11 +1314,11 @@ initialize_reductio
[gcc r15-6004] Support for 64-bit location_t: libgdiagnostics parts
https://gcc.gnu.org/g:85018b146cd30a4a594b46cdb0e3683c8e908568 commit r15-6004-g85018b146cd30a4a594b46cdb0e3683c8e908568 Author: Lewis Hyatt Date: Fri Dec 6 19:01:37 2024 -0500 Support for 64-bit location_t: libgdiagnostics parts Tweak libgdiagnostics.cc, which is necessarily sensitive to line-map internals, to support 64-bit location_t as well. gcc/ChangeLog: * libgdiagnostics.cc (struct diagnostic_manager): Use location_t(-1) instead of UINT_MAX to support 64-bit location_t as well. (diagnostic_manager::diagnostic_manager): Change hard-coded "5" to line_map_suggested_range_bits. Diff: --- gcc/libgdiagnostics.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gcc/libgdiagnostics.cc b/gcc/libgdiagnostics.cc index e5cee0958f9c..53a8423f9045 100644 --- a/gcc/libgdiagnostics.cc +++ b/gcc/libgdiagnostics.cc @@ -320,7 +320,7 @@ public: linemap_init (&m_line_table, BUILTINS_LOCATION); m_line_table.m_reallocator = xrealloc; m_line_table.m_round_alloc_size = round_alloc_size; -m_line_table.default_range_bits = 5; +m_line_table.default_range_bits = line_map_suggested_range_bits; } ~diagnostic_manager () { @@ -500,7 +500,7 @@ private: impl_client_version_info m_client_version_info; std::vector> m_sinks; hash_map m_str_to_file_map; - hash_map, + hash_map, diagnostic_physical_location *> m_location_t_map; std::vector> m_logical_locs; const diagnostic *m_current_diag;
[gcc r15-6002] final: Fix call to INSN_LOCATION on a NOTE rtl
https://gcc.gnu.org/g:eaefc8f322e86ab18cbea55e9c07348933e64317 commit r15-6002-geaefc8f322e86ab18cbea55e9c07348933e64317 Author: Lewis Hyatt Date: Fri Dec 6 19:01:32 2024 -0500 final: Fix call to INSN_LOCATION on a NOTE rtl This function has a code path that calls INSN_LOCATION on an rtl note. For a note, this returns the note type enum rather than a location, but it runs without complaint even with --enable-checking=rtl because both are stored in the rt_int member of the rtunion. A subsequent commit will add a new rtl format code specifically for locations, in which case attempting to call INSN_LOCATION on a note will trigger an error. Fix it up by handling the case of a note missing a location separately. gcc/ChangeLog: * final.cc (reemit_insn_block_notes): Don't try to call INSN_LOCATION on a NOTE rtl object. Don't call change_scope () for a NOTE missing a location. Diff: --- gcc/final.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gcc/final.cc b/gcc/final.cc index 4d3d056cb56e..a6936963f995 100644 --- a/gcc/final.cc +++ b/gcc/final.cc @@ -1513,6 +1513,8 @@ reemit_insn_block_notes (void) case NOTE_INSN_BEGIN_STMT: case NOTE_INSN_INLINE_ENTRY: this_block = LOCATION_BLOCK (NOTE_MARKER_LOCATION (insn)); + if (!this_block) + continue; goto set_cur_block_to_this_block; default: @@ -1538,7 +1540,6 @@ reemit_insn_block_notes (void) this_block = choose_inner_scope (this_block, insn_scope (body->insn (i))); } -set_cur_block_to_this_block: if (! this_block) { if (INSN_LOCATION (insn) == UNKNOWN_LOCATION) @@ -1547,6 +1548,7 @@ reemit_insn_block_notes (void) this_block = DECL_INITIAL (cfun->decl); } +set_cur_block_to_this_block: if (this_block != cur_block) { change_scope (insn, cur_block, this_block);
[gcc r15-6430] libcpp: Fix overly large buffer allocation
https://gcc.gnu.org/g:27af1a14f3a0c897f5da3fc36cd2f9fe5ca4b0ed commit r15-6430-g27af1a14f3a0c897f5da3fc36cd2f9fe5ca4b0ed Author: Lewis Hyatt Date: Tue Oct 22 15:23:40 2024 -0400 libcpp: Fix overly large buffer allocation It seems that tokens_buff_new() has always been allocating the virtual location buffer 4 times larger than intended, and now that location_t is 64-bit, it is 8 times larger. Fixed. libcpp/ChangeLog: * macro.cc (tokens_buff_new): Fix length argument to XNEWVEC. Diff: --- libcpp/macro.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libcpp/macro.cc b/libcpp/macro.cc index 0b8eebee0610..66c0bb031456 100644 --- a/libcpp/macro.cc +++ b/libcpp/macro.cc @@ -2579,10 +2579,8 @@ tokens_buff_new (cpp_reader *pfile, size_t len, location_t **virt_locs) { size_t tokens_size = len * sizeof (cpp_token *); - size_t locs_size = len * sizeof (location_t); - if (virt_locs != NULL) -*virt_locs = XNEWVEC (location_t, locs_size); +*virt_locs = XNEWVEC (location_t, len); return _cpp_get_buff (pfile, tokens_size); }
[gcc r16-179] c-family: Improve location for -Wunknown-pragmas in a _Pragma [PR118838]
https://gcc.gnu.org/g:78673484b4055b93207eee0efd60a434b0bf96ab commit r16-179-g78673484b4055b93207eee0efd60a434b0bf96ab Author: Lewis Hyatt Date: Tue Feb 11 13:45:41 2025 -0500 c-family: Improve location for -Wunknown-pragmas in a _Pragma [PR118838] The warning for -Wunknown-pragmas is issued at the location provided by libcpp to the def_pragma() callback. This location is cpp_reader::directive_line, which is a location for the start of the line only; it is also not a valid location in case the unknown pragma was lexed from a _Pragma string. These factors make it impossible to suppress -Wunknown-pragmas via _Pragma("GCC diagnostic...") directives on the same source line, as in the PR and the test case. Address that by issuing the warning at a better location returned by cpp_get_diagnostic_override_loc(). libcpp already maintains this location to handle _Pragma-related diagnostics internally; it was needed also to make a publicly accessible version of it. gcc/c-family/ChangeLog: PR c/118838 * c-lex.cc (cb_def_pragma): Call cpp_get_diagnostic_override_loc() to get a valid location at which to issue -Wunknown-pragmas, in case it was triggered from a _Pragma. libcpp/ChangeLog: PR c/118838 * errors.cc (cpp_get_diagnostic_override_loc): New function. * include/cpplib.h (cpp_get_diagnostic_override_loc): Declare. gcc/testsuite/ChangeLog: PR c/118838 * c-c++-common/cpp/pragma-diagnostic-loc-2.c: New test. * g++.dg/gomp/macro-4.C: Adjust expected output. * gcc.dg/gomp/macro-4.c: Likewise. * gcc.dg/cpp/Wunknown-pragmas-1.c: Likewise. Diff: --- gcc/c-family/c-lex.cc | 7 ++- .../c-c++-common/cpp/pragma-diagnostic-loc-2.c | 15 +++ gcc/testsuite/g++.dg/gomp/macro-4.C| 8 gcc/testsuite/gcc.dg/cpp/Wunknown-pragmas-1.c | 22 +- gcc/testsuite/gcc.dg/gomp/macro-4.c| 8 libcpp/errors.cc | 10 ++ libcpp/include/cpplib.h| 2 ++ 7 files changed, 54 insertions(+), 18 deletions(-) diff --git a/gcc/c-family/c-lex.cc b/gcc/c-family/c-lex.cc index e450c9a57f0c..fef6ae6f457b 100644 --- a/gcc/c-family/c-lex.cc +++ b/gcc/c-family/c-lex.cc @@ -248,7 +248,12 @@ cb_def_pragma (cpp_reader *pfile, location_t loc) { const unsigned char *space, *name; const cpp_token *s; - location_t fe_loc = loc; + + /* If we are processing a _Pragma, LOC is not a valid location, but libcpp +will provide a good location via this function instead. */ + location_t fe_loc = cpp_get_diagnostic_override_loc (pfile); + if (fe_loc == UNKNOWN_LOCATION) + fe_loc = loc; space = name = (const unsigned char *) ""; diff --git a/gcc/testsuite/c-c++-common/cpp/pragma-diagnostic-loc-2.c b/gcc/testsuite/c-c++-common/cpp/pragma-diagnostic-loc-2.c new file mode 100644 index ..734da2154705 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/pragma-diagnostic-loc-2.c @@ -0,0 +1,15 @@ +/* PR c/118838 */ +/* { dg-do compile } */ +/* { dg-additional-options "-Wunknown-pragmas" } */ + +/* Make sure the warnings are suppressed as expected. */ + +/* The tokens need to be all on the same line here. */ +_Pragma ("GCC diagnostic push") _Pragma ("GCC diagnostic ignored \"-Wunknown-pragmas\"") _Pragma ("__unknown__") _Pragma ("GCC diagnostic pop") + +#define MACRO \ +_Pragma ("GCC diagnostic push") \ +_Pragma ("GCC diagnostic ignored \"-Wunknown-pragmas\"") \ +_Pragma ("__unknown__") \ +_Pragma ("GCC diagnostic pop") +MACRO diff --git a/gcc/testsuite/g++.dg/gomp/macro-4.C b/gcc/testsuite/g++.dg/gomp/macro-4.C index dcc8bcbc8e5c..5aa6d97c6609 100644 --- a/gcc/testsuite/g++.dg/gomp/macro-4.C +++ b/gcc/testsuite/g++.dg/gomp/macro-4.C @@ -3,7 +3,7 @@ // { dg-options "-fopenmp -Wunknown-pragmas" } #define p _Pragma ("omp parallel") -#define omp_p _Pragma ("omp p") +#define omp_p _Pragma ("omp p") // { dg-warning "ignoring '#pragma omp _Pragma'" } void bar (void); @@ -12,18 +12,18 @@ foo (void) { #pragma omp p // { dg-warning "-:ignoring '#pragma omp _Pragma'" } bar (); - omp_p// { dg-warning "-:ignoring '#pragma omp _Pragma'" } +omp_p // { dg-note "in expansion of macro 'omp_p'" } bar (); } #define parallel serial -#define omp_parallel _Pragma ("omp parallel") +#define omp_parallel _Pragma ("omp parallel") // { dg-warning "ignoring '#pragma omp serial'" } void baz (void) { #pragma omp parallel // { dg-warning "-:ignoring '#pragma omp serial'" } bar (); - omp_parallel // { dg-warning "-:ignoring '#pragma omp serial'" } +om