From 6ef5231bdf52aba0854491d24ab30bebd8f2ab0a Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@gcc.gnu.org>
Date: Wed, 5 Sep 2007 22:45:27 +0200
Subject: [PATCH] builtins.def (BUILT_IN_VA_ARG_PACK): New built-in.

	* builtins.def (BUILT_IN_VA_ARG_PACK): New built-in.
	* tree.h (CALL_EXPR_VA_ARG_PACK): Define.
	* tree-inline.h (copy_body_data): Add call_expr field.
	* tree-inline.c (expand_call_inline): Initialize call_expr.
	(copy_bb): Append anonymous inline fn arguments to arguments
	when inlining a CALL_EXPR_VA_ARG_PACK call.
	* builtins.c (expand_builtin): Issue an error if
	BUILT_IN_VA_ARG_PACK is seen during expand.
	(fold_call_expr, fold_builtin_call_array): Don't fold
	CALL_EXPR_VA_ARG_PACK CALL_EXPRs or calls with
	__builtin_va_arg_pack () call as last argument.
	* gimplify.c (gimplify_call_expr): If last argument to a vararg
	function is __builtin_va_arg_pack (), decrease number of call
	arguments and instead set CALL_EXPR_VA_ARG_PACK on the CALL_EXPR.
	* expr.c (expand_expr_real_1): Issue an error if
	CALL_EXPR_VA_ARG_PACK CALL_EXPR is seen during expand.
	* tree-pretty-print.c (dump_generic_node): Handle printing
	CALL_EXPR_VA_ARG_PACK bit on CALL_EXPRs.
	* doc/extend.texi (__builtin_va_arg_pack): Document.

	* gcc.c-torture/execute/va-arg-pack-1.c: New test.
	* gcc.dg/va-arg-pack-1.c: New test.

From-SVN: r128150
---
 gcc/ChangeLog                                 | 122 +++++++++------
 gcc/builtins.c                                |  41 ++++-
 gcc/builtins.def                              |   1 +
 gcc/doc/extend.texi                           |  26 ++++
 gcc/expr.c                                    |   4 +
 gcc/gimplify.c                                |  46 +++++-
 gcc/testsuite/ChangeLog                       |   5 +
 .../gcc.c-torture/execute/va-arg-pack-1.c     | 143 ++++++++++++++++++
 gcc/testsuite/gcc.dg/va-arg-pack-1.c          |  52 +++++++
 gcc/tree-inline.c                             |  53 ++++++-
 gcc/tree-inline.h                             |   4 +
 gcc/tree-pretty-print.c                       |   9 ++
 gcc/tree.h                                    |   7 +
 13 files changed, 457 insertions(+), 56 deletions(-)
 create mode 100644 gcc/testsuite/gcc.c-torture/execute/va-arg-pack-1.c
 create mode 100644 gcc/testsuite/gcc.dg/va-arg-pack-1.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6f0ea1852267..ea2f73f8ed38 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,25 @@
+2007-09-05  Jakub Jelinek  <jakub@redhat.com>
+
+	* builtins.def (BUILT_IN_VA_ARG_PACK): New built-in.
+	* tree.h (CALL_EXPR_VA_ARG_PACK): Define.
+	* tree-inline.h (copy_body_data): Add call_expr field.
+	* tree-inline.c (expand_call_inline): Initialize call_expr.
+	(copy_bb): Append anonymous inline fn arguments to arguments
+	when inlining a CALL_EXPR_VA_ARG_PACK call.
+	* builtins.c (expand_builtin): Issue an error if
+	BUILT_IN_VA_ARG_PACK is seen during expand.
+	(fold_call_expr, fold_builtin_call_array): Don't fold
+	CALL_EXPR_VA_ARG_PACK CALL_EXPRs or calls with
+	__builtin_va_arg_pack () call as last argument.
+	* gimplify.c (gimplify_call_expr): If last argument to a vararg
+	function is __builtin_va_arg_pack (), decrease number of call
+	arguments and instead set CALL_EXPR_VA_ARG_PACK on the CALL_EXPR.
+	* expr.c (expand_expr_real_1): Issue an error if
+	CALL_EXPR_VA_ARG_PACK CALL_EXPR is seen during expand.
+	* tree-pretty-print.c (dump_generic_node): Handle printing
+	CALL_EXPR_VA_ARG_PACK bit on CALL_EXPRs.
+	* doc/extend.texi (__builtin_va_arg_pack): Document.
+
 2007-09-05  Adam Nemet  <anemet@caviumnetworks.com>
 
 	PR tree-optimization/21513
@@ -92,7 +114,7 @@
 	(was_mips16_p): New.
 	(mips_set_mips16_mode): New, split out from override_options.
 	(mips_set_current_function): New.
-	(override_options):  Add sorry for unsupported mips16/pic
+	(override_options): Add sorry for unsupported mips16/pic
 	combination.  Remove error for mips16/dsp combination.	Save
 	base option settings.  
 	(mips_file_start): Move mips16 mode setting output from here....
@@ -114,7 +136,7 @@
 
 	* config/mips/mips.c (mips_legitimize_tls_address): Call sorry
 	if we encounter TLS address in MIPS16 mode.
-	(mips_legitimize_const_move):  Check cannot_force_const_mem for
+	(mips_legitimize_const_move): Check cannot_force_const_mem for
 	the (const (plus symbol offset)) case; this forces invalid TLS
 	address in MIPS16 mode to be caught by the above call to sorry.
 	(override_options): Don't reset targetm.have_tls in MIPS16 mode,
@@ -134,7 +156,7 @@
 	* function.h: Here.
 	(set_cfun): Declare.
 	* tree-inline.c (cfun_stack, push_cfun, pop_cfun): Moved to...
-	* function.c:  Here.
+	* function.c: Here.
 	(push_function_context_to): Use allocate_struct_function
 	to create null context, not init_dummy_function_start.  Use set_cfun.
 	(pop_function_context_from): Use set_cfun.
@@ -168,7 +190,7 @@
 
 2007-09-05  Kenneth Zadeck <zadeck@naturalbridge.com>
 
-	* regrename.c (rerename_optimize):  Use deferred rescanning and
+	* regrename.c (rerename_optimize): Use deferred rescanning and
 	insert explicit calls to rescan insns when changed.
 	
 2007-09-05  Jan Hubicka  <jh@suse.cz>
@@ -1178,9 +1200,9 @@
 
 	* toplev.c (init_alignments): New, split out from...
 	(process_options): ...here.
-	(backend_init_target):  New, split out from...
+	(backend_init_target): New, split out from...
 	(backend_init): ...here.
-	(lang_dependent_init_target):  New, split out from...
+	(lang_dependent_init_target): New, split out from...
 	(lang_dependent_init): ...here.
 	(target_reinit): New.
 	* toplev.h (target_reinit): Declare.
@@ -3338,7 +3360,7 @@
 
 2007-08-11  David Daney  <ddaney@avtrex.com>
 
-	* config/mips/mips.c (mips_sched_reorder):  Mark cycle parameter
+	* config/mips/mips.c (mips_sched_reorder): Mark cycle parameter
 	as ATTRIBUTE_UNUSED.
 
 2007-08-11  David Edelsohn  <edelsohn@gnu.org>
@@ -3514,17 +3536,17 @@
 
 2007-08-09  Sandra Loosemore  <sandra@codesourcery.com>
 
-	* config/mips/mips.opt (mhard-float, msoft-float):  Make these
+	* config/mips/mips.opt (mhard-float, msoft-float): Make these
 	control TARGET_HARD_FLOAT_ABI and TARGET_SOFT_FLOAT_ABI, rather
 	than TARGET_HARD_FLOAT and TARGET_SOFT_FLOAT.  
 	* config/mips/mips.h (mips16_hard_float): Delete.
-	(TARGET_HARD_FLOAT_ABI, TARGET_SOFT_FLOAT_ABI):  Delete these
+	(TARGET_HARD_FLOAT_ABI, TARGET_SOFT_FLOAT_ABI): Delete these
 	definitions, and replace with....
 	(TARGET_HARD_FLOAT, TARGET_SOFT_FLOAT): Define.
 	* config/mips/mips.c (mips16_hard_float): Delete.  Replace
 	all references with (TARGET_MIPS16 && TARGET_HARD_FLOAT_ABI).
 	(MIPS_MARCH_CONTROLS_SOFT_FLOAT): Update comments.
-	(override_options):  Replace MASK_SOFT_FLOAT references with
+	(override_options): Replace MASK_SOFT_FLOAT references with
 	MASK_SOFT_FLOAT_ABI.  Delete twiddling with MASK_SOFT_FLOAT
 	and mips16_hard_float when TARGET_MIPS16.
 	
@@ -3562,7 +3584,7 @@
 	tri-state integer.
 	* optabs.c (expand_ffs, expand_ctz): New functions to compute
 	ffs and ctz using clz.
-	(expand_unop):  Call them.
+	(expand_unop): Call them.
 	* config/rs6000/rs6000.h (CLZ_DEFINED_VALUE_AT_ZERO): Fix its
 	result value.
 	(CTZ_DEFINED_VALUE_AT_ZERO): Likewise.
@@ -4687,7 +4709,7 @@
 
 2007-08-01  Sandra Loosemore  <sandra@codesourcery.com>
 
-	* reload.c (find_reloads_address_part):  Pass correct MEMREFLOC
+	* reload.c (find_reloads_address_part): Pass correct MEMREFLOC
 	argument to find_reloads_address.
 
 2007-08-01  Daniel Jacobowitz  <dan@codesourcery.com>
@@ -4846,7 +4868,7 @@
 
 2007-07-31  Sandra Loosemore  <sandra@codesourcery.com>
 
-	* config/mips/mips.h (ISA_HAS_SYNCI):  Add !TARGET_MIPS16 test.
+	* config/mips/mips.h (ISA_HAS_SYNCI): Add !TARGET_MIPS16 test.
 
 2007-07-31  Revital Eres  <eres@il.ibm.com>
 
@@ -6228,7 +6250,7 @@
 
 2007-07-18  Caroline Tice  <ctice@apple.com>
 	
-	* var-tracking.c (find_src_status):  Check for  COND_EXEC insns
+	* var-tracking.c (find_src_status): Check for  COND_EXEC insns
 	and handle them correctly; check that src is not NULL before
 	trying to use it.
 	(find_src_set_src): Likewise.
@@ -6392,7 +6414,7 @@
 2007-07-16  Sandra Loosemore  <sandra@codesourcery.com>
 	    Nigel Stephens  <nigel@mips.com>
 
-	* config/mips/mips.md:  Include 20kc.md.
+	* config/mips/mips.md: Include 20kc.md.
 	* config/mips/20kc.md: New file.
 	* config/mips/mips.c (mips_rtx_cost_data): Fill in 20Kc costs.
 	(mips_adjust_cost): Tweak for 20Kc.
@@ -8876,7 +8898,7 @@
 	* df-problems.c (df_ru_alloc, df_rd_alloc, df_lr_alloc,
 	df_live_alloc, df_urec_alloc, df_note_alloc): set optional_p.
 	(problem_RU, problem_RD, problem_LR, problem_UREC, problem_CHAIN,
-	problem_NOTE):  Initialize free_blocks_on_set_blocks.
+	problem_NOTE): Initialize free_blocks_on_set_blocks.
 	(df_lr_bb_local_compute): Recompute luids if df_live problem is
 	not active.
 	(df_live_set_all_dirty, df_note_alloc): New function.
@@ -9341,7 +9363,7 @@
 	* tree-ssa.c (tree_ssa_useless_type_conversion_1):
 	Convert the MIN/MAX of the inner type to the outer
 	type before comparing them.
-	* tree-ssa-loop-prefetch.c (idx_analyze_ref):  Handle
+	* tree-ssa-loop-prefetch.c (idx_analyze_ref): Handle
 	POINTER_PLUS_EXPR instead of PLUS_EXPR.
 	(issue_prefetch_ref): Create a POINTER_PLUS_EXPR instead
 	of PLUS_EXPR for pointers.
@@ -10916,7 +10938,7 @@
 	* config/mn10300/mn10300.md: Include.
 	* config/mn10300/mn10300.c(mn10300_secondary_reload_class):
 	Fix up for removed macro.
-	* config/mn10300/predicates.md (call_address_operand):  Ditto.
+	* config/mn10300/predicates.md (call_address_operand): Ditto.
 	* config/mn10300/mn10300.h (REG_CLASS_FROM_LETTER): Delete.
 	(CONST_OK_FOR_I): Ditto.
 	(CONST_OK_FOR_J): Ditto.
@@ -11279,10 +11301,10 @@
 	* doc/extend.texi (Function Attributes): Document MIPS "near" and
 	"far" attributes.
 
-	* testsuite/gcc.target/mips/near-far-1.c:  New test case.
-	* testsuite/gcc.target/mips/near-far-2.c:  New test case.
-	* testsuite/gcc.target/mips/near-far-3.c:  New test case.
-	* testsuite/gcc.target/mips/near-far-4.c:  New test case.
+	* testsuite/gcc.target/mips/near-far-1.c: New test case.
+	* testsuite/gcc.target/mips/near-far-2.c: New test case.
+	* testsuite/gcc.target/mips/near-far-3.c: New test case.
+	* testsuite/gcc.target/mips/near-far-4.c: New test case.
 
 2007-05-25  Eric Christopher  <echristo@apple.com>
 
@@ -11444,7 +11466,7 @@
 	stmt_dominates_stmt_p, get_lsm_tmp_name): Declare.
 	* Makefile.in (tree-predcom.o): Add.
 	(tree-affine.o): Add TREE_GIMPLE_H dependency.
-	* passes.c (init_optimization_passes):  Add dceloop after
+	* passes.c (init_optimization_passes): Add dceloop after
 	copy propagation in loop optimizer.  Add predictive commoning
 	to loop optimizer passes.
 
@@ -12692,7 +12714,7 @@
 
 2007-05-14  Dave Korn  <dave.korn@artimi.com>
 
-	* genautomata.c (gen_regexp_el):  Allocate correct size for regexp.
+	* genautomata.c (gen_regexp_el): Allocate correct size for regexp.
 
 2007-05-14  Rafael Avila de Espindola  <espindola@google.com>
 
@@ -13905,7 +13927,7 @@
 
 2007-04-26  Steve Ellcey  <sje@cup.hp.com>
 
-	* config/ia64/ia64.md (ip_value):  Fix itanium_class attribute.
+	* config/ia64/ia64.md (ip_value): Fix itanium_class attribute.
 
 2007-04-26  Richard Guenther  <rguenther@suse.de>
 
@@ -14219,7 +14241,7 @@
 	(create_phi_node): Use set_phi_nodes.
 	* omp-low.c (expand_omp_parallel): Use bb_stmt_list.
 	* tree-if-conv.c (process_phi_nodes): Use set_phi_nodes.
-	(combine_blocks):  Use bb_stmt_list and set_bb_stmt_list.
+	(combine_blocks): Use bb_stmt_list and set_bb_stmt_list.
 	* tree-flow-inline.h (phi_nodes, set_phi_nodes,
 	(bsi_start, bsi_last): Use bb_stmt_list.
 	(phi_nodes_ptr, bb_stmt_list, set_bb_stmt_list): New functions.
@@ -14788,7 +14810,7 @@
 	* tree-ssa-loop-ivopts.c (ivopts_global_cost_for_size): Use
 	estimate_reg_pressure_cost.  Add number of ivs.
 	(determine_set_costs): Dump target_reg_cost.
-	* loop-invariant.c (gain_for_invariant):  Use
+	* loop-invariant.c (gain_for_invariant): Use
 	estimate_reg_pressure_cost.  Removed n_inv_uses argument.
 	(best_gain_for_invariant, find_invariants_to_move): Remove
 	n_inv_uses.
@@ -15663,7 +15685,7 @@
 2007-04-07  Bruce Korb  <bkorb@gnu.org>
 
 	* c.opt: Add -Wformat-contains-nul.
-	* c-format.c (set_Wformat):  Set warn_format_contains_nul to the
+	* c-format.c (set_Wformat): Set warn_format_contains_nul to the
 	  -Wformat setting.
 	(check_format_info_main): Check OPT_Wformat_contains_nul before emitting
 	the NUL byte warning.
@@ -15689,7 +15711,7 @@
 	argument "reliable".
 	(infer_loop_bounds_from_ref, infer_loop_bounds_from_array):
 	Add argument "reliable".  Propagate it through calls.
-	(infer_loop_bounds_from_undefined):  Derive number of iterations
+	(infer_loop_bounds_from_undefined): Derive number of iterations
 	estimates from references in blocks that do not dominate loop latch.
 	(gcov_type_to_double_int): New function.
 	(estimate_numbers_of_iterations_loop): Use gcov_type_to_double_int
@@ -17893,7 +17915,7 @@
 	(dsp_32only_bdesc): New description table for 32-bit only DSP REV 1
 	and 2 builtins.
 	(bdesc_map): Add one field of unsupported_target_flags.
-	(bdesc_arrays):  Update entries to have extra fields.  Add
+	(bdesc_arrays): Update entries to have extra fields.  Add
 	dsp_32only_bdesc.
 	(mips_init_builtins): Initialize new function types.
 	Check unsupported_target_fileds to filter out builtins.
@@ -18896,7 +18918,7 @@
 
 2007-03-01  Zdenek Dvorak  <dvorakz@suse.cz>
 
-	* tree-ssa-loop-prefetch.c (determine_unroll_factor):  Bound the
+	* tree-ssa-loop-prefetch.c (determine_unroll_factor): Bound the
 	unroll factor by the estimated number of iterations.
 	(loop_prefetch_arrays): Do not prefetch in loops that iterate less
 	than prefetch latency.
@@ -19352,7 +19374,7 @@
 2007-02-23  Steve Ellcey  <sje@cup.hp.com>
 
 	PR debug/29614
-	* varpool.c (varpool_assemble_pending_decls):  Set
+	* varpool.c (varpool_assemble_pending_decls): Set
 	varpool_last_needed_node to null.
 
 2007-02-23  DJ Delorie  <dj@redhat.com>
@@ -19456,8 +19478,8 @@
 	* config/spu/spu-protos.h (spu_init_expanders): Declare.
 	* config/spu/spu.c (spu_expand_prologue): Set REGNO_POINTER_ALIGN for
 	HARD_FRAME_POINTER_REGNUM.
-	(spu_legitimate_address):  Use regno_aligned_for_reload.
-	(regno_aligned_for_load):  HARD_FRAME_POINTER_REGNUM is only 16 byte
+	(spu_legitimate_address): Use regno_aligned_for_reload.
+	(regno_aligned_for_load): HARD_FRAME_POINTER_REGNUM is only 16 byte
 	aligned when frame_pointer_needed is true.
 	(spu_init_expanders): New.  Set alignment of HARD_FRAME_POINTER_REGNUM
 	to 8 bits.
@@ -19473,7 +19495,7 @@
 	rotqmbi_<mode>, rotqmby_<mode>, ashr<mode>3, rotma_<mode>,
 	rotl<mode>3, rotlti3, rotqbybi_ti, rotqby_ti, rotqbi_ti): Use
 	spu_nonmem_operand instead of spu_shift_operands.  Use new modifiers.
-	(lshr<mode>3_reg):  Fix rtl description.
+	(lshr<mode>3_reg): Fix rtl description.
 
 	Make sure mulhisi immediate operands are valid.
 	* config/spu/predicates.md (imm_K_operand): Add.
@@ -19488,7 +19510,7 @@
 	* config/spu/spu.c (print_operand): Handle HIGH correctly.
 	(spu_split_immediate): Split CONST_VECTORs with -mlarge-mem.
 	(immediate_load_p): Allow symbols that use 2 instructions to create.
-	(classify_immediate, spu_builtin_splats):  Don't accept a CONST_VECTOR
+	(classify_immediate, spu_builtin_splats): Don't accept a CONST_VECTOR
 	with symbols when flag_pic is set.
 	(const_vector_immediate_p): New.
 	(logical_immediate_p, iohl_immediate_p, arith_immediate_p): Don't
@@ -19531,14 +19553,14 @@
 	* config/spu/spu_internals.h: Ditto.
 
 	Fix incorrect operand modifiers.
-	* config/spu/spu-builtins.md (spu_mpy, spu_mpyu):  Remove use of %H.
-	* config/spu/spu.md (xor<mode>3):  Change %S to %J.
+	* config/spu/spu-builtins.md (spu_mpy, spu_mpyu): Remove use of %H.
+	* config/spu/spu.md (xor<mode>3): Change %S to %J.
 
 	Optimize one case of zero_extend of a vec_select.
-	* config/spu/spu.md (_vec_extractv8hi_ze):  Add.
+	* config/spu/spu.md (_vec_extractv8hi_ze): Add.
 
 	Accept any immediate for hbr.
-	* config/spu/spu.md (hbr):  Change s constraints to i.
+	* config/spu/spu.md (hbr): Change s constraints to i.
 
 2007-02-21  Paul Brook  <paul@codesourcery.com>
 
@@ -19843,7 +19865,7 @@
 2007-02-18  Roger Sayle  <roger@eyesopen.com>
 
 	PR rtl-optimization/28173
-	* simplify-rtx.c (simplify_binary_operation_1) <IOR>:  Optimize
+	* simplify-rtx.c (simplify_binary_operation_1) <IOR>: Optimize
 	(X & C1) | C2 as C2 when (C1 & C2) == C1 and X has no side-effects.
 	Optimize (X & C1) | C2 as X | C2 when (C1 | C2) == ~0.
 	Canonicalize (X & C1) | C2 as (X & (C1 & ~C2)) | C2.
@@ -20275,7 +20297,7 @@
 	of an arglist.  Change return type to bool.  Use new CALL_EXPR
 	accessors.
 
-	(fold_builtin_strstr):  Pass call arguments individually instead
+	(fold_builtin_strstr): Pass call arguments individually instead
 	of as an arglist, fixing callers appropriately.  Use new CALL_EXPR
 	accessors and constructors.  Return NULL_TREE instead of 0.
 	(fold_builtin_strchr): Likewise.
@@ -20320,7 +20342,7 @@
 	(fold_ternary): Remove CALL_EXPR case, since they are no longer
 	ternary expressions.
 	(fold): Add logic for tcc_vl_exp.
-	(fold_checksum_tree):  Make it know about tcc_vl_exp.  Use
+	(fold_checksum_tree): Make it know about tcc_vl_exp.  Use
 	TREE_OPERAND_LENGTH instead of TREE_CODE_LENGTH.
 	(fold_build3_stat): Add assertion to flag broken interface for
 	constructing CALL_EXPRs.
@@ -20350,7 +20372,7 @@
 	* tree-vrp.c (stmt_interesting_for_vrp): Use new CALL_EXPR accessors.
 	(vrp_visit_stmt): Likewise.
 
-	* tree-ssa-loop-im.c (outermost_invariant_loop_expr):  Make it
+	* tree-ssa-loop-im.c (outermost_invariant_loop_expr): Make it
 	know about tcc_vl_exp.  Use TREE_OPERAND_LENGTH instead of
 	TREE_CODE_LENGTH.
 	(force_move_till_expr): Likewise.
@@ -20544,7 +20566,7 @@
 	(estimate_num_insns_1): Use new CALL_EXPR accessors.
 	(expand_call_inline): Tidy up call to initialize_inlined_parameters.
 
-	* tree-vect-transform.c (vect_create_epilog_for_reduction):  Use
+	* tree-vect-transform.c (vect_create_epilog_for_reduction): Use
 	TREE_OPERAND_LENGTH instead of TREE_CODE_LENGTH.
 	(vectorizable_reduction): Likewise.
 	(vectorizable_call): Use new CALL_EXPR iterators.
@@ -20647,7 +20669,7 @@
 	(arm_expand_unop_builtin): Likewise.
 	(arm_expand_builtin): Use new CALL_EXPR accessors.
 
-	* config/mips/mips.c (mips_expand_builtin):  Use new CALL_EXPR
+	* config/mips/mips.c (mips_expand_builtin): Use new CALL_EXPR
 	accessors.
 
 	* config/bfin/bfin.c (bfin_expand_binop_builtin): Pass entire
@@ -22819,7 +22841,7 @@
 	* tree-data-ref.c (tree_fold_divides_p): Don't use tree_fold_gcd to
 	test whether one constant integer is a multiple of another.  Instead
 	call int_const_binop with TRUNC_MOD_EXPR and test for a zero result.
-	* fold-const.c (multiple_of_p):  We've determined both TOP and
+	* fold-const.c (multiple_of_p): We've determined both TOP and
 	BOTTOM are integer constants so we can call int_const_binop directly
 	instead of the more generic const_binop.
 
@@ -22962,7 +22984,7 @@
 
 	PR other/30182
 	* config/pa/pa.c (pa_init_builtins): Set asm names for finite routines.
-	* config/ia64/ia64.c (ia64_init_builtins):  Ditto.
+	* config/ia64/ia64.c (ia64_init_builtins): Ditto.
 
 2007-01-25  Richard Guenther  <rguenther@suse.de>
 
@@ -23505,7 +23527,7 @@
 	* longlong.h (count_leading_zeros, COUNT_LEADING_ZEROS_0): Add
 	ColdFire alternatives.
 	* config/m68k/m68k.h (CLZ_DEFINED_VALUE_AT_ZERO): New macro.
-	* config/m68k/m68k.md (clzsi2):  Define for ColdFire
+	* config/m68k/m68k.md (clzsi2): Define for ColdFire
 	architectures that support ff1 instruction.
 
 2007-01-19  Richard Sandiford  <richard@codesourcery.com>
@@ -25667,7 +25689,7 @@
 
 2007-01-02  Steve Ellcey  <sje@cup.hp.com>
 
-	* sbitmap.c (HOST_BITS_PER_LONG_LONG):  Change to
+	* sbitmap.c (HOST_BITS_PER_LONG_LONG): Change to
 	HOST_BITS_PER_LONGLONG
 
 2007-01-02  Manuel Lopez-Ibanez <manu@gcc.gnu.org>
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 166792c4a40e..566e1cc2e1b8 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -6270,6 +6270,12 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
     case BUILT_IN_ARGS_INFO:
       return expand_builtin_args_info (exp);
 
+    case BUILT_IN_VA_ARG_PACK:
+      /* All valid uses of __builtin_va_arg_pack () are removed during
+	 inlining.  */
+      error ("invalid use of %<__builtin_va_arg_pack ()%>");
+      return const0_rtx;
+
       /* Return the address of the first anonymous stack arg.  */
     case BUILT_IN_NEXT_ARG:
       if (fold_builtin_next_arg (exp, false))
@@ -10472,14 +10478,32 @@ fold_call_expr (tree exp, bool ignore)
   tree fndecl = get_callee_fndecl (exp);
   if (fndecl
       && TREE_CODE (fndecl) == FUNCTION_DECL
-      && DECL_BUILT_IN (fndecl))
-    {
+      && DECL_BUILT_IN (fndecl)
+      /* If CALL_EXPR_VA_ARG_PACK is set, the arguments aren't finalized
+	 yet.  Defer folding until we see all the arguments
+	 (after inlining).  */
+      && !CALL_EXPR_VA_ARG_PACK (exp))
+    {
+      int nargs = call_expr_nargs (exp);
+
+      /* Before gimplification CALL_EXPR_VA_ARG_PACK is not set, but
+	 instead last argument is __builtin_va_arg_pack ().  Defer folding
+	 even in that case, until arguments are finalized.  */
+      if (nargs && TREE_CODE (CALL_EXPR_ARG (exp, nargs - 1)) == CALL_EXPR)
+	{
+	  tree fndecl2 = get_callee_fndecl (CALL_EXPR_ARG (exp, nargs - 1));
+	  if (fndecl2
+	      && TREE_CODE (fndecl2) == FUNCTION_DECL
+	      && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
+	      && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
+	    return NULL_TREE;
+	}
+
       /* FIXME: Don't use a list in this interface.  */
       if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
 	  return targetm.fold_builtin (fndecl, CALL_EXPR_ARGS (exp), ignore);
       else
 	{
-	  int nargs = call_expr_nargs (exp);
 	  if (nargs <= MAX_ARGS_TO_FOLD_BUILTIN)
 	    {
 	      tree *args = CALL_EXPR_ARGP (exp);
@@ -10565,6 +10589,17 @@ fold_builtin_call_array (tree type,
     if (TREE_CODE (fndecl) == FUNCTION_DECL
         && DECL_BUILT_IN (fndecl))
       {
+	/* If last argument is __builtin_va_arg_pack (), arguments to this
+	   function are not finalized yet.  Defer folding until they are.  */
+	if (n && TREE_CODE (argarray[n - 1]) == CALL_EXPR)
+	  {
+	    tree fndecl2 = get_callee_fndecl (argarray[n - 1]);
+	    if (fndecl2
+		&& TREE_CODE (fndecl2) == FUNCTION_DECL
+		&& DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
+		&& DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
+	      return build_call_array (type, fn, n, argarray);
+	  }
         if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
           {
             tree arglist = NULL_TREE;
diff --git a/gcc/builtins.def b/gcc/builtins.def
index 8bedfbf30e93..01ba3b365877 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -701,6 +701,7 @@ DEF_GCC_BUILTIN        (BUILT_IN_UPDATE_SETJMP_BUF, "update_setjmp_buf", BT_FN_V
 DEF_GCC_BUILTIN        (BUILT_IN_VA_COPY, "va_copy", BT_FN_VOID_VALIST_REF_VALIST_ARG, ATTR_NULL)
 DEF_GCC_BUILTIN        (BUILT_IN_VA_END, "va_end", BT_FN_VOID_VALIST_REF, ATTR_NULL)
 DEF_GCC_BUILTIN        (BUILT_IN_VA_START, "va_start", BT_FN_VOID_VALIST_REF_VAR, ATTR_NULL)
+DEF_GCC_BUILTIN        (BUILT_IN_VA_ARG_PACK, "va_arg_pack", BT_FN_INT, ATTR_PURE_NOTHROW_LIST)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN__EXIT, "_exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LIST)
 DEF_C99_BUILTIN        (BUILT_IN__EXIT2, "_Exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LIST)
 
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 0012740476b9..9f306a44e484 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -556,6 +556,32 @@ the containing function.  You should specify, for @var{result}, a value
 returned by @code{__builtin_apply}.
 @end deftypefn
 
+@deftypefn {Built-in Function} __builtin_va_arg_pack ()
+This built-in function represents all anonymous arguments of an inline
+function.  It can be used only in inline functions which will be always
+inlined, never compiled as a separate function, such as those using
+@code{__attribute__ ((__always_inline__))} or
+@code{__attribute__ ((__gnu_inline__))} extern inline functions.
+It must be only passed as last argument to some other function
+with variable arguments.  This is useful for writing small wrapper
+inlines for variable argument functions, when using preprocessor
+macros is undesirable.  For example:
+@smallexample
+extern int myprintf (FILE *f, const char *format, ...);
+extern inline __attribute__ ((__gnu_inline__)) int
+myprintf (FILE *f, const char *format, ...)
+@{
+  int r = fprintf (f, "myprintf: ");
+  if (r < 0)
+    return r;
+  int s = fprintf (f, format, __builtin_va_arg_pack ());
+  if (s < 0)
+    return s;
+  return r + s;
+@}
+@end smallexample
+@end deftypefn
+
 @node Typeof
 @section Referring to a Type with @code{typeof}
 @findex typeof
diff --git a/gcc/expr.c b/gcc/expr.c
index 13f447cc8b6a..054f4f13add7 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -7935,6 +7935,10 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
       return expand_expr (OBJ_TYPE_REF_EXPR (exp), target, tmode, modifier);
 
     case CALL_EXPR:
+      /* All valid uses of __builtin_va_arg_pack () are removed during
+	 inlining.  */
+      if (CALL_EXPR_VA_ARG_PACK (exp))
+	error ("invalid use of %<__builtin_va_arg_pack ()%>");
       /* Check for a built-in function.  */
       if (TREE_CODE (CALL_EXPR_FN (exp)) == ADDR_EXPR
 	  && (TREE_CODE (TREE_OPERAND (CALL_EXPR_FN (exp), 0))
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 5c376ac50601..ee8ef09a1030 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -2170,8 +2170,50 @@ gimplify_call_expr (tree *expr_p, tree *pre_p, bool want_value)
 	    }
 	}
     }
-  else if (nargs != 0)
-    CALL_CANNOT_INLINE_P (*expr_p) = 1;
+  else
+    {
+      if (nargs != 0)
+	CALL_CANNOT_INLINE_P (*expr_p) = 1;
+      i = 0;
+      p = NULL_TREE;
+    }
+
+  /* If the last argument is __builtin_va_arg_pack () and it is not
+     passed as a named argument, decrease the number of CALL_EXPR
+     arguments and set instead the CALL_EXPR_VA_ARG_PACK flag.  */
+  if (!p
+      && i < nargs
+      && TREE_CODE (CALL_EXPR_ARG (*expr_p, nargs - 1)) == CALL_EXPR)
+    {
+      tree last_arg = CALL_EXPR_ARG (*expr_p, nargs - 1);
+      tree last_arg_fndecl = get_callee_fndecl (last_arg);
+
+      if (last_arg_fndecl
+	  && TREE_CODE (last_arg_fndecl) == FUNCTION_DECL
+	  && DECL_BUILT_IN_CLASS (last_arg_fndecl) == BUILT_IN_NORMAL
+	  && DECL_FUNCTION_CODE (last_arg_fndecl) == BUILT_IN_VA_ARG_PACK)
+	{
+	  tree call = *expr_p;
+
+	  --nargs;
+	  *expr_p = build_call_array (TREE_TYPE (call), CALL_EXPR_FN (call),
+				      nargs, CALL_EXPR_ARGP (call));
+	  /* Copy all CALL_EXPR flags, locus and block, except
+	     CALL_EXPR_VA_ARG_PACK flag.  */
+	  CALL_EXPR_STATIC_CHAIN (*expr_p) = CALL_EXPR_STATIC_CHAIN (call);
+	  CALL_EXPR_TAILCALL (*expr_p) = CALL_EXPR_TAILCALL (call);
+	  CALL_EXPR_RETURN_SLOT_OPT (*expr_p)
+	    = CALL_EXPR_RETURN_SLOT_OPT (call);
+	  CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call);
+	  CALL_CANNOT_INLINE_P (*expr_p)
+	    = CALL_CANNOT_INLINE_P (call);
+	  TREE_NOTHROW (*expr_p) = TREE_NOTHROW (call);
+	  SET_EXPR_LOCUS (*expr_p, EXPR_LOCUS (call));
+	  TREE_BLOCK (*expr_p) = TREE_BLOCK (call);
+	  /* Set CALL_EXPR_VA_ARG_PACK.  */
+	  CALL_EXPR_VA_ARG_PACK (*expr_p) = 1;
+	}
+    }
 
   /* Finally, gimplify the function arguments.  */
   for (i = (PUSH_ARGS_REVERSED ? nargs - 1 : 0);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index aeaad7277a52..7a2a20bd149a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2007-09-05  Jakub Jelinek  <jakub@redhat.com>
+
+	* gcc.c-torture/execute/va-arg-pack-1.c: New test.
+	* gcc.dg/va-arg-pack-1.c: New test.
+
 2007-09-05  Adam Nemet  <anemet@caviumnetworks.com>
 
 	* gcc.dg/tree-ssa/builtin-expect-1.c: New test.
diff --git a/gcc/testsuite/gcc.c-torture/execute/va-arg-pack-1.c b/gcc/testsuite/gcc.c-torture/execute/va-arg-pack-1.c
new file mode 100644
index 000000000000..baefe8758219
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/va-arg-pack-1.c
@@ -0,0 +1,143 @@
+/* __builtin_va_arg_pack () builtin tests.  */
+
+#include <stdarg.h>
+
+extern void abort (void);
+
+int v1 = 8;
+long int v2 = 3;
+void *v3 = (void *) &v2;
+struct A { char c[16]; } v4 = { "foo" };
+long double v5 = 40;
+char seen[20];
+int cnt;
+
+__attribute__ ((noinline)) int
+foo1 (int x, int y, ...)
+{
+  int i;
+  long int l;
+  void *v;
+  struct A a;
+  long double ld;
+  va_list ap;
+
+  va_start (ap, y);
+  if (x < 0 || x >= 20 || seen[x])
+    abort ();
+  seen[x] = ++cnt;
+  if (y != 6)
+    abort ();
+  i = va_arg (ap, int);
+  if (i != 5)
+    abort ();
+  switch (x)
+    {
+    case 0:
+      i = va_arg (ap, int);
+      if (i != 9 || v1 != 9)
+	abort ();
+      a = va_arg (ap, struct A);
+      if (__builtin_memcmp (a.c, v4.c, sizeof (a.c)) != 0)
+	abort ();
+      v = (void *) va_arg (ap, struct A *);
+      if (v != (void *) &v4)
+	abort ();
+      l = va_arg (ap, long int);
+      if (l != 3 || v2 != 4)
+	abort ();
+      break;
+    case 1:
+      ld = va_arg (ap, long double);
+      if (ld != 41 || v5 != ld)
+	abort ();
+      i = va_arg (ap, int);
+      if (i != 8)
+	abort ();
+      v = va_arg (ap, void *);
+      if (v != &v2)
+	abort ();
+      break;
+    case 2:
+      break;
+    default:
+      abort ();
+    }
+  va_end (ap);
+  return x;
+}
+
+__attribute__ ((noinline)) int
+foo2 (int x, int y, ...)
+{
+  long long int ll;
+  void *v;
+  struct A a, b;
+  long double ld;
+  va_list ap;
+
+  va_start (ap, y);
+  if (x < 0 || x >= 20 || seen[x])
+    abort ();
+  seen[x] = ++cnt | 64;
+  if (y != 10)
+    abort ();
+  switch (x)
+    {
+    case 11:
+      break;
+    case 12:
+      ld = va_arg (ap, long double);
+      if (ld != 41 || v5 != 40)
+	abort ();
+      a = va_arg (ap, struct A);
+      if (__builtin_memcmp (a.c, v4.c, sizeof (a.c)) != 0)
+	abort ();
+      b = va_arg (ap, struct A);
+      if (__builtin_memcmp (b.c, v4.c, sizeof (b.c)) != 0)
+	abort ();
+      v = va_arg (ap, void *);
+      if (v != &v2)
+	abort ();
+      ll = va_arg (ap, long long int);
+      if (ll != 16LL)
+	abort ();
+      break;
+    case 2:
+      break;
+    default:
+      abort ();
+    }
+  va_end (ap);
+  return x + 8;
+}
+
+__attribute__ ((noinline)) int
+foo3 (void)
+{
+  return 6;
+}
+
+extern inline __attribute__ ((always_inline, gnu_inline)) int
+bar (int x, ...)
+{
+  if (x < 10)
+    return foo1 (x, foo3 (), 5, __builtin_va_arg_pack ());
+  return foo2 (x, foo3 () + 4, __builtin_va_arg_pack ());
+}
+
+int
+main (void)
+{
+  if (bar (0, ++v1, v4, &v4, v2++) != 0)
+    abort ();
+  if (bar (1, ++v5, 8, v3) != 1)
+    abort ();
+  if (bar (2) != 2)
+    abort ();
+  if (bar (v1 + 2) != 19)
+    abort ();
+  if (bar (v1 + 3, v5--, v4, v4, v3, 16LL) != 20)
+    abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/va-arg-pack-1.c b/gcc/testsuite/gcc.dg/va-arg-pack-1.c
new file mode 100644
index 000000000000..09ae97917e4a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/va-arg-pack-1.c
@@ -0,0 +1,52 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int bar (int, const char *, int, ...);
+int baz (int, const char *, long int);
+
+int
+f1 (int x, ...)
+{
+  return bar (5, "", 6, __builtin_va_arg_pack ());	/* { dg-error "invalid use of" } */
+}
+
+extern inline __attribute__((always_inline)) int
+f2 (int y, ...)
+{
+  return bar (y, "", __builtin_va_arg_pack ());		/* { dg-error "invalid use of" } */
+}
+
+extern inline __attribute__((always_inline)) int
+f3 (int y, ...)
+{
+  return bar (y, "", 5, __builtin_va_arg_pack ());
+}
+
+extern inline __attribute__((always_inline)) int
+f4 (int y, ...)
+{
+  return bar (y, "", 4, __builtin_va_arg_pack (), 6);	/* { dg-error "invalid use of" } */
+}
+
+extern inline __attribute__((always_inline)) int
+f5 (int y, ...)
+{
+  return baz (y, "", __builtin_va_arg_pack ());		/* { dg-error "invalid use of" } */
+}
+
+extern inline __attribute__((always_inline)) int
+f6 (int y, ...)
+{
+  return __builtin_va_arg_pack ();			/* { dg-error "invalid use of" } */
+}
+
+int
+test (void)
+{
+  int a = f2 (5, "a", 6);
+  a += f3 (6, "ab", 17LL);
+  a += f4 (7, 1, 2, 3);
+  a += f5 (8, 7L);
+  a += f6 (9);
+  return a;
+}
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index b655b79ac01d..d49c3c8c4905 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -815,9 +815,59 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, int count_scal
 	     into multiple statements, we need to process all of them.  */
 	  while (!bsi_end_p (copy_bsi))
 	    {
-	      stmt = bsi_stmt (copy_bsi);
+	      tree *stmtp = bsi_stmt_ptr (copy_bsi);
+	      tree stmt = *stmtp;
 	      call = get_call_expr_in (stmt);
 
+	      if (call && CALL_EXPR_VA_ARG_PACK (call) && id->call_expr)
+		{
+		  /* __builtin_va_arg_pack () should be replaced by
+		     all arguments corresponding to ... in the caller.  */
+		  tree p, *argarray, new_call, *call_ptr;
+		  int nargs = call_expr_nargs (id->call_expr);
+
+		  for (p = DECL_ARGUMENTS (id->src_fn); p; p = TREE_CHAIN (p))
+		    nargs--;
+
+		  argarray = (tree *) alloca ((nargs + call_expr_nargs (call))
+					      * sizeof (tree));
+
+		  memcpy (argarray, CALL_EXPR_ARGP (call),
+			  call_expr_nargs (call) * sizeof (*argarray));
+		  memcpy (argarray + call_expr_nargs (call),
+			  CALL_EXPR_ARGP (id->call_expr)
+			  + (call_expr_nargs (id->call_expr) - nargs),
+			  nargs * sizeof (*argarray));
+
+		  new_call = build_call_array (TREE_TYPE (call),
+					       CALL_EXPR_FN (call),
+					       nargs + call_expr_nargs (call),
+					       argarray);
+		  /* Copy all CALL_EXPR flags, locus and block, except
+		     CALL_EXPR_VA_ARG_PACK flag.  */
+		  CALL_EXPR_STATIC_CHAIN (new_call)
+		    = CALL_EXPR_STATIC_CHAIN (call);
+		  CALL_EXPR_TAILCALL (new_call) = CALL_EXPR_TAILCALL (call);
+		  CALL_EXPR_RETURN_SLOT_OPT (new_call)
+		    = CALL_EXPR_RETURN_SLOT_OPT (call);
+		  CALL_FROM_THUNK_P (new_call) = CALL_FROM_THUNK_P (call);
+		  CALL_CANNOT_INLINE_P (new_call)
+		    = CALL_CANNOT_INLINE_P (call);
+		  TREE_NOTHROW (new_call) = TREE_NOTHROW (call);
+		  SET_EXPR_LOCUS (new_call, EXPR_LOCUS (call));
+		  TREE_BLOCK (new_call) = TREE_BLOCK (call);
+
+		  call_ptr = stmtp;
+		  if (TREE_CODE (*call_ptr) == GIMPLE_MODIFY_STMT)
+		    call_ptr = &GIMPLE_STMT_OPERAND (*call_ptr, 1);
+		  if (TREE_CODE (*call_ptr) == WITH_SIZE_EXPR)
+		    call_ptr = &TREE_OPERAND (*call_ptr, 0);
+		  gcc_assert (*call_ptr == call);
+		  *call_ptr = new_call;
+		  stmt = *stmtp;
+		  update_stmt (stmt);
+		}
+
 	      /* Statements produced by inlining can be unfolded, especially
 		 when we constant propagated some operands.  We can't fold
 		 them right now for two reasons:
@@ -2518,6 +2568,7 @@ expand_call_inline (basic_block bb, tree stmt, tree *tp, void *data)
   id->src_fn = fn;
   id->src_node = cg_edge->callee;
   id->src_cfun = DECL_STRUCT_FUNCTION (fn);
+  id->call_expr = t;
 
   initialize_inlined_parameters (id, t, fn, bb);
 
diff --git a/gcc/tree-inline.h b/gcc/tree-inline.h
index 574b1d70040f..1fa360ad3459 100644
--- a/gcc/tree-inline.h
+++ b/gcc/tree-inline.h
@@ -56,6 +56,10 @@ typedef struct copy_body_data
   /* Current BLOCK.  */
   tree block;
 
+  /* CALL_EXPR if va arg parameter packs should be expanded or NULL
+     is not.  */
+  tree call_expr;
+
   /* Exception region the inlined call lie in.  */
   int eh_region;
   /* Take region number in the function being copied, add this value and
diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
index 8da7ade6a110..bc7ebf4ea79b 100644
--- a/gcc/tree-pretty-print.c
+++ b/gcc/tree-pretty-print.c
@@ -1228,6 +1228,15 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 	      }
 	  }
       }
+      if (CALL_EXPR_VA_ARG_PACK (node))
+	{
+	  if (call_expr_nargs (node) > 0)
+	    {
+	      pp_character (buffer, ',');
+	      pp_space (buffer);
+	    }
+	  pp_string (buffer, "__builtin_va_arg_pack ()");
+	}
       pp_character (buffer, ')');
 
       op1 = CALL_EXPR_STATIC_CHAIN (node);
diff --git a/gcc/tree.h b/gcc/tree.h
index 5fda4d4b3a18..c274fb6ec245 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -464,6 +464,8 @@ struct gimple_stmt GTY(())
            VAR_DECL or FUNCTION_DECL or IDENTIFIER_NODE
        ASM_VOLATILE_P in
            ASM_EXPR
+       CALL_EXPR_VA_ARG_PACK in
+	  CALL_EXPR
        TYPE_CACHED_VALUES_P in
           ..._TYPE
        SAVE_EXPR_RESOLVED_P in
@@ -1222,6 +1224,11 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
 #define SAVE_EXPR_RESOLVED_P(NODE) \
   (TREE_CHECK (NODE, SAVE_EXPR)->base.public_flag)
 
+/* Set on a CALL_EXPR if this stdarg call should be passed the argument
+   pack.  */
+#define CALL_EXPR_VA_ARG_PACK(NODE) \
+  (CALL_EXPR_CHECK(NODE)->base.public_flag)
+
 /* In any expression, decl, or constant, nonzero means it has side effects or
    reevaluation of the whole expression could produce a different value.
    This is set if any subexpression is a function call, a side effect or a
-- 
GitLab