From e57e265ba61a2e07623521dc872a2b7e82e70b37 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 3 Feb 2004 11:22:41 +0000 Subject: [PATCH] re PR c/11658 (Wrong error message) 2004-02-03 Paolo Bonzini PR c/11658 PR c/13994 * Makefile.in (c-parse.o, c-convert.o, c-typeck.o): Depend on langhooks.h. * objc/Make-lang.in (objc-parse.o): Depend on langhooks.h. * c-parse.in, c-convert.c, c-typeck.c, objc/objc-act.c: Include langhooks.h. Replace c_common_truthvalue_conversion with the truthvalue_conversion language hook throughout. (expr_no_commas): Call default_conversion before save_expr for the first term of the production 'x ? : y'. * c-common.c (c_common_truthvalue_conversion): Remove obsolete block. Invoke recursively the hook instead of this function. * c-convert.c (convert): handle ERROR_MARK_NODE. * c-typeck.c (build_binary_op): handle ERROR_MARK_NODE returned by the truthvalue_conversion language hook. * c-lang.c (LANG_HOOKS_TRUTHVALUE_CONVERSION): Use c_objc_common_truthvalue_conversion. * c-objc-common.c (c_objc_common_truthvalue_conversion): New function. * c-tree.h (c_objc_common_truthvalue_conversion): Declare it. * objc/objc-lang.c (LANG_HOOKS_TRUTHVALUE_CONVERSION): Use c_objc_common_truthvalue_conversion. From-SVN: r77168 --- gcc/ChangeLog | 26 ++++++++++++++++++++++++++ gcc/Makefile.in | 7 ++++--- gcc/c-common.c | 42 ++++++++++-------------------------------- gcc/c-convert.c | 6 +++++- gcc/c-lang.c | 2 +- gcc/c-objc-common.c | 29 +++++++++++++++++++++++++++++ gcc/c-parse.in | 22 +++++++++++----------- gcc/c-tree.h | 1 + gcc/c-typeck.c | 12 ++++++++---- gcc/objc/Make-lang.in | 3 ++- gcc/objc/objc-act.c | 11 ++++++----- gcc/objc/objc-lang.c | 2 +- 12 files changed, 104 insertions(+), 59 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0bedc8af962b..d79909bca0de 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,29 @@ +2004-02-03 Paolo Bonzini + + PR c/11658 + PR c/13994 + * Makefile.in (c-parse.o, c-convert.o, c-typeck.o): Depend + on langhooks.h. + * objc/Make-lang.in (objc-parse.o): Depend on langhooks.h. + * c-parse.in, c-convert.c, c-typeck.c, objc/objc-act.c: + Include langhooks.h. Replace c_common_truthvalue_conversion + with the truthvalue_conversion language hook throughout. + (expr_no_commas): Call default_conversion before save_expr + for the first term of the production 'x ? : y'. + * c-common.c (c_common_truthvalue_conversion): Remove + obsolete block. Invoke recursively the hook instead + of this function. + * c-convert.c (convert): handle ERROR_MARK_NODE. + * c-typeck.c (build_binary_op): handle ERROR_MARK_NODE + returned by the truthvalue_conversion language hook. + * c-lang.c (LANG_HOOKS_TRUTHVALUE_CONVERSION): Use + c_objc_common_truthvalue_conversion. + * c-objc-common.c (c_objc_common_truthvalue_conversion): + New function. + * c-tree.h (c_objc_common_truthvalue_conversion): Declare it. + * objc/objc-lang.c (LANG_HOOKS_TRUTHVALUE_CONVERSION): Use + c_objc_common_truthvalue_conversion. + 2004-02-03 Kazu Hirata * config/c4x/c4x.h (FUNCTION_VALUE): Use gen_rtx_REG instead diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 746c74231a1a..043b8d4a2202 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1272,7 +1272,7 @@ c-errors.o: c-errors.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ $(C_TREE_H) flags.h $(DIAGNOSTIC_H) $(TM_P_H) c-parse.o : c-parse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ $(GGC_H) intl.h $(C_TREE_H) input.h flags.h toplev.h output.h $(CPPLIB_H) \ - varray.h gt-c-parse.h + varray.h gt-c-parse.h langhooks.h srcextra: c-parse.y c-parse.c gengtype-lex.c gengtype-yacc.c gengtype-yacc.h -cp -p $^ $(srcdir) @@ -1295,7 +1295,8 @@ c-decl.o : c-decl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ opts.h c-pragma.h gt-c-decl.h cgraph.h $(HASHTAB_H) libfuncs.h except.h \ $(LANGHOOKS_DEF_H) c-typeck.o : c-typeck.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(C_TREE_H) \ - $(TARGET_H) flags.h intl.h output.h $(EXPR_H) $(RTL_H) toplev.h $(TM_P_H) + $(TARGET_H) flags.h intl.h output.h $(EXPR_H) $(RTL_H) toplev.h $(TM_P_H) \ + langhooks.h c-lang.o : c-lang.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ $(C_TREE_H) $(C_PRETTY_PRINT_H) $(DIAGNOSTIC_H) \ $(GGC_H) langhooks.h $(LANGHOOKS_DEF_H) $(C_COMMON_H) gtype-c.h @@ -1345,7 +1346,7 @@ c-common.o : c-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ $(OBSTACK_H) $(C_COMMON_H) flags.h toplev.h output.h c-pragma.h intl.h \ $(GGC_H) $(EXPR_H) $(TM_P_H) builtin-types.def builtin-attrs.def \ $(DIAGNOSTIC_H) gt-c-common.h langhooks.h varray.h $(RTL_H) \ - $(TARGET_H) $(C_TREE_H) + $(TARGET_H) $(C_TREE_H) langhooks.h c-pretty-print.o : c-pretty-print.c $(C_PRETTY_PRINT_H) \ $(C_COMMON_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) real.h diff --git a/gcc/c-common.c b/gcc/c-common.c index b96655731eb0..b628ac49e5be 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -2614,28 +2614,6 @@ c_common_truthvalue_conversion (tree expr) if (TREE_CODE (expr) == FUNCTION_DECL) expr = build_unary_op (ADDR_EXPR, expr, 0); -#if 0 /* This appears to be wrong for C++. */ - /* These really should return error_mark_node after 2.4 is stable. - But not all callers handle ERROR_MARK properly. */ - switch (TREE_CODE (TREE_TYPE (expr))) - { - case RECORD_TYPE: - error ("struct type value used where scalar is required"); - return truthvalue_false_node; - - case UNION_TYPE: - error ("union type value used where scalar is required"); - return truthvalue_false_node; - - case ARRAY_TYPE: - error ("array type value used where scalar is required"); - return truthvalue_false_node; - - default: - break; - } -#endif /* 0 */ - switch (TREE_CODE (expr)) { case EQ_EXPR: @@ -2686,15 +2664,15 @@ c_common_truthvalue_conversion (tree expr) case COMPLEX_EXPR: return build_binary_op ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)) ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR), - c_common_truthvalue_conversion (TREE_OPERAND (expr, 0)), - c_common_truthvalue_conversion (TREE_OPERAND (expr, 1)), + (*lang_hooks.truthvalue_conversion) (TREE_OPERAND (expr, 0)), + (*lang_hooks.truthvalue_conversion) (TREE_OPERAND (expr, 1)), 0); case NEGATE_EXPR: case ABS_EXPR: case FLOAT_EXPR: /* These don't change whether an object is nonzero or zero. */ - return c_common_truthvalue_conversion (TREE_OPERAND (expr, 0)); + return (*lang_hooks.truthvalue_conversion) (TREE_OPERAND (expr, 0)); case LROTATE_EXPR: case RROTATE_EXPR: @@ -2702,15 +2680,15 @@ c_common_truthvalue_conversion (tree expr) we can't ignore them if their second arg has side-effects. */ if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))) return build (COMPOUND_EXPR, truthvalue_type_node, TREE_OPERAND (expr, 1), - c_common_truthvalue_conversion (TREE_OPERAND (expr, 0))); + (*lang_hooks.truthvalue_conversion) (TREE_OPERAND (expr, 0))); else - return c_common_truthvalue_conversion (TREE_OPERAND (expr, 0)); + return (*lang_hooks.truthvalue_conversion) (TREE_OPERAND (expr, 0)); case COND_EXPR: /* Distribute the conversion into the arms of a COND_EXPR. */ return fold (build (COND_EXPR, truthvalue_type_node, TREE_OPERAND (expr, 0), - c_common_truthvalue_conversion (TREE_OPERAND (expr, 1)), - c_common_truthvalue_conversion (TREE_OPERAND (expr, 2)))); + (*lang_hooks.truthvalue_conversion) (TREE_OPERAND (expr, 1)), + (*lang_hooks.truthvalue_conversion) (TREE_OPERAND (expr, 2)))); case CONVERT_EXPR: /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE, @@ -2723,7 +2701,7 @@ c_common_truthvalue_conversion (tree expr) /* If this is widening the argument, we can ignore it. */ if (TYPE_PRECISION (TREE_TYPE (expr)) >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0)))) - return c_common_truthvalue_conversion (TREE_OPERAND (expr, 0)); + return (*lang_hooks.truthvalue_conversion) (TREE_OPERAND (expr, 0)); break; case MINUS_EXPR: @@ -2772,8 +2750,8 @@ c_common_truthvalue_conversion (tree expr) return (build_binary_op ((TREE_SIDE_EFFECTS (expr) ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR), - c_common_truthvalue_conversion (build_unary_op (REALPART_EXPR, t, 0)), - c_common_truthvalue_conversion (build_unary_op (IMAGPART_EXPR, t, 0)), + (*lang_hooks.truthvalue_conversion) (build_unary_op (REALPART_EXPR, t, 0)), + (*lang_hooks.truthvalue_conversion) (build_unary_op (IMAGPART_EXPR, t, 0)), 0)); } diff --git a/gcc/c-convert.c b/gcc/c-convert.c index ce095acc29a5..57fc967d2ed5 100644 --- a/gcc/c-convert.c +++ b/gcc/c-convert.c @@ -33,6 +33,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "flags.h" #include "convert.h" #include "c-common.h" +#include "langhooks.h" #include "toplev.h" /* Change of width--truncation and extension of integers or reals-- @@ -94,7 +95,10 @@ convert (tree type, tree expr) return fold (convert_to_integer (type, e)); if (code == BOOLEAN_TYPE) { - tree t = c_common_truthvalue_conversion (expr); + tree t = (*lang_hooks.truthvalue_conversion) (expr); + if (TREE_CODE (t) == ERROR_MARK) + return t; + /* If it returns a NOP_EXPR, we must fold it here to avoid infinite recursion between fold () and convert (). */ if (TREE_CODE (t) == NOP_EXPR) diff --git a/gcc/c-lang.c b/gcc/c-lang.c index 1a097e277979..927f5abb210c 100644 --- a/gcc/c-lang.c +++ b/gcc/c-lang.c @@ -66,7 +66,7 @@ enum c_language_kind c_language = clk_c; #undef LANG_HOOKS_PARSE_FILE #define LANG_HOOKS_PARSE_FILE c_common_parse_file #undef LANG_HOOKS_TRUTHVALUE_CONVERSION -#define LANG_HOOKS_TRUTHVALUE_CONVERSION c_common_truthvalue_conversion +#define LANG_HOOKS_TRUTHVALUE_CONVERSION c_objc_common_truthvalue_conversion #undef LANG_HOOKS_FINISH_INCOMPLETE_DECL #define LANG_HOOKS_FINISH_INCOMPLETE_DECL c_finish_incomplete_decl #undef LANG_HOOKS_UNSAFE_FOR_REEVAL diff --git a/gcc/c-objc-common.c b/gcc/c-objc-common.c index 5a57aa46065b..73a3241a413e 100644 --- a/gcc/c-objc-common.c +++ b/gcc/c-objc-common.c @@ -332,3 +332,32 @@ c_tree_printer (pretty_printer *pp, text_info *text) pp_string (pp, n); return true; } + +tree +c_objc_common_truthvalue_conversion (tree expr) +{ + retry: + switch (TREE_CODE (TREE_TYPE (expr))) + { + case ARRAY_TYPE: + expr = default_conversion (expr); + if (TREE_CODE (TREE_TYPE (expr)) != ARRAY_TYPE) + goto retry; + + error ("used array that cannot be converted to pointer where scalar is required"); + return error_mark_node; + + case RECORD_TYPE: + error ("used struct type value where scalar is required"); + return error_mark_node; + + case UNION_TYPE: + error ("used union type value where scalar is required"); + return error_mark_node; + default: + break; + } + + return c_common_truthvalue_conversion (expr); +} + diff --git a/gcc/c-parse.in b/gcc/c-parse.in index 59dc9b5cfd06..23e2898aed16 100644 --- a/gcc/c-parse.in +++ b/gcc/c-parse.in @@ -38,6 +38,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "coretypes.h" #include "tm.h" #include "tree.h" +#include "langhooks.h" #include "input.h" #include "cpplib.h" #include "intl.h" @@ -579,21 +580,21 @@ expr_no_commas: | expr_no_commas '^' expr_no_commas { $$ = parser_build_binary_op ($2, $1, $3); } | expr_no_commas ANDAND - { $1 = c_common_truthvalue_conversion + { $1 = (*lang_hooks.truthvalue_conversion) (default_conversion ($1)); skip_evaluation += $1 == truthvalue_false_node; } expr_no_commas { skip_evaluation -= $1 == truthvalue_false_node; $$ = parser_build_binary_op (TRUTH_ANDIF_EXPR, $1, $4); } | expr_no_commas OROR - { $1 = c_common_truthvalue_conversion + { $1 = (*lang_hooks.truthvalue_conversion) (default_conversion ($1)); skip_evaluation += $1 == truthvalue_true_node; } expr_no_commas { skip_evaluation -= $1 == truthvalue_true_node; $$ = parser_build_binary_op (TRUTH_ORIF_EXPR, $1, $4); } | expr_no_commas '?' - { $1 = c_common_truthvalue_conversion + { $1 = (*lang_hooks.truthvalue_conversion) (default_conversion ($1)); skip_evaluation += $1 == truthvalue_false_node; } expr ':' @@ -606,9 +607,8 @@ expr_no_commas: { if (pedantic) pedwarn ("ISO C forbids omitting the middle term of a ?: expression"); /* Make sure first operand is calculated only once. */ - $2 = save_expr ($1); - $1 = c_common_truthvalue_conversion - (default_conversion ($2)); + $2 = save_expr (default_conversion ($1)); + $1 = (*lang_hooks.truthvalue_conversion) ($2); skip_evaluation += $1 == truthvalue_true_node; } ':' expr_no_commas { skip_evaluation -= $1 == truthvalue_true_node; @@ -2192,7 +2192,7 @@ if_prefix: IF { $$ = c_begin_if_stmt (); } '(' expr ')' - { c_expand_start_cond (c_common_truthvalue_conversion ($4), + { c_expand_start_cond ((*lang_hooks.truthvalue_conversion) ($4), compstmt_count,$2); $$ = stmt_count; if_stmt_locus = $-1; } @@ -2301,16 +2301,16 @@ select_or_iter_stmt: $$ = c_begin_while_stmt (); } '(' expr ')' { c_in_iteration_stmt++; - $4 = c_common_truthvalue_conversion ($4); + $4 = (*lang_hooks.truthvalue_conversion) ($4); c_finish_while_stmt_cond - (c_common_truthvalue_conversion ($4), $2); + ((*lang_hooks.truthvalue_conversion) ($4), $2); $$ = add_stmt ($2); } c99_block_lineno_labeled_stmt { c_in_iteration_stmt--; RECHAIN_STMTS ($6, WHILE_BODY ($6)); } | do_stmt_start '(' expr ')' ';' - { DO_COND ($1) = c_common_truthvalue_conversion ($3); } + { DO_COND ($1) = (*lang_hooks.truthvalue_conversion) ($3); } | do_stmt_start error { } | FOR @@ -2323,7 +2323,7 @@ select_or_iter_stmt: xexpr ';' { if ($6) FOR_COND ($2) - = c_common_truthvalue_conversion ($6); } + = (*lang_hooks.truthvalue_conversion) ($6); } xexpr ')' { c_in_iteration_stmt++; FOR_EXPR ($2) = $9; } diff --git a/gcc/c-tree.h b/gcc/c-tree.h index 4849ab2dd555..e9bc5c6863ce 100644 --- a/gcc/c-tree.h +++ b/gcc/c-tree.h @@ -237,6 +237,7 @@ extern void merge_translation_unit_decls (void); extern int c_disregard_inline_limits (tree); extern int c_cannot_inline_tree_fn (tree *); extern bool c_objc_common_init (void); +extern tree c_objc_common_truthvalue_conversion (tree expr); extern int c_missing_noreturn_ok_p (tree); extern void c_objc_common_finish_file (void); extern int defer_fn (tree); diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 367285ecf1cc..d61e89e64558 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -35,6 +35,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "tm.h" #include "rtl.h" #include "tree.h" +#include "langhooks.h" #include "c-tree.h" #include "tm_p.h" #include "flags.h" @@ -2259,7 +2260,7 @@ build_unary_op (enum tree_code code, tree xarg, int flag) error ("wrong type argument to unary exclamation mark"); return error_mark_node; } - arg = c_common_truthvalue_conversion (arg); + arg = (*lang_hooks.truthvalue_conversion) (arg); return invert_truthvalue (arg); case NOP_EXPR: @@ -2632,7 +2633,7 @@ build_conditional_expr (tree ifexp, tree op1, tree op2) tree result_type = NULL; tree orig_op1 = op1, orig_op2 = op2; - ifexp = c_common_truthvalue_conversion (default_conversion (ifexp)); + ifexp = (*lang_hooks.truthvalue_conversion) (default_conversion (ifexp)); /* Promote both alternatives. */ @@ -6539,8 +6540,8 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, but that does not mean the operands should be converted to ints! */ result_type = integer_type_node; - op0 = c_common_truthvalue_conversion (op0); - op1 = c_common_truthvalue_conversion (op1); + op0 = (*lang_hooks.truthvalue_conversion) (op0); + op1 = (*lang_hooks.truthvalue_conversion) (op1); converted = 1; } break; @@ -6778,6 +6779,9 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, break; } + if (code0 == ERROR_MARK || code1 == ERROR_MARK) + return error_mark_node; + if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE || code0 == VECTOR_TYPE) && diff --git a/gcc/objc/Make-lang.in b/gcc/objc/Make-lang.in index 022453fdbcf4..1b0665c97f88 100644 --- a/gcc/objc/Make-lang.in +++ b/gcc/objc/Make-lang.in @@ -64,7 +64,8 @@ objc/objc-lang.o : objc/objc-lang.c \ objc/objc-parse.o : objc/objc-parse.c \ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(C_TREE_H) \ - toplev.h $(GGC_H) c-pragma.h input.h flags.h output.h objc/objc-act.h + toplev.h $(GGC_H) c-pragma.h input.h flags.h output.h objc/objc-act.h \ + langhooks.h objc/objc-act.o : objc/objc-act.c \ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(RTL_H) $(TM_P_H) \ diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c index c1352922c7ed..c29c4fa6aeaf 100644 --- a/gcc/objc/objc-act.c +++ b/gcc/objc/objc-act.c @@ -50,6 +50,7 @@ Boston, MA 02111-1307, USA. */ #include "c-tree.h" #include "c-common.h" #include "flags.h" +#include "langhooks.h" #include "objc-act.h" #include "input.h" #include "except.h" @@ -2850,7 +2851,7 @@ objc_build_try_enter_fragment (void) cond = build_unary_op (TRUTH_NOT_EXPR, build_function_call (objc_setjmp_decl, func_params), 0); - c_expand_start_cond (c_common_truthvalue_conversion (cond), + c_expand_start_cond ((*lang_hooks.truthvalue_conversion) (cond), 0, if_stmt); objc_enter_block (); } @@ -2978,7 +2979,7 @@ objc_build_try_epilogue (int also_catch_prologue) val_stack_push (&catch_count_stack, 1); if_stmt = c_begin_if_stmt (); if_nesting_count++; - c_expand_start_cond (c_common_truthvalue_conversion (boolean_false_node), + c_expand_start_cond ((*lang_hooks.truthvalue_conversion) (boolean_false_node), 0, if_stmt); objc_enter_block (); @@ -3068,7 +3069,7 @@ objc_build_catch_stmt (tree catch_expr) cond = build_function_call (objc_exception_match_decl, func_params); } - c_expand_start_cond (c_common_truthvalue_conversion (cond), + c_expand_start_cond ((*lang_hooks.truthvalue_conversion) (cond), 0, if_stmt); objc_enter_block (); objc_declare_variable (RID_REGISTER, var_name, @@ -3138,7 +3139,7 @@ objc_build_finally_prologue (void) tree if_stmt = c_begin_if_stmt (); if_nesting_count++; - c_expand_start_cond (c_common_truthvalue_conversion + c_expand_start_cond ((*lang_hooks.truthvalue_conversion) (build_unary_op (TRUTH_NOT_EXPR, TREE_VALUE (objc_rethrow_exception), 0)), @@ -3166,7 +3167,7 @@ objc_build_finally_epilogue (void) if_nesting_count++; c_expand_start_cond - (c_common_truthvalue_conversion (TREE_VALUE (objc_rethrow_exception)), + ((*lang_hooks.truthvalue_conversion) (TREE_VALUE (objc_rethrow_exception)), 0, if_stmt); objc_enter_block (); objc_build_throw_stmt (TREE_VALUE (objc_rethrow_exception)); diff --git a/gcc/objc/objc-lang.c b/gcc/objc/objc-lang.c index 3f70122302c4..72c772c40b49 100644 --- a/gcc/objc/objc-lang.c +++ b/gcc/objc/objc-lang.c @@ -60,7 +60,7 @@ enum c_language_kind c_language = clk_objc; #undef LANG_HOOKS_MARK_ADDRESSABLE #define LANG_HOOKS_MARK_ADDRESSABLE c_mark_addressable #undef LANG_HOOKS_TRUTHVALUE_CONVERSION -#define LANG_HOOKS_TRUTHVALUE_CONVERSION c_common_truthvalue_conversion +#define LANG_HOOKS_TRUTHVALUE_CONVERSION c_objc_common_truthvalue_conversion #undef LANG_HOOKS_FINISH_INCOMPLETE_DECL #define LANG_HOOKS_FINISH_INCOMPLETE_DECL c_finish_incomplete_decl #undef LANG_HOOKS_UNSAFE_FOR_REEVAL