aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManuel Lopez-Ibanez <manu@gcc.gnu.org>2008-07-22 09:45:58 +0000
committerManuel Lopez-Ibanez <manu@gcc.gnu.org>2008-07-22 09:45:58 +0000
commit6062b9f256d9b3a8b94ff1d9e056fff8fb9fb73d (patch)
tree17d49712a4145447c738fd8de9102fd6bb8c8f50
parentf9158711b8be9f8b6c8aaf85aeadb66edaad566f (diff)
2008-07-22 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
PR 28079 libcpp/ * directives.c (strtolinenum): Handle overflow. (do_line): Give a warning if line number overflowed. (do_linemarker): Update call to strtolinenum. gcc/testsuite/ * gcc.dg/cpp/line6.c: New. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@138049 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/cpp/line6.c7
-rw-r--r--libcpp/ChangeLog7
-rw-r--r--libcpp/directives.c31
4 files changed, 40 insertions, 10 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 2e53d3a5111..21202bd3a1f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2008-07-22 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR 28079
+ * gcc.dg/cpp/line6.c: New.
+
2008-07-21 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
* gfortran.dg/fmt_g0_3.f08: Fix typo in expected error message.
diff --git a/gcc/testsuite/gcc.dg/cpp/line6.c b/gcc/testsuite/gcc.dg/cpp/line6.c
new file mode 100644
index 00000000000..c59ea3af7f1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cpp/line6.c
@@ -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 } */
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index f8ec058a47a..cb1de791edc 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,10 @@
+2008-07-22 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR 28079
+ * directives.c (strtolinenum): Handle overflow.
+ (do_line): Give a warning if line number overflowed.
+ (do_linemarker): Update call to strtolinenum.
+
2008-07-21 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
* include/line-map.h (linenum_type): New typedef.
diff --git a/libcpp/directives.c b/libcpp/directives.c
index 90933eb4807..9e0744b23d9 100644
--- a/libcpp/directives.c
+++ b/libcpp/directives.c
@@ -102,7 +102,7 @@ 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 strtolinenum (const uchar *, unsigned int, linenum_type *);
+static bool strtolinenum (const uchar *, size_t, linenum_type *, bool *);
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 *);
@@ -837,23 +837,30 @@ read_flag (cpp_reader *pfile, unsigned int last)
}
/* 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. */
-static int
-strtolinenum (const uchar *str, unsigned int len, linenum_type *nump)
+ of length LEN, to binary; store it in NUMP, and return false if the
+ number was well-formed, true if not. WRAPPED is set to true if the
+ number did not fit into 'unsigned long'. */
+static bool
+strtolinenum (const uchar *str, size_t len, linenum_type *nump, bool *wrapped)
{
linenum_type reg = 0;
+ linenum_type reg_prev = 0;
+
uchar c;
+ *wrapped = false;
while (len--)
{
c = *str++;
if (!ISDIGIT (c))
- return 1;
+ return true;
reg *= 10;
reg += c - '0';
+ if (reg < reg_prev)
+ *wrapped = true;
+ reg_prev = reg;
}
*nump = reg;
- return 0;
+ return false;
}
/* Interpret #line command.
@@ -875,12 +882,13 @@ do_line (cpp_reader *pfile)
/* C99 raised the minimum limit on #line numbers. */
linenum_type cap = CPP_OPTION (pfile, c99) ? 2147483647 : 32767;
+ bool wrapped;
/* #line commands expand macros. */
token = cpp_get_token (pfile);
if (token->type != CPP_NUMBER
|| strtolinenum (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");
@@ -891,8 +899,10 @@ do_line (cpp_reader *pfile)
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)
+ cpp_error (pfile, CPP_DL_WARNING, "line number out of range");
token = cpp_get_token (pfile);
if (token->type == CPP_STRING)
@@ -929,6 +939,7 @@ do_linemarker (cpp_reader *pfile)
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
@@ -939,7 +950,7 @@ do_linemarker (cpp_reader *pfile)
token = cpp_get_token (pfile);
if (token->type != CPP_NUMBER
|| strtolinenum (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. */