#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'" }
--- /dev/null
+/* { 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" } */
#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'" "" { target *-*-* } 9 } */
pfile->buffer->file = pfile->buffer->prev->file;
pfile->buffer->sysp = pfile->buffer->prev->sysp;
+ /* See comment below regarding the use of expansion_loc as the location
+ for all tokens; arrange here that diagnostics issued during lexing
+ get the same treatment. */
+ const auto prev_loc_override = pfile->diagnostic_override_loc;
+ pfile->diagnostic_override_loc = expansion_loc;
+
start_directive (pfile);
_cpp_clean_line (pfile);
save_directive = pfile->directive;
make that applicable to the real buffer too. */
pfile->buffer->prev->sysp = pfile->buffer->sysp;
_cpp_pop_buffer (pfile);
+ pfile->diagnostic_override_loc = prev_loc_override;
/* Reset the old macro state before ... */
XDELETE (pfile->context);
enum cpp_warning_reason reason, rich_location *richloc,
const char *msgid, va_list *ap)
{
- bool ret;
-
if (!pfile->cb.diagnostic)
abort ();
- ret = pfile->cb.diagnostic (pfile, level, reason, richloc, _(msgid), ap);
-
- return ret;
+ if (pfile->diagnostic_override_loc && level != CPP_DL_NOTE)
+ {
+ rich_location rc2{pfile->line_table, pfile->diagnostic_override_loc};
+ rc2.set_escape_on_output (richloc->escape_on_output_p ());
+ return pfile->cb.diagnostic (pfile, level, reason, &rc2, _(msgid), ap);
+ }
+ return pfile->cb.diagnostic (pfile, level, reason, richloc, _(msgid), ap);
}
/* Print a diagnostic at the location of the previously lexed token. */
if (!pfile->cb.diagnostic)
abort ();
+ /* Don't override note locations, which will likely make the note
+ more confusing. */
+ const bool do_loc_override
+ = pfile->diagnostic_override_loc && level != CPP_DL_NOTE;
+ if (do_loc_override)
+ src_loc = pfile->diagnostic_override_loc;
rich_location richloc (pfile->line_table, src_loc);
- if (column)
+ if (column && !do_loc_override)
richloc.override_column (column);
ret = pfile->cb.diagnostic (pfile, level, reason, &richloc, _(msgid), ap);
zero of said file. */
location_t main_loc;
+ /* If non-zero, override diagnostic locations (other than DK_NOTE
+ diagnostics) to this one. */
+ location_t diagnostic_override_loc;
+
/* Returns true iff we should warn about UTF-8 bidirectional control
characters. */
bool warn_bidi_p () const