summaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authornathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>2001-04-24 08:22:06 +0000
committernathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>2001-04-24 08:22:06 +0000
commit65b7f83fcb833ccbead60bbb1533884ad0898486 (patch)
tree268353894884ce2459e1f3b08adc4825b8ed0dd6 /gcc/cp
parent2b686fc594fc9314f3585e5f0e32a8d15fb79765 (diff)
downloadgcc-65b7f83fcb833ccbead60bbb1533884ad0898486.tar.gz
gcc:
Lazy __FUNCTION__ generation. * c-common.h (RID_FUNCTION_NAME, RID_PRETTY_FUNCTION_NAME, RID_C99_FUNCTION_NAME): New _RIDs. (CTI_FUNCTION_ID, CTI_PRETTY_FUNCTION_ID, CTI_FUNC_ID): Remove. (CTI_FUNCTION_NAME_DECL, CTI_PRETTY_FUNCTION_NAME_DECL, CTI_C99_FUNCTION_NAME_DECL, CTI_SAVED_FUNCTION_NAME_DECLS): New global tree slots. (function_id_node, pretty_function_id_node, func_id_node): Remove. (c99_function_name_decl_node, function_name_decl_node, pretty_function_name_decl_node, saved_function_name_decls): Declare. (struct language_function): Remove x_function_name_declared_p. (make_fname_decl): Remove a parameter. (declare_function_names): Remove prototype. (start_fname_decls, finish_fname_decls): Prototype. (fname_as_string): Likewise. (fname_string, fname_decl): Likewise. * c-common.c (make_fname_decl): Adjust. (struct fname_var_t): New struct. (fname_vars): New static array. (declare_function_name): Remove. (start_fname_decls, finish_fname_decls): New functions. (fname_as_string): New function from remnants of declare_function_name. (fname_string, fname_decl): New functions. * c-decl.c (c_function_name_declared_p): Remove. (init_decl_processing): Don't generate __FUNCTION__ et al ids, don't call declare_function_name. Call start_fname_decls. (c_make_fname_decl): Adjust parameters. Generate the name. Don't clobber the line number. Call finish_decl. (start_function): Call start_fname_decls. (finish_function): Call finish_fname_decls. Remove c_function_name_declared_p. (push_c_function_context): Don't push c_function_name_declared_p. (pop_c_function_context): Don't pop c_function_name_declared_p. (c_begin_compound_stmt): Don't check c_function_name_declared_p. * c-parse.in (STRING_FUNC_NAME, VAR_FUNC_NAME): New tokens. (program): Call finish_fname_decls for C. (primary): Add VAR_FUNC_NAME. (reswords): Add slots for __FUNCTION__ et al. (rid_to_yy): Add mappings for __FUNCTION__ et al. (yylexname): If it's a STRING_FUNC_NAME generate the function name now. Don't look for VAR_DECLs containing __FUNCTION__ et al. * c-semantics.c (prune_unused_decls): Remove. (finish_stmt_tree): Don't call prune_unused_decls. (genrtl_decl_stmt): Don't prune unused decls here. cp: Lazy __FUNCTION__ generation. * cp-tree.def (FUNCTION_NAME): Remove. * cp-tree.h (function_name_declared_p): Remove. (cp_fname_init): Prototype. * decl.c (init_decl_processing): Don't generate __FUNCTION__ et al ids, don't call declare_function_name. Call start_fname_decls. (cp_make_fname_decl): Adjust parameters. Generate the name. Don't clobber the line number. (cp_fname_init): New function. (start_function): Call start_fname_decls. (finish_function): Call finish_fname_decls. * lex.c (reswords): Add slots for __FUNCTION__ et al. (rid_to_yy): Add mappings for __FUNCTION__ et al. * optimize.c (maybe_clone_body): Remove function_name_declared_p. * parse.y (VAR_FUNC_NAME): New token. (primary): Add VAR_FUNC_NAME. * pt.c (tsubst_decl): Adjust a DECL_PRETTY_FUNCTION_P's generation. (tsubst, FUNCTION_NAME case): Remove. (tsubst_copy, FUNCTION_NAME case): Remove. (tsubst_expr, DECL_STMT case): Be careful with a DECL_PRETTY_FUNCTION_P. (instantiate_decl): Remove function_name_declared_p. * semantics.c (begin_compound_statement): Don't call declare_function_name here. (setup_vtbl_ptr). Don't save & restore function_name_declared_p. (finish_translation_unit): Call finish_fname_decls. (expand_body): Remove function_name_declared_p. * typeck2.c (digest_init): Allow any ERROR_MARK. testsuite: * gcc.dg/c99-func-2.c: Remove xfail. * gcc.dg/c99-func-3.c: Remove xfail. * gcc.dg/c99-func-4.c: Remove xfail. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@41520 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog32
-rw-r--r--gcc/cp/cp-tree.def3
-rw-r--r--gcc/cp/cp-tree.h7
-rw-r--r--gcc/cp/decl.c103
-rw-r--r--gcc/cp/lex.c7
-rw-r--r--gcc/cp/optimize.c1
-rw-r--r--gcc/cp/parse.y10
-rw-r--r--gcc/cp/pt.c37
-rw-r--r--gcc/cp/semantics.c25
-rw-r--r--gcc/cp/typeck2.c5
10 files changed, 124 insertions, 106 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 31c1f92c7fb..69a674d954b 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,35 @@
+2001-04-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ Lazy __FUNCTION__ generation.
+ * cp-tree.def (FUNCTION_NAME): Remove.
+ * cp-tree.h (function_name_declared_p): Remove.
+ (cp_fname_init): Prototype.
+ * decl.c (init_decl_processing): Don't generate __FUNCTION__ et al ids,
+ don't call declare_function_name. Call start_fname_decls.
+ (cp_make_fname_decl): Adjust parameters. Generate the name. Don't
+ clobber the line number.
+ (cp_fname_init): New function.
+ (start_function): Call start_fname_decls.
+ (finish_function): Call finish_fname_decls.
+ * lex.c (reswords): Add slots for __FUNCTION__ et al.
+ (rid_to_yy): Add mappings for __FUNCTION__ et al.
+ * optimize.c (maybe_clone_body): Remove function_name_declared_p.
+ * parse.y (VAR_FUNC_NAME): New token.
+ (primary): Add VAR_FUNC_NAME.
+ * pt.c (tsubst_decl): Adjust a DECL_PRETTY_FUNCTION_P's
+ generation.
+ (tsubst, FUNCTION_NAME case): Remove.
+ (tsubst_copy, FUNCTION_NAME case): Remove.
+ (tsubst_expr, DECL_STMT case): Be careful with a
+ DECL_PRETTY_FUNCTION_P.
+ (instantiate_decl): Remove function_name_declared_p.
+ * semantics.c (begin_compound_statement): Don't call
+ declare_function_name here.
+ (setup_vtbl_ptr). Don't save & restore function_name_declared_p.
+ (finish_translation_unit): Call finish_fname_decls.
+ (expand_body): Remove function_name_declared_p.
+ * typeck2.c (digest_init): Allow any ERROR_MARK.
+
2001-04-24 Nathan Sidwell <nathan@codesourcery.com>
* pt.c (tsubst_decl): Use VOID_TYPE_P.
diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def
index 5e89189774d..486667c3a80 100644
--- a/gcc/cp/cp-tree.def
+++ b/gcc/cp/cp-tree.def
@@ -200,9 +200,6 @@ DEFTREECODE (WRAPPER, "wrapper", 'x', 1)
unused. */
DEFTREECODE (LOOKUP_EXPR, "lookup_expr", 'e', 1)
-/* Used to represent __PRETTY_FUNCTION__ in template bodies. */
-DEFTREECODE (FUNCTION_NAME, "function_name", 'e', 0)
-
/* A whole bunch of tree codes for the initial, superficial parsing of
templates. */
DEFTREECODE (MODOP_EXPR, "modop_expr", 'e', 3)
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index d5c358a0176..2723c316b4e 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -968,12 +968,6 @@ struct cp_language_function
#define in_function_try_handler cp_function_chain->in_function_try_handler
-/* Nonzero if __FUNCTION__ and its ilk have been declared in this
- function. */
-
-#define function_name_declared_p \
- (cp_function_chain->base.x_function_name_declared_p)
-
extern tree current_function_return_value;
extern tree global_namespace;
@@ -3911,6 +3905,7 @@ extern int nonstatic_local_decl_p PARAMS ((tree));
extern tree declare_global_var PARAMS ((tree, tree));
extern void register_dtor_fn PARAMS ((tree));
extern tmpl_spec_kind current_tmpl_spec_kind PARAMS ((int));
+extern tree cp_fname_init PARAMS ((const char *));
/* in decl2.c */
extern void init_decl2 PARAMS ((void));
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 85a73101321..834e2dcd5da 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -138,7 +138,7 @@ static tree get_atexit_node PARAMS ((void));
static tree get_dso_handle_node PARAMS ((void));
static tree start_cleanup_fn PARAMS ((void));
static void end_cleanup_fn PARAMS ((void));
-static tree cp_make_fname_decl PARAMS ((tree, const char *, int));
+static tree cp_make_fname_decl PARAMS ((tree, int));
static void initialize_predefined_identifiers PARAMS ((void));
static tree check_special_function_return_type
PARAMS ((special_function_kind, tree, tree));
@@ -6519,6 +6519,7 @@ init_decl_processing ()
{
tree bad_alloc_type_node, newtype, deltype;
+
if (flag_honor_std)
push_namespace (std_identifier);
bad_alloc_type_node = xref_tag
@@ -6526,7 +6527,8 @@ init_decl_processing ()
if (flag_honor_std)
pop_namespace ();
newtype = build_exception_variant
- (ptr_ftype_sizetype, add_exception_specifier (NULL_TREE, bad_alloc_type_node, -1));
+ (ptr_ftype_sizetype, add_exception_specifier
+ (NULL_TREE, bad_alloc_type_node, -1));
deltype = build_exception_variant (void_ftype_ptr, empty_except_spec);
push_cp_library_fn (NEW_EXPR, newtype);
push_cp_library_fn (VEC_NEW_EXPR, newtype);
@@ -6553,13 +6555,8 @@ init_decl_processing ()
if (! supports_one_only ())
flag_weak = 0;
- /* Create the global bindings for __FUNCTION__ and __PRETTY_FUNCTION__. */
- function_id_node = get_identifier ("__FUNCTION__");
- pretty_function_id_node = get_identifier ("__PRETTY_FUNCTION__");
- func_id_node = get_identifier ("__func__");
-
make_fname_decl = cp_make_fname_decl;
- declare_function_name ();
+ start_fname_decls ();
/* Prepare to check format strings against argument lists. */
init_function_format_info ();
@@ -6607,57 +6604,68 @@ init_decl_processing ()
ggc_add_tree_root (&free_bindings, 1);
}
+/* Generate an initializer for a function naming variable from
+ NAME. NAME may be NULL, in which case we generate a special
+ ERROR_MARK node which should be replaced later. */
+
+tree
+cp_fname_init (name)
+ const char *name;
+{
+ tree domain = NULL_TREE;
+ tree type;
+ tree init = NULL_TREE;
+ size_t length = 0;
+
+ if (name)
+ {
+ length = strlen (name);
+ domain = build_index_type (size_int (length));
+ init = build_string (length + 1, name);
+ }
+
+ type = build_qualified_type (char_type_node, TYPE_QUAL_CONST);
+ type = build_cplus_array_type (type, domain);
+
+ if (init)
+ TREE_TYPE (init) = type;
+ else
+ /* We don't know the value until instantiation time. Make
+ something which will be digested now, but replaced later. */
+ init = build (ERROR_MARK, type);
+
+ return init;
+}
+
/* Create the VAR_DECL for __FUNCTION__ etc. ID is the name to give the
decl, NAME is the initialization string and TYPE_DEP indicates whether
NAME depended on the type of the function. We make use of that to detect
- __PRETTY_FUNCTION__ inside a template fn. Because we build a tree for
- the function before emitting any of it, we don't need to treat the
- VAR_DECL specially. We can decide whether to emit it later, if it was
- used. */
+ __PRETTY_FUNCTION__ inside a template fn. This is being done
+ lazily at the point of first use, so we musn't push the decl now. */
static tree
-cp_make_fname_decl (id, name, type_dep)
+cp_make_fname_decl (id, type_dep)
tree id;
- const char *name;
int type_dep;
{
- tree decl, type, init;
- size_t length = strlen (name);
- tree domain = NULL_TREE;
-
- if (!processing_template_decl)
- type_dep = 0;
- if (!type_dep)
- domain = build_index_type (size_int (length));
-
- type = build_cplus_array_type
- (build_qualified_type (char_type_node, TYPE_QUAL_CONST),
- domain);
+ const char *name = (type_dep && processing_template_decl
+ ? NULL : fname_as_string (type_dep));
+ tree init = cp_fname_init (name);
+ tree decl = build_decl (VAR_DECL, id, TREE_TYPE (init));
- decl = build_decl (VAR_DECL, id, type);
+ /* As we don't push the decl here, we must set the context. */
+ DECL_CONTEXT (decl) = current_function_decl;
+ DECL_PRETTY_FUNCTION_P (decl) = type_dep;
+
TREE_STATIC (decl) = 1;
TREE_READONLY (decl) = 1;
- DECL_SOURCE_LINE (decl) = 0;
DECL_ARTIFICIAL (decl) = 1;
- DECL_IN_SYSTEM_HEADER (decl) = 1;
- DECL_IGNORED_P (decl) = 1;
- pushdecl (decl);
- if (processing_template_decl)
- decl = push_template_decl (decl);
- if (type_dep)
- {
- init = build (FUNCTION_NAME, type);
- DECL_PRETTY_FUNCTION_P (decl) = 1;
- }
- else
- {
- init = build_string (length + 1, name);
- TREE_TYPE (init) = type;
- }
DECL_INITIAL (decl) = init;
- cp_finish_decl (decl, init, NULL_TREE, LOOKUP_ONLYCONVERTING);
+
+ TREE_USED (decl) = 1;
- /* We will have to make sure we only emit this, if it is actually used. */
+ cp_finish_decl (decl, init, NULL_TREE, LOOKUP_ONLYCONVERTING);
+
return decl;
}
@@ -12966,6 +12974,7 @@ finish_enum (enumtype)
if (scope && TREE_CODE (scope) == FUNCTION_DECL)
add_stmt (build_min (TAG_DEFN, enumtype));
+
return;
}
@@ -13602,6 +13611,8 @@ start_function (declspecs, declarator, attrs, flags)
DECL_CONTEXT (dtor_label) = current_function_decl;
}
+ start_fname_decls ();
+
store_parm_decls (current_function_parms);
return 1;
@@ -13931,6 +13942,8 @@ finish_function (flags)
my_friendly_assert (building_stmt_tree (), 20000911);
+ finish_fname_decls ();
+
/* For a cloned function, we've already got all the code we need;
there's no need to add any extra bits. */
if (!DECL_CLONED_FUNCTION_P (fndecl))
diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c
index cb6a4d92461..f005482aec1 100644
--- a/gcc/cp/lex.c
+++ b/gcc/cp/lex.c
@@ -402,6 +402,8 @@ CONSTRAINT(ridbits_fit, RID_LAST_MODIFIER < sizeof(unsigned long) * CHAR_BIT);
static const struct resword reswords[] =
{
{ "_Complex", RID_COMPLEX, 0 },
+ { "__FUNCTION__", RID_FUNCTION_NAME, 0 },
+ { "__PRETTY_FUNCTION__", RID_PRETTY_FUNCTION_NAME, 0 },
{ "__alignof", RID_ALIGNOF, 0 },
{ "__alignof__", RID_ALIGNOF, 0 },
{ "__asm", RID_ASM, 0 },
@@ -414,6 +416,7 @@ static const struct resword reswords[] =
{ "__const", RID_CONST, 0 },
{ "__const__", RID_CONST, 0 },
{ "__extension__", RID_EXTENSION, 0 },
+ { "__func__", RID_C99_FUNCTION_NAME, 0 },
{ "__imag", RID_IMAGPART, 0 },
{ "__imag__", RID_IMAGPART, 0 },
{ "__inline", RID_INLINE, 0 },
@@ -585,6 +588,10 @@ const short rid_to_yy[RID_MAX] =
/* RID_PTREXTENT */ 0,
/* RID_PTRVALUE */ 0,
+ /* RID_FUNCTION_NAME */ VAR_FUNC_NAME,
+ /* RID_PRETTY_FUNCTION_NAME */ VAR_FUNC_NAME,
+ /* RID_c99_FUNCTION_NAME */ VAR_FUNC_NAME,
+
/* C++ */
/* RID_BOOL */ TYPESPEC,
/* RID_WCHAR */ TYPESPEC,
diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c
index 8f6fd0e6fcf..2ed10ea0c34 100644
--- a/gcc/cp/optimize.c
+++ b/gcc/cp/optimize.c
@@ -1123,7 +1123,6 @@ maybe_clone_body (fn)
VARRAY_FREE (id.fns);
/* Now, expand this function into RTL, if appropriate. */
- function_name_declared_p = 1;
finish_function (0);
BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn);
expand_body (clone);
diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y
index 37a2bb482f1..22b3e9583a7 100644
--- a/gcc/cp/parse.y
+++ b/gcc/cp/parse.y
@@ -259,6 +259,10 @@ cp_parse_init ()
yylval is the node for the constant. */
%token CONSTANT
+/* __func__, __FUNCTION__ or __PRETTY_FUNCTION__.
+ yylval contains an IDENTIFIER_NODE which indicates which one. */
+%token VAR_FUNC_NAME
+
/* String constants in raw form.
yylval is a STRING_CST node. */
%token STRING
@@ -1556,6 +1560,12 @@ primary:
(TREE_TYPE (TREE_TYPE ($$)),
TYPE_DOMAIN (TREE_TYPE ($$)));
}
+ | VAR_FUNC_NAME
+ {
+ $$ = fname_decl (C_RID_CODE ($$), $$);
+ if (processing_template_decl)
+ $$ = build_min_nt (LOOKUP_EXPR, DECL_NAME ($$));
+ }
| '(' expr ')'
{ $$ = finish_parenthesized_expr ($2); }
| '(' expr_or_declarator_intern ')'
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 1b88a783986..2a1dc4414ae 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -5987,10 +5987,9 @@ tsubst_decl (t, args, type)
/* For __PRETTY_FUNCTION__ we have to adjust the initializer. */
if (DECL_PRETTY_FUNCTION_P (r))
{
- DECL_INITIAL (r) = tsubst (DECL_INITIAL (t),
- args,
- /*complain=*/1,
- NULL_TREE);
+ const char *name = (*decl_printable_name)
+ (current_function_decl, 2);
+ DECL_INITIAL (r) = cp_fname_init (name);
TREE_TYPE (r) = TREE_TYPE (DECL_INITIAL (r));
}
@@ -6794,24 +6793,6 @@ tsubst (t, args, complain, in_decl)
return TREE_TYPE (e1);
}
- case FUNCTION_NAME:
- {
- const char *name;
- int len;
- tree type;
- tree str;
-
- /* This code should match declare_hidden_char_array in
- c-common.c. */
- name = (*decl_printable_name) (current_function_decl, 2);
- len = strlen (name) + 1;
- type = build_array_type (char_type_node,
- build_index_type (size_int (len)));
- str = build_string (len, name);
- TREE_TYPE (str) = type;
- return str;
- }
-
default:
sorry ("use of `%s' in template",
tree_code_name [(int) TREE_CODE (t)]);
@@ -7172,9 +7153,6 @@ tsubst_copy (t, args, complain, in_decl)
in_decl),
tsubst (TREE_TYPE (t), args, complain, in_decl));
- case FUNCTION_NAME:
- return tsubst (t, args, complain, in_decl);
-
default:
return t;
}
@@ -7254,7 +7232,10 @@ tsubst_expr (t, args, complain, in_decl)
{
init = DECL_INITIAL (decl);
decl = tsubst (decl, args, complain, in_decl);
- init = tsubst_expr (init, args, complain, in_decl);
+ if (DECL_PRETTY_FUNCTION_P (decl))
+ init = DECL_INITIAL (decl);
+ else
+ init = tsubst_expr (init, args, complain, in_decl);
if (decl != error_mark_node)
{
if (TREE_CODE (decl) != TYPE_DECL)
@@ -9934,10 +9915,6 @@ instantiate_decl (d, defer_ok)
/* Set up context. */
start_function (NULL_TREE, d, NULL_TREE, SF_PRE_PARSED);
- /* We already set up __FUNCTION__, etc., so we don't want to do
- it again now. */
- function_name_declared_p = 1;
-
/* Substitute into the body of the function. */
tsubst_expr (DECL_SAVED_TREE (code_pattern), args,
/*complain=*/1, tmpl);
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 8dae039192e..5a42fd034a2 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -852,16 +852,6 @@ begin_compound_stmt (has_no_scope)
to accidentally keep a block *inside* the scopeless block. */
keep_next_level (0);
- /* If this is the outermost block of the function, declare the
- variables __FUNCTION__, __PRETTY_FUNCTION__, and so forth. */
- if (cfun
- && !function_name_declared_p
- && !has_no_scope)
- {
- function_name_declared_p = 1;
- declare_function_name ();
- }
-
return r;
}
@@ -1180,7 +1170,6 @@ setup_vtbl_ptr (member_init_list, base_init_list)
{
tree if_stmt;
tree compound_stmt;
- int saved_cfnd;
/* If the dtor is empty, and we know there is not any possible
way we could use any vtable entries, before they are possibly
@@ -1201,12 +1190,7 @@ setup_vtbl_ptr (member_init_list, base_init_list)
finish_if_stmt_cond (boolean_true_node, if_stmt);
current_vcalls_possible_p = &IF_COND (if_stmt);
- /* Don't declare __PRETTY_FUNCTION__ and friends here when we
- open the block for the if-body. */
- saved_cfnd = function_name_declared_p;
- function_name_declared_p = 1;
compound_stmt = begin_compound_stmt (/*has_no_scope=*/0);
- function_name_declared_p = saved_cfnd;
/* Make all virtual function table pointers in non-virtual base
classes point to CURRENT_CLASS_TYPE's virtual function
@@ -1706,6 +1690,10 @@ finish_translation_unit ()
pop_everything ();
while (current_namespace != global_namespace)
pop_namespace ();
+
+ /* Do file scope __FUNCTION__ et al. */
+ finish_fname_decls ();
+
finish_file ();
}
@@ -2472,11 +2460,6 @@ expand_body (fn)
genrtl_start_function (fn);
current_function_is_thunk = DECL_THUNK_P (fn);
- /* We don't need to redeclare __FUNCTION__, __PRETTY_FUNCTION__, or
- any of the other magic variables we set up when starting a
- function body. */
- function_name_declared_p = 1;
-
/* Expand the body. */
expand_stmt (DECL_SAVED_TREE (fn));
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 3c26b1b8dda..26b2a1c5a71 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -470,6 +470,11 @@ digest_init (type, init, tail)
&& TREE_VALUE (init) == error_mark_node))
return error_mark_node;
+ if (TREE_CODE (init) == ERROR_MARK)
+ /* __PRETTY_FUNCTION__'s initializer is a bogus expression inside
+ a template function. This gets substituted during instantiation. */
+ return init;
+
/* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */
if (TREE_CODE (init) == NON_LVALUE_EXPR)
init = TREE_OPERAND (init, 0);