From 3b8f20a10d59773f19a43affa79dd7db7846db11 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Manuel=20L=C3=B3pez-Ib=C3=A1=C3=B1ez?= Date: Tue, 22 Jul 2008 09:45:58 +0000 Subject: [PATCH] re PR preprocessor/28079 (#line range not verified without -pedantic) 2008-07-22 Manuel Lopez-Ibanez 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. From-SVN: r138049 --- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/cpp/line6.c | 7 +++++++ libcpp/ChangeLog | 7 +++++++ libcpp/directives.c | 31 +++++++++++++++++++++---------- 4 files changed, 40 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/cpp/line6.c 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 + + PR 28079 + * gcc.dg/cpp/line6.c: New. + 2008-07-21 Ralf Wildenhues * 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 + + 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 * 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. */ -- 2.30.2