Bug 61817 - Inconsistent location of tokens in the expansion list of a built-in macro
Summary: Inconsistent location of tokens in the expansion list of a built-in macro
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: preprocessor (show other bugs)
Version: 5.0
: P3 normal
Target Milestone: ---
Assignee: Richard Henderson
URL:
Keywords:
: 61861 (view as bug list)
Depends on:
Blocks: 60723
  Show dependency treegraph
 
Reported: 2014-07-16 08:47 UTC by Dodji Seketeli
Modified: 2018-10-18 04:45 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2014-07-16 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Dodji Seketeli 2014-07-16 08:47:41 UTC
Consider this function-like macro definition in the inc.h file

------------------->inc.h<-------------------
#define F() const int line = __LINE__
------------------->8<-----------------------

Now consider its use in a file test.c:

------------------>cat -n test.c<----------------
     1  #include "inc.h"
     2
     3  void
     4  foo()
     5  {
     6    F
     7      (
     8       )
     9      ;
    10  }
------------------->8<---------------------

Running test.c through cc1 -quiet -E yields:

--------------------->8<--------------------
# 1 "test.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "test.c"
# 1 "inc.h" 1
# 2 "test.c" 2

void
foo()
{
  const int line =

 8
    ;                                                                                                                                                                   
}
--------------------->8<----------------------

Note how tokens "const", "int", "line" and "=" are all on the same line as the expansion point of the function-like F() macro, but how the token "8", resulting from the expansion of the built-in macro __FILE__ is on the same line as the closing parenthesis of the invocation of F().

This is the problem.  The result of the __FILE__ macro should be "6" and should be on the same line (line 6) as the other tokens of the expansion-list of F().

This issue actually holds for the expansion of all built-in macros.


So more generelly, I would describe the issue as such:

When expanded in a function-like macro, the location of resulting tokens of a built-in macro is set to the closing parenthesis of the enclosing function-like macro invocation, rather than being set to the location of the expansion point of the invocation the enclosing functin-like macro.
Comment 1 Dodji Seketeli 2014-08-08 15:59:10 UTC
I sent a patch for this at http://comments.gmane.org/gmane.comp.gcc.patches/316794
Comment 2 Dodji Seketeli 2014-08-08 16:06:45 UTC
*** Bug 61861 has been marked as a duplicate of this bug. ***
Comment 3 Martin Sebor 2015-03-30 15:44:55 UTC
The question of what value a __LINE__ macro should expand in the invocation of a function-like macro that spans multiple lines was discussed by the C committee in February 2015.  The consensus in the discussion was that:

1) the __LINE__ macro expands to the physical source line number (as opposed to logical line number)
2) the logical line number is one greater than the number of new-line characters read or introduced in translation phase 1 while processing the source file to the current token
3) __LINE__ (along with all other) tokens only come into existence in phase 3 of translation
4) in an invocation of a function-like macro, any new-line characters must be read to form the logical line containing the invocation (including its arguments)

Thus, all __LINE__ tokens that are formed as a result of the expansion of a function-like macro must expand to the number of the physical line that contains the closing parenthesis the macro invocation.

According to this interpretation the following test is expected to pass (and does with gcc 4.9 and 5):

#define F(x, y, z) a = __LINE__, b = x ## y, c = z

enum {
#line 10
    F
     (
      __LI,
      NE__,
      __LINE__
      )
};

#define A(e)  _Static_assert (e, #e)
    A (a == 15);
    A (b == 15);
    A (c == 15);

During the committee discussion it was observed that not all implementations get this right.  A paper has been submitted into the Spring 2015 mailing to reflect this issue (below).  The paper will be discussed at the April 2015 meeting in Lysaker.

http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1911.htm
Comment 4 Richard Henderson 2016-04-06 18:35:48 UTC
Author: rth
Date: Wed Apr  6 18:35:16 2016
New Revision: 234794

URL: https://gcc.gnu.org/viewcvs?rev=234794&root=gcc&view=rev
Log:
PR preprocessor/61817
PR preprocessor/69391

  * internal.h (_cpp_builtin_macro_text): Update decl.
  * macro.c (_cpp_builtin_macro_text): Accept location for __LINE__.
  (builtin_macro): Accept a second location for __LINE__.
  (enter_macro_context): Compute both virtual and real expansion
  locations for the macro.

  * gcc.dg/pr61817-1.c: New test.
  * gcc.dg/pr61817-2.c: New test.
  * gcc.dg/pr69391-1.c: New test.
  * gcc.dg/pr69391-2.c: New test.

Added:
    trunk/gcc/testsuite/gcc.dg/pr61817-1.c
    trunk/gcc/testsuite/gcc.dg/pr61817-2.c
    trunk/gcc/testsuite/gcc.dg/pr69391-1.c
    trunk/gcc/testsuite/gcc.dg/pr69391-2.c
Modified:
    trunk/gcc/testsuite/ChangeLog
    trunk/libcpp/ChangeLog
    trunk/libcpp/internal.h
    trunk/libcpp/macro.c
Comment 5 Richard Henderson 2016-04-06 18:36:10 UTC
Fixed.