From: Max TenEyck Woodbury <max+...@mtew.isa-geek.net> Copyright 2013 assigned to the Free Software Foundation. --- gcc/testsuite/gcc.dg/cpp/line4.c | 19 +++++++++++++++---- libcpp/directives.c | 9 ++++++++- libcpp/internal.h | 1 + libcpp/macro.c | 3 +++ 4 files changed, 27 insertions(+), 5 deletions(-)
diff --git a/gcc/testsuite/gcc.dg/cpp/line4.c b/gcc/testsuite/gcc.dg/cpp/line4.c index 84dbf96..0120a2b 100644 --- a/gcc/testsuite/gcc.dg/cpp/line4.c +++ b/gcc/testsuite/gcc.dg/cpp/line4.c @@ -13,7 +13,18 @@ enum { i = __LINE__ }; enum { j = __LINE__ }; #line 16 /* N.B. the _next_ line is line 16. */ - -char array1[i == 44 ? 1 : -1]; -char array2[j == 90 ? 1 : -1]; -char array3[__LINE__ == 19 ? 1 : -1]; + /* __LINE__ should be 16 */ +char array1[i == 44 ? 1 : -1]; /* 17 */ +char array2[j == 90 ? 1 : -1]; /* 18 */ +char array3[__LINE__ == 19 ? 1 : -1]; /* 19 */ + /* 20 */ +# line __LINE__ /* N.B. the __LINE__ sequence should _not_ change here. */ + /* 22 */ +char array4[__LINE__ == 23 ? 1: -1]; /* 23 */ +char array5[__LINE__ == 23 ? -1: 1]; /* 24 */ + /* 25 */ +# line __LINE__ /* N.B. nor shoud a multi-line comment change the fact + that the __LINE__ sequence should _not_ change here. */ + /* 28 */ +char array6[__LINE__ == 29 ? 1: -1]; /* 29 */ +char array7[__LINE__ == 27 ? -1: 1]; /* 30 */ diff --git a/libcpp/directives.c b/libcpp/directives.c index 65b2034..adb04a5 100644 --- a/libcpp/directives.c +++ b/libcpp/directives.c @@ -900,7 +900,9 @@ do_line (cpp_reader *pfile) bool wrapped; /* #line commands expand macros. */ + ++pfile->state.in_directive; /* Request special __LINE__ handling. */ token = cpp_get_token (pfile); + --pfile->state.in_directive; /* Cancle request */ if (token->type != CPP_NUMBER || strtolinenum (token->val.str.text, token->val.str.len, &new_lineno, &wrapped)) @@ -914,7 +916,9 @@ do_line (cpp_reader *pfile) return; } - if (CPP_PEDANTIC (pfile) && (new_lineno == 0 || new_lineno > cap || wrapped)) + if (CPP_PEDANTIC (pfile) && (new_lineno == 0 || + (new_lineno > cap && new_lineno != CUR__LINE__) || + 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"); @@ -936,6 +940,9 @@ do_line (cpp_reader *pfile) } skip_rest_of_line (pfile); + if ( new_lineno == CUR__LINE__ ) /* Postponed evaluation ? */ + new_lineno = linemap_get_expansion_line (pfile->line_table, + pfile->line_table->highest_line); _cpp_do_file_change (pfile, LC_RENAME_VERBATIM, new_file, new_lineno, map_sysp); } diff --git a/libcpp/internal.h b/libcpp/internal.h index 5321458..268de86 100644 --- a/libcpp/internal.h +++ b/libcpp/internal.h @@ -604,6 +604,7 @@ cpp_in_primary_file (cpp_reader *pfile) { return pfile->line_table->depth == 1; } +#define CUR__LINE__ -1U /* In macro.c */ extern void _cpp_free_definition (cpp_hashnode *); diff --git a/libcpp/macro.c b/libcpp/macro.c index e359d15..47e41b6 100644 --- a/libcpp/macro.c +++ b/libcpp/macro.c @@ -309,6 +309,9 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node) /* If __LINE__ is embedded in a macro, it must expand to the line of the macro's invocation, not its definition. Otherwise things like assert() will not work properly. */ + if ( pfile->state.in_directive > 1 ) /* In #line directive? */ + number = CUR__LINE__; /* yes, postpone the lookup... */ + else number = linemap_get_expansion_line (pfile->line_table, CPP_OPTION (pfile, traditional) ? pfile->line_table->highest_line -- 1.8.0.rc0.18.gf84667d