From: "Manuel López-Ibáñez" <lopezibanez@gmail.com>
To: "GCC Patches" <gcc-patches@gcc.gnu.org>
Subject: [CPP] 28079 #line range not verified without -pedantic
Date: Wed, 27 Feb 2008 17:07:00 -0000 [thread overview]
Message-ID: <6c33472e0802270639g6a83ac8exbeeaf367c6074be@mail.gmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 575 bytes --]
Currently CPP will silently convert line numbers from unsigned long to
unsigned int. It will also wrap-around line numbers higher than
ULONG_MAX. This patch adds a warning when any of these events occur.
Boostrapped and regression tested on x86_64-unknown-linux-gnu.
2008-02-27 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
PR28079
libcpp/
* directives.c (strtoul_for_line): Add a parameter 'wrapped'.
(do_line): Update call to strtoul_for_line. Warn if wrapped or if truncated.
(do_linemarker): Update call to strtoul_for_line.
testsuite/
* gcc.dg/cpp/line6.c: New.
[-- Attachment #2: fix-pr28079.diff --]
[-- Type: text/plain, Size: 4624 bytes --]
Index: gcc/testsuite/gcc.dg/cpp/line6.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/line6.c (revision 0)
+++ gcc/testsuite/gcc.dg/cpp/line6.c (revision 0)
@@ -0,0 +1,7 @@
+/* PR 28079 */
+/* { dg-do preprocess } */
+/* { dg-options "" } */
+
+#line 18446744073709551616 /* { dg-warning "line number out of range" } */
+
+#line 12312312312435 /* { dg-warning "line number out of range" "" { target *-*-* } 0 } */
Index: libcpp/directives.c
===================================================================
--- libcpp/directives.c (revision 132503)
+++ libcpp/directives.c (working copy)
@@ -99,11 +99,12 @@ static void directive_diagnostics (cpp_r
static void run_directive (cpp_reader *, int, const char *, size_t);
static char *glue_header_name (cpp_reader *);
static const char *parse_include (cpp_reader *, int *, const cpp_token ***);
static void push_conditional (cpp_reader *, int, int, const cpp_hashnode *);
static unsigned int read_flag (cpp_reader *, unsigned int);
-static int strtoul_for_line (const uchar *, unsigned int, unsigned long *);
+static int strtoul_for_line (const uchar *, unsigned int, unsigned long *,
+ bool *wrapped);
static void do_diagnostic (cpp_reader *, int, int);
static cpp_hashnode *lex_macro_node (cpp_reader *, bool);
static int undefine_macros (cpp_reader *, cpp_hashnode *, void *);
static void do_include_common (cpp_reader *, enum include_type);
static struct pragma_entry *lookup_pragma_entry (struct pragma_entry *,
@@ -818,23 +819,30 @@ read_flag (cpp_reader *pfile, unsigned i
return 0;
}
/* Subroutine of do_line and do_linemarker. Convert a number in STR,
of length LEN, to binary; store it in NUMP, and return 0 if the
- number was well-formed, 1 if not. Temporary, hopefully. */
+ number was well-formed, 1 if not. WRAPPED is set to true if the
+ number did not fit into 'unsigned long'. Temporary, hopefully. */
static int
-strtoul_for_line (const uchar *str, unsigned int len, long unsigned int *nump)
+strtoul_for_line (const uchar *str, unsigned int len, long unsigned int *nump, bool *wrapped)
{
unsigned long reg = 0;
+ unsigned long reg_prev = 0;
+
uchar c;
+ *wrapped = false;
while (len--)
{
c = *str++;
if (!ISDIGIT (c))
- return 1;
+ return 2;
reg *= 10;
reg += c - '0';
+ if (reg < reg_prev)
+ *wrapped = true;
+ reg_prev = reg;
}
*nump = reg;
return 0;
}
@@ -855,28 +863,31 @@ do_line (cpp_reader *pfile)
const char *new_file = map->to_file;
unsigned long new_lineno;
/* C99 raised the minimum limit on #line numbers. */
unsigned int cap = CPP_OPTION (pfile, c99) ? 2147483647 : 32767;
+ bool wrapped;
/* #line commands expand macros. */
token = cpp_get_token (pfile);
if (token->type != CPP_NUMBER
|| strtoul_for_line (token->val.str.text, token->val.str.len,
- &new_lineno))
+ &new_lineno, &wrapped))
{
if (token->type == CPP_EOF)
cpp_error (pfile, CPP_DL_ERROR, "unexpected end of file after #line");
else
cpp_error (pfile, CPP_DL_ERROR,
"\"%s\" after #line is not a positive integer",
cpp_token_as_text (pfile, token));
return;
}
- if (CPP_PEDANTIC (pfile) && (new_lineno == 0 || new_lineno > cap))
+ if (CPP_PEDANTIC (pfile) && (new_lineno == 0 || new_lineno > cap || wrapped))
cpp_error (pfile, CPP_DL_PEDWARN, "line number out of range");
+ else if (wrapped || new_lineno != (unsigned int) new_lineno)
+ cpp_error (pfile, CPP_DL_WARNING, "line number out of range");
token = cpp_get_token (pfile);
if (token->type == CPP_STRING)
{
cpp_string s = { 0, 0 };
@@ -909,21 +920,22 @@ do_linemarker (cpp_reader *pfile)
const char *new_file = map->to_file;
unsigned long new_lineno;
unsigned int new_sysp = map->sysp;
enum lc_reason reason = LC_RENAME;
int flag;
+ bool wrapped;
/* Back up so we can get the number again. Putting this in
_cpp_handle_directive risks two calls to _cpp_backup_tokens in
some circumstances, which can segfault. */
_cpp_backup_tokens (pfile, 1);
/* #line commands expand macros. */
token = cpp_get_token (pfile);
if (token->type != CPP_NUMBER
|| strtoul_for_line (token->val.str.text, token->val.str.len,
- &new_lineno))
+ &new_lineno, &wrapped))
{
/* Unlike #line, there does not seem to be a way to get an EOF
here. So, it should be safe to always spell the token. */
cpp_error (pfile, CPP_DL_ERROR,
"\"%s\" after # is not a positive integer",
next reply other threads:[~2008-02-27 14:40 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-02-27 17:07 Manuel López-Ibáñez [this message]
2008-02-29 20:09 ` Mark Mitchell
2008-02-29 20:20 ` Manuel López-Ibáñez
2008-02-29 22:05 ` Mark Mitchell
2008-03-07 15:34 ` Tom Tromey
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=6c33472e0802270639g6a83ac8exbeeaf367c6074be@mail.gmail.com \
--to=lopezibanez@gmail.com \
--cc=gcc-patches@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).