[PATCH] Postpone __LINE__ evaluation to the end of #line directives
mtewoodbury@gmail.com
mtewoodbury@gmail.com
Wed Nov 27 12:12:00 GMT 2013
From: Max TenEyck Woodbury <max+git@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
More information about the Gcc-patches
mailing list