This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: GCC stack backtraces


On Wed, 12 Sep 2012, Gabriel Dos Reis wrote:

> On Wed, Sep 12, 2012 at 11:50 AM, Diego Novillo <dnovillo@google.com> wrote:
> 
> > Alternately, we could use Richi's approach I suppose (what happened to that
> > patch, btw)?
> 
> I was under the impression that the patch was good to go in; Richard?

Yes.  I've made the name adjustment agreed to - it's __builtin_FILE, etc.,
now and removed the const attribute from the builtins - they are not
really const.

Bootstrap & testing in progress, I will commit this patch if that
succeeds unless somebody objects quickly.

That allows us to get rid of the macros in vec.h that wrap the
functions using the default argument trick for -fmem-report.  Note
that --enable-gather-detailed-mem-stats use of the builtins needs
to be conditional on support for them - so beware of some more
#ifdefery or configury before you do this change.

Thanks,
Richard.

2012-09-13  Richard Guenther  <rguenther@suse.de>

	* builtin-types.def (BT_FN_CONST_STRING): Add.
	* builtins.def (BUILT_IN_FILE_LOCATION, BUILT_IN_FUNCTION_LOCATION,
	BUILT_IN_LINE_LOCATION): New builtins.
	* gimplify.c (gimplify_call_expr): Expand them.
	* doc/extend.texi (__builtin_LINE, __builtin_FUNCTION,
	__builtin_FILE): Document.

	* g++.dg/ext/builtin-location.C: New testcase.

Index: gcc/builtin-types.def
===================================================================
*** gcc/builtin-types.def.orig	2012-08-15 15:39:49.000000000 +0200
--- gcc/builtin-types.def	2012-09-13 14:27:34.815103538 +0200
*************** DEF_POINTER_TYPE (BT_PTR_PTR, BT_PTR)
*** 140,145 ****
--- 140,146 ----
  DEF_FUNCTION_TYPE_0 (BT_FN_VOID, BT_VOID)
  DEF_FUNCTION_TYPE_0 (BT_FN_BOOL, BT_BOOL)
  DEF_FUNCTION_TYPE_0 (BT_FN_PTR, BT_PTR)
+ DEF_FUNCTION_TYPE_0 (BT_FN_CONST_STRING, BT_CONST_STRING)
  DEF_FUNCTION_TYPE_0 (BT_FN_PID, BT_PID)
  DEF_FUNCTION_TYPE_0 (BT_FN_INT, BT_INT)
  DEF_FUNCTION_TYPE_0 (BT_FN_UINT, BT_UINT)
Index: gcc/builtins.def
===================================================================
*** gcc/builtins.def.orig	2012-08-15 15:39:49.000000000 +0200
--- gcc/builtins.def	2012-09-13 14:30:48.822096864 +0200
*************** DEF_BUILTIN_STUB (BUILT_IN_EH_POINTER, "
*** 801,806 ****
--- 801,811 ----
  DEF_BUILTIN_STUB (BUILT_IN_EH_FILTER, "__builtin_eh_filter")
  DEF_BUILTIN_STUB (BUILT_IN_EH_COPY_VALUES, "__builtin_eh_copy_values")
  
+ /* __FILE__, __LINE__, __FUNCTION__ as builtins.  */
+ DEF_GCC_BUILTIN (BUILT_IN_FILE_LOCATION, "FILE", BT_FN_CONST_STRING, ATTR_NOTHROW_LEAF_LIST)
+ DEF_GCC_BUILTIN (BUILT_IN_FUNCTION_LOCATION, "FUNCTION", BT_FN_CONST_STRING, ATTR_NOTHROW_LEAF_LIST)
+ DEF_GCC_BUILTIN (BUILT_IN_LINE_LOCATION, "LINE", BT_FN_INT, ATTR_NOTHROW_LEAF_LIST)
+ 
  /* Synchronization Primitives.  */
  #include "sync-builtins.def"
  
Index: gcc/gimplify.c
===================================================================
*** gcc/gimplify.c.orig	2012-09-04 15:24:24.000000000 +0200
--- gcc/gimplify.c	2012-09-13 14:27:34.825103540 +0200
*************** gimplify_call_expr (tree *expr_p, gimple
*** 2498,2518 ****
       transform all calls in the same manner as the expanders do, but
       we do transform most of them.  */
    fndecl = get_callee_fndecl (*expr_p);
!   if (fndecl && DECL_BUILT_IN (fndecl))
!     {
!       tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
! 
!       if (new_tree && new_tree != *expr_p)
! 	{
! 	  /* There was a transformation of this call which computes the
! 	     same value, but in a more efficient way.  Return and try
! 	     again.  */
! 	  *expr_p = new_tree;
! 	  return GS_OK;
! 	}
! 
!       if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
! 	  && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_VA_START)
          {
  	  builtin_va_start_p = TRUE;
  	  if (call_expr_nargs (*expr_p) < 2)
--- 2498,2508 ----
       transform all calls in the same manner as the expanders do, but
       we do transform most of them.  */
    fndecl = get_callee_fndecl (*expr_p);
!   if (fndecl
!       && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
!     switch (DECL_FUNCTION_CODE (fndecl))
!       {
!       case BUILT_IN_VA_START:
          {
  	  builtin_va_start_p = TRUE;
  	  if (call_expr_nargs (*expr_p) < 2)
*************** gimplify_call_expr (tree *expr_p, gimple
*** 2527,2532 ****
--- 2517,2556 ----
  	      *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
  	      return GS_OK;
  	    }
+ 	  break;
+ 	}
+       case BUILT_IN_LINE_LOCATION:
+ 	{
+ 	  expanded_location loc = expand_location (EXPR_LOCATION (*expr_p));
+ 	  *expr_p = build_int_cst (TREE_TYPE (*expr_p), loc.line);
+ 	  return GS_OK;
+ 	}
+       case BUILT_IN_FILE_LOCATION:
+ 	{
+ 	  expanded_location loc = expand_location (EXPR_LOCATION (*expr_p));
+ 	  *expr_p = build_string_literal (strlen (loc.file) + 1, loc.file);
+ 	  return GS_OK;
+ 	}
+       case BUILT_IN_FUNCTION_LOCATION:
+ 	{
+ 	  const char *function;
+ 	  function = IDENTIFIER_POINTER (DECL_NAME (current_function_decl));
+ 	  *expr_p = build_string_literal (strlen (function) + 1, function);
+ 	  return GS_OK;
+ 	}
+       default:
+         ;
+       }
+   if (fndecl && DECL_BUILT_IN (fndecl))
+     {
+       tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
+       if (new_tree && new_tree != *expr_p)
+ 	{
+ 	  /* There was a transformation of this call which computes the
+ 	     same value, but in a more efficient way.  Return and try
+ 	     again.  */
+ 	  *expr_p = new_tree;
+ 	  return GS_OK;
  	}
      }
  
Index: gcc/doc/extend.texi
===================================================================
*** gcc/doc/extend.texi.orig	2012-09-03 14:54:17.000000000 +0200
--- gcc/doc/extend.texi	2012-09-13 14:27:34.853103538 +0200
*************** means that the compiler can assume for x
*** 8324,8329 ****
--- 8324,8344 ----
  (char *) x - 8 is 32 byte aligned.
  @end deftypefn
  
+ @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.
+ @end deftypefn
+ 
+ @deftypefn {Built-in Function} int __builtin_FUNCTION ()
+ This function is the equivalent to the preprocessor @code{__FUNCTION__}
+ macro and returns the function name the invocation of the built-in is in.
+ @end deftypefn
+ 
+ @deftypefn {Built-in Function} int __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.
+ @end deftypefn
+ 
  @deftypefn {Built-in Function} void __builtin___clear_cache (char *@var{begin}, char *@var{end})
  This function is used to flush the processor's instruction cache for
  the region of memory between @var{begin} inclusive and @var{end}
Index: gcc/testsuite/g++.dg/ext/builtin-location.C
===================================================================
*** /dev/null	1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/g++.dg/ext/builtin-location.C	2012-09-13 14:27:34.868103539 +0200
***************
*** 0 ****
--- 1,20 ----
+ // { dg-do link }
+ 
+ #include <cstdio>
+ 
+ void bar (const char *file = __builtin_FILE (),
+ 	  const char *function = __builtin_FUNCTION (),
+ 	  int line = __builtin_LINE ())
+ {
+   printf ("%s (%s): %d\n", file, function, line);
+ }
+ 
+ int main()
+ {
+   bar ();
+   printf ("%s (%s): %d\n",
+ 	  __builtin_FILE (),
+ 	  __builtin_FUNCTION (),
+ 	  __builtin_LINE ());
+   return 0;
+ }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]