mirror of git://gcc.gnu.org/git/gcc.git
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.
This commit is contained in:
parent
dea7b9a78b
commit
78673484b4
|
|
@ -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 *) "";
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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'" }
|
||||
omp_parallel // { dg-note "in expansion of macro 'omp_parallel'" }
|
||||
bar ();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,21 +8,25 @@
|
|||
#pragma unknown1 /* { dg-warning "-:unknown1" "unknown1" } */
|
||||
|
||||
#define COMMA ,
|
||||
#define FOO(x) x
|
||||
#define BAR(x) _Pragma("unknown_before") x
|
||||
#define BAZ(x) x _Pragma("unknown_after")
|
||||
#define FOO(x) x /* { dg-note "in definition of macro 'FOO'" } */
|
||||
|
||||
int _Pragma("unknown2") bar1; /* { dg-warning "-:unknown2" "unknown2" } */
|
||||
#define BAR1(x) _Pragma("unknown_before1") x /* { dg-warning "unknown_before1" } */
|
||||
#define BAR2(x) _Pragma("unknown_before2") x /* { dg-warning "unknown_before2" } */
|
||||
|
||||
FOO(int _Pragma("unknown3") bar2); /* { dg-warning "-:unknown3" "unknown3" } */
|
||||
#define BAZ1(x) x _Pragma("unknown_after1") /* { dg-warning "unknown_after1" } */
|
||||
#define BAZ2(x) x _Pragma("unknown_after2") /* { dg-warning "unknown_after2" } */
|
||||
|
||||
int BAR(bar3); /* { dg-warning "-:unknown_before" "unknown_before 1" } */
|
||||
int _Pragma("unknown2") bar1; /* { dg-warning "unknown2" "unknown2" } */
|
||||
|
||||
BAR(int bar4); /* { dg-warning "-:unknown_before" "unknown_before 2" } */
|
||||
FOO(int _Pragma("unknown3") bar2); /* { dg-warning "unknown3" "unknown3" } */
|
||||
|
||||
int BAZ(bar5); /* { dg-warning "-:unknown_after" "unknown_after 1" } */
|
||||
int BAR1(bar3); /* { dg-note "in expansion of macro 'BAR1'" } */
|
||||
|
||||
int BAZ(bar6;) /* { dg-warning "-:unknown_after" "unknown_after 2" } */
|
||||
BAR2(int bar4); /* { dg-note "in expansion of macro 'BAR2'" } */
|
||||
|
||||
int BAZ1(bar5); /* { dg-note "in expansion of macro 'BAZ1'" } */
|
||||
|
||||
int BAZ2(bar6;) /* { dg-note "in expansion of macro 'BAZ2'" } */
|
||||
|
||||
FOO(int bar7; _Pragma("unknown4")) /* { dg-warning "-:unknown4" "unknown4" } */
|
||||
|
||||
|
|
|
|||
|
|
@ -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'" } */
|
||||
omp_parallel /* { dg-note "in expansion of macro 'omp_parallel'" } */
|
||||
bar ();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,6 +52,16 @@ cpp_diagnostic_get_current_location (cpp_reader *pfile)
|
|||
}
|
||||
}
|
||||
|
||||
/* Sometimes a diagnostic needs to be generated before libcpp has been able
|
||||
to generate a valid location for the current token; in that case, the
|
||||
non-zero location returned by this function is the preferred one to use. */
|
||||
|
||||
location_t
|
||||
cpp_get_diagnostic_override_loc (const cpp_reader *pfile)
|
||||
{
|
||||
return pfile->diagnostic_override_loc;
|
||||
}
|
||||
|
||||
/* Print a diagnostic at the given location. */
|
||||
|
||||
ATTRIBUTE_CPP_PPDIAG (5, 0)
|
||||
|
|
|
|||
|
|
@ -1169,6 +1169,8 @@ extern const char *cpp_probe_header_unit (cpp_reader *, const char *file,
|
|||
extern const char *cpp_get_narrow_charset_name (cpp_reader *) ATTRIBUTE_PURE;
|
||||
extern const char *cpp_get_wide_charset_name (cpp_reader *) ATTRIBUTE_PURE;
|
||||
|
||||
extern location_t cpp_get_diagnostic_override_loc (const cpp_reader *);
|
||||
|
||||
/* This function reads the file, but does not start preprocessing. It
|
||||
returns the name of the original file; this is the same as the
|
||||
input file, except for preprocessed input. This will generate at
|
||||
|
|
|
|||
Loading…
Reference in New Issue