The testcase noted that builtin_LINE used in a default argument was getting the location of the call in one case, and the location of the function declaration in another. The way it is used in default arguments suggests that the intent is for it to have the location of the call. This patch updates the EXPR_LOCATION of calls to builtin_LINE and builtin_FILE to match the location where the default argument is expanded, so that the result is consistent.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit 4088607eba17cb79c9bda0d5e2829705c75386b8
Author: Jason Merrill <ja...@redhat.com>
Date:   Thu Jan 16 13:54:35 2014 -0500

    	PR c++/59821
    	* tree.c (bot_manip): Update the location of builtin_LINE and
    	builtin_FILE calls.

diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 7aad1eb..ce41c3b 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -2306,7 +2306,20 @@ bot_manip (tree* tp, int* walk_subtrees, void* data)
   /* Make a copy of this node.  */
   t = copy_tree_r (tp, walk_subtrees, NULL);
   if (TREE_CODE (*tp) == CALL_EXPR)
-    set_flags_from_callee (*tp);
+    {
+      set_flags_from_callee (*tp);
+
+      /* builtin_LINE and builtin_FILE get the location where the default
+	 argument is expanded, not where the call was written.  */
+      tree callee = get_callee_fndecl (*tp);
+      if (callee && DECL_BUILT_IN (callee))
+	switch (DECL_FUNCTION_CODE (callee))
+	  {
+	  case BUILT_IN_FILE:
+	  case BUILT_IN_LINE:
+	    SET_EXPR_LOCATION (*tp, input_location);
+	  }
+    }
   return t;
 }
 
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 84fd594..8568316 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -8726,6 +8726,8 @@ means that the compiler can assume for @code{x}, set to @code{arg}, that
 @deftypefn {Built-in Function} int __builtin_LINE ()
 This function is the equivalent to the preprocessor @code{__LINE__}
 macro and returns the line number of the invocation of the built-in.
+In a C++ default argument for a function F, it gets the line number of
+the call to F.
 @end deftypefn
 
 @deftypefn {Built-in Function} {const char *} __builtin_FUNCTION ()
@@ -8736,6 +8738,8 @@ macro and returns the function name the invocation of the built-in is in.
 @deftypefn {Built-in Function} {const char *} __builtin_FILE ()
 This function is the equivalent to the preprocessor @code{__FILE__}
 macro and returns the file name the invocation of the built-in is in.
+In a C++ default argument for a function F, it gets the file name of
+the call to F.
 @end deftypefn
 
 @deftypefn {Built-in Function} void __builtin___clear_cache (char *@var{begin}, char *@var{end})
diff --git a/gcc/testsuite/g++.dg/ext/builtin-line1.C b/gcc/testsuite/g++.dg/ext/builtin-line1.C
new file mode 100644
index 0000000..21a4f59
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/builtin-line1.C
@@ -0,0 +1,17 @@
+// __builtin_LINE gets the location where the default argument is expanded.
+// { dg-do run }
+
+#include <cassert>
+struct Foo
+{
+  int line;
+  Foo( int line = __builtin_LINE() )
+    : line( line )
+  {}
+};
+
+int main()
+{
+  assert (Foo().line == __LINE__);
+  assert ((new Foo)->line == __LINE__);
+}

Reply via email to