c: more precise locations for some -Wpragmas diagnostics

gcc/c-family/ChangeLog:
	* c-pragma.c (GCC_BAD_AT): New macro.
	(GCC_BAD2_AT): New macro.
	(handle_pragma_pack): Use the location of the pertinent token when
	issuing diagnostics about invalid constants/actions, and trailing
	junk.
	(handle_pragma_target): Likewise for non-string "GCC option".
	(handle_pragma_message): Likewise for trailing junk.

gcc/testsuite/ChangeLog:
	* gcc.dg/bad-pragma-locations.c: New test.

Signed-off-by: David Malcolm <dmalcolm@redhat.com>
This commit is contained in:
David Malcolm 2021-11-04 17:58:27 -04:00
parent 96276f9935
commit 8722a17067
2 changed files with 107 additions and 12 deletions

View File

@ -39,6 +39,10 @@ along with GCC; see the file COPYING3. If not see
do { warning (OPT_Wpragmas, gmsgid); return; } while (0)
#define GCC_BAD2(gmsgid, arg) \
do { warning (OPT_Wpragmas, gmsgid, arg); return; } while (0)
#define GCC_BAD_AT(loc, gmsgid) \
do { warning_at (loc, OPT_Wpragmas, gmsgid); return; } while (0)
#define GCC_BAD2_AT(loc, gmsgid, arg) \
do { warning_at (loc, OPT_Wpragmas, gmsgid, arg); return; } while (0)
struct GTY(()) align_stack {
int alignment;
@ -130,6 +134,7 @@ pop_alignment (tree id)
static void
handle_pragma_pack (cpp_reader * ARG_UNUSED (dummy))
{
location_t loc;
tree x, id = 0;
int align = -1;
enum cpp_ttype token;
@ -138,7 +143,7 @@ handle_pragma_pack (cpp_reader * ARG_UNUSED (dummy))
if (pragma_lex (&x) != CPP_OPEN_PAREN)
GCC_BAD ("missing %<(%> after %<#pragma pack%> - ignored");
token = pragma_lex (&x);
token = pragma_lex (&x, &loc);
if (token == CPP_CLOSE_PAREN)
{
action = set;
@ -147,7 +152,7 @@ handle_pragma_pack (cpp_reader * ARG_UNUSED (dummy))
else if (token == CPP_NUMBER)
{
if (TREE_CODE (x) != INTEGER_CST)
GCC_BAD ("invalid constant in %<#pragma pack%> - ignored");
GCC_BAD_AT (loc, "invalid constant in %<#pragma pack%> - ignored");
align = TREE_INT_CST_LOW (x);
action = set;
if (pragma_lex (&x) != CPP_CLOSE_PAREN)
@ -167,11 +172,12 @@ handle_pragma_pack (cpp_reader * ARG_UNUSED (dummy))
else if (!strcmp (op, "pop"))
action = pop;
else
GCC_BAD2 ("unknown action %qE for %<#pragma pack%> - ignored", x);
GCC_BAD2_AT (loc, "unknown action %qE for %<#pragma pack%> - ignored",
x);
while ((token = pragma_lex (&x)) == CPP_COMMA)
{
token = pragma_lex (&x);
token = pragma_lex (&x, &loc);
if (token == CPP_NAME && id == 0)
{
id = x;
@ -179,7 +185,8 @@ handle_pragma_pack (cpp_reader * ARG_UNUSED (dummy))
else if (token == CPP_NUMBER && action == push && align == -1)
{
if (TREE_CODE (x) != INTEGER_CST)
GCC_BAD ("invalid constant in %<#pragma pack%> - ignored");
GCC_BAD_AT (loc,
"invalid constant in %<#pragma pack%> - ignored");
align = TREE_INT_CST_LOW (x);
if (align == -1)
action = set;
@ -195,8 +202,8 @@ handle_pragma_pack (cpp_reader * ARG_UNUSED (dummy))
else
GCC_BAD ("malformed %<#pragma pack%> - ignored");
if (pragma_lex (&x) != CPP_EOF)
warning (OPT_Wpragmas, "junk at end of %<#pragma pack%>");
if (pragma_lex (&x, &loc) != CPP_EOF)
warning_at (loc, OPT_Wpragmas, "junk at end of %<#pragma pack%>");
if (flag_pack_struct)
GCC_BAD ("%<#pragma pack%> has no effect with %<-fpack-struct%> - ignored");
@ -857,6 +864,7 @@ handle_pragma_diagnostic(cpp_reader *ARG_UNUSED(dummy))
static void
handle_pragma_target(cpp_reader *ARG_UNUSED(dummy))
{
location_t loc;
enum cpp_ttype token;
tree x;
bool close_paren_needed_p = false;
@ -867,16 +875,16 @@ handle_pragma_target(cpp_reader *ARG_UNUSED(dummy))
return;
}
token = pragma_lex (&x);
token = pragma_lex (&x, &loc);
if (token == CPP_OPEN_PAREN)
{
close_paren_needed_p = true;
token = pragma_lex (&x);
token = pragma_lex (&x, &loc);
}
if (token != CPP_STRING)
{
GCC_BAD ("%<#pragma GCC option%> is not a string");
GCC_BAD_AT (loc, "%<#pragma GCC option%> is not a string");
return;
}
@ -1149,6 +1157,7 @@ handle_pragma_reset_options (cpp_reader *ARG_UNUSED(dummy))
static void
handle_pragma_message (cpp_reader *ARG_UNUSED(dummy))
{
location_t loc;
enum cpp_ttype token;
tree x, message = 0;
@ -1170,8 +1179,8 @@ handle_pragma_message (cpp_reader *ARG_UNUSED(dummy))
gcc_assert (message);
if (pragma_lex (&x) != CPP_EOF)
warning (OPT_Wpragmas, "junk at end of %<#pragma message%>");
if (pragma_lex (&x, &loc) != CPP_EOF)
warning_at (loc, OPT_Wpragmas, "junk at end of %<#pragma message%>");
if (TREE_STRING_LENGTH (message) > 1)
inform (input_location, "%<#pragma message: %s%>",

View File

@ -0,0 +1,86 @@
/* Verify that we use precise locations when emitting diagnostics
about pragmas. */
/* { dg-do assemble } */
/* { dg-options "-fdiagnostics-show-caret" } */
/* pack ****************************************************************************/
#pragma pack
/* { dg-warning "missing '\\(' after '#pragma pack' - ignored" "" { target *-*-* } .-1 }
{ dg-begin-multiline-output "" }
#pragma pack
^~~~
{ dg-end-multiline-output "" } */
#pragma pack (
/* { dg-warning "malformed '#pragma pack' - ignored" "" { target *-*-* } .-1 }
{ dg-begin-multiline-output "" }
#pragma pack (
^~~~
{ dg-end-multiline-output "" } */
#pragma pack (32
/* { dg-warning "malformed '#pragma pack' - ignored" "" { target *-*-* } .-1 }
{ dg-begin-multiline-output "" }
#pragma pack (32
^~~~
{ dg-end-multiline-output "" } */
#pragma pack (3.14159
/* { dg-warning "invalid constant in '#pragma pack' - ignored" "" { target *-*-* } .-1 }
{ dg-begin-multiline-output "" }
#pragma pack (3.14159
^~~~~~~
{ dg-end-multiline-output "" } */
#pragma pack (push, 3.14159
/* { dg-warning "invalid constant in '#pragma pack' - ignored" "" { target *-*-* } .-1 }
{ dg-begin-multiline-output "" }
#pragma pack (push, 3.14159
^~~~~~~
{ dg-end-multiline-output "" } */
#pragma pack (toothbrush
/* { dg-warning "unknown action 'toothbrush' for '#pragma pack' - ignored" "" { target *-*-* } .-1 }
{ dg-begin-multiline-output "" }
#pragma pack (toothbrush
^~~~~~~~~~
{ dg-end-multiline-output "" } */
#pragma pack() pyjamas
/* { dg-warning "junk at end of '#pragma pack'" "" { target *-*-* } .-1 }
{ dg-begin-multiline-output "" }
#pragma pack() pyjamas
^~~~~~~
{ dg-end-multiline-output "" } */
/* target ****************************************************************************/
#pragma GCC target 42
/* { dg-warning "#pragma GCC option' is not a string" "" { target *-*-* } .-1 }
{ dg-begin-multiline-output "" }
#pragma GCC target 42
^~
{ dg-end-multiline-output "" } */
#pragma GCC target ( 1776
/* { dg-warning "#pragma GCC option' is not a string" "" { target *-*-* } .-1 }
{ dg-begin-multiline-output "" }
#pragma GCC target ( 1776
^~~~
{ dg-end-multiline-output "" } */
/* message ****************************************************************************/
#pragma message "foo" int
/* { dg-warning "junk at end of '#pragma message'" "" { target *-*-* } .-1 }
{ dg-message "'#pragma message: foo'" "" { target *-*-* } .-2 }
{ dg-begin-multiline-output "" }
#pragma message "foo" int
^~~
{ dg-end-multiline-output "" }
{ dg-begin-multiline-output "" }
#pragma message "foo" int
^~~~~~~
{ dg-end-multiline-output "" } */