diff options
author | hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-03-27 22:57:57 +0000 |
---|---|---|
committer | hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-03-27 22:57:57 +0000 |
commit | 1ad9855894ce874c82fb2529176d12a0dca7d161 (patch) | |
tree | 50631967d69624a3bb07421ce25ec1325a5e33a4 | |
parent | f62137abf2a8e0ab8e518c430d3d941b1debd894 (diff) |
Merged with trunk at revision 145121.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/ix86/atom@145141 138bc75d-0d04-0410-961f-82ee72b054a4
50 files changed, 2006 insertions, 187 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8eeb1053050..9ca01a2b653 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,85 @@ +2009-03-27 Xinliang David Li <davidxl@google.com> + + PR tree-optimization/39557 + * tree-ssa.c (warn_uninitialized_vars): free postdom info. + +2009-03-27 Xinliang David Li <davidxl@google.com> + + PR tree-optimization/39548 + * tree-ssa-copy.c (copy_prop_visit_phi_node): Add copy + candidate check. + +2009-03-27 H.J. Lu <hongjiu.lu@intel.com> + + * c-common.c (pointer_int_sum): Use %wd on return from + tree_low_cst. + +2009-03-27 H.J. Lu <hongjiu.lu@intel.com> + + * c-common.c (pointer_int_sum): Use HOST_WIDE_INT_PRINT_DEC + on return from tree_low_cst. + +2009-03-27 Andrew Pinski <andrew_pinski@playstation.sony.com> + + PR c++/36799 + * ginclude/stdarg.h (va_copy): Define also for __GXX_EXPERIMENTAL_CXX0X__. + +2009-03-27 Manuel Lopez-Ibanez <manu@gcc.gnu.org> + + PR c++/35652 + * builtins.h (c_strlen): Do not warn here. + * c-typeck.c (build_binary_op): Adjust calls to pointer_int_sum. + * c-common.c (pointer_int_sum): Take an explicit location. + Warn about offsets out of bounds. + * c-common.h (pointer_int_sum): Adjust declaration. + +2009-03-26 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + + * doc/invoke.texi (i386 and x86-64 Windows Options): Fix texinfo + markup glitch. + +2009-03-26 Jakub Jelinek <jakub@redhat.com> + + PR c++/39554 + * opts.c (warn_if_disallowed_function_p): Don't assume + get_callee_fndecl must return non-NULL. + +2009-03-26 Vladimir Makarov <vmakarov@redhat.com> + + PR rtl-optimization/39522 + * reload1.c (reload_as_needed): Invalidate reg_last_reload_reg too + when reg_reloaded_valid is set. + +2009-03-26 Ulrich Weigand <Ulrich.Weigand@de.ibm.com> + + * config/spu/divv2df3.c: New file. + * config/spu/t-spu-elf (LIB2FUNCS_STATIC_EXTRA): Add it. + (DPBIT_FUNCS): Filter out _div_df. + +2009-03-26 Bernd Schmidt <bernd.schmidt@analog.com> + + * config/bfin/bfin.c (bfin_optimize_loop): If the LSETUP goes before + a jump insn, count that jump in the distance to the loop start. + +2009-03-25 Kaz Kojima <kkojima@gcc.gnu.org> + + PR target/39523 + * config/sh/sh.c (calc_live_regs): Fix condition for global + registers except PIC_OFFSET_TABLE_REGNUM. + +2009-03-25 Kai Tietz <kai.tietz@onevision.com> + + PR/39518 + * doc/invoke.texi (-mconsole): New. + (-mcygwin): New. + (-mno-cygwin): New. + (-mdll): New. + (-mnop-fun-dllimport): New. + (-mthread): New. + (-mwin32): New. + (-mwindows): New. + (sub section "i386 and x86-64 Windows Options"): New. + 2009-03-25 Ralf Corsépius <ralf.corsepius@rtems.org> * config/arm/rtems-elf.h: Remove LINK_GCC_C_SEQUENCE_SPEC. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 7e93ddc1aee..8b355c9c929 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20090325 +20090327 diff --git a/gcc/builtins.c b/gcc/builtins.c index cc9d93e2311..929ea9069cb 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -469,16 +469,13 @@ c_strlen (tree src, int only_value) else offset = tree_low_cst (offset_node, 0); - /* If the offset is known to be out of bounds, warn, and call strlen at - runtime. */ + /* If the offset is known to be out of bounds, the front-end should + have warned already. We call strlen at runtime. + + ??? Perhaps we should turn this into an assert and force + front-ends to define offsets whtin boundaries. */ if (offset < 0 || offset > max) { - /* Suppress multiple warnings for propagated constant strings. */ - if (! TREE_NO_WARNING (src)) - { - warning (0, "offset outside bounds of constant string"); - TREE_NO_WARNING (src) = 1; - } return NULL_TREE; } diff --git a/gcc/c-common.c b/gcc/c-common.c index cc00511cc0c..820d859c5bb 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -3211,7 +3211,8 @@ shorten_compare (tree *op0_ptr, tree *op1_ptr, tree *restype_ptr, of pointer PTROP and integer INTOP. */ tree -pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop) +pointer_int_sum (location_t location, enum tree_code resultcode, + tree ptrop, tree intop) { tree size_exp, ret; @@ -3220,19 +3221,19 @@ pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop) if (TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE) { - pedwarn (input_location, pedantic ? OPT_pedantic : OPT_Wpointer_arith, + pedwarn (location, pedantic ? OPT_pedantic : OPT_Wpointer_arith, "pointer of type %<void *%> used in arithmetic"); size_exp = integer_one_node; } else if (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE) { - pedwarn (input_location, pedantic ? OPT_pedantic : OPT_Wpointer_arith, + pedwarn (location, pedantic ? OPT_pedantic : OPT_Wpointer_arith, "pointer to a function used in arithmetic"); size_exp = integer_one_node; } else if (TREE_CODE (TREE_TYPE (result_type)) == METHOD_TYPE) { - pedwarn (input_location, pedantic ? OPT_pedantic : OPT_Wpointer_arith, + pedwarn (location, pedantic ? OPT_pedantic : OPT_Wpointer_arith, "pointer to member function used in arithmetic"); size_exp = integer_one_node; } @@ -3295,6 +3296,31 @@ pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop) if (resultcode == MINUS_EXPR) intop = fold_build1 (NEGATE_EXPR, sizetype, intop); + if (TREE_CODE (intop) == INTEGER_CST) + { + tree offset_node; + tree string_cst = string_constant (ptrop, &offset_node); + + if (string_cst != 0 + && !(offset_node && TREE_CODE (offset_node) != INTEGER_CST)) + { + HOST_WIDE_INT max = TREE_STRING_LENGTH (string_cst); + HOST_WIDE_INT offset; + if (offset_node == 0) + offset = 0; + else if (! host_integerp (offset_node, 0)) + offset = -1; + else + offset = tree_low_cst (offset_node, 0); + + offset = offset + tree_low_cst (intop, 0); + if (offset < 0 || offset > max) + warning_at (location, 0, + "offset %<%wd%> outside bounds of constant string", + tree_low_cst (intop, 0)); + } + } + ret = fold_build2 (POINTER_PLUS_EXPR, result_type, ptrop, intop); fold_undefer_and_ignore_overflow_warnings (); diff --git a/gcc/c-common.h b/gcc/c-common.h index 475c3334592..6ba33c6aedc 100644 --- a/gcc/c-common.h +++ b/gcc/c-common.h @@ -746,7 +746,7 @@ extern tree shorten_binary_op (tree result_type, tree op0, tree op1, bool bitwis and, if so, perhaps change them both back to their original type. */ extern tree shorten_compare (tree *, tree *, tree *, enum tree_code *); -extern tree pointer_int_sum (enum tree_code, tree, tree); +extern tree pointer_int_sum (location_t, enum tree_code, tree, tree); /* Add qualifiers to a type, in the fashion for C. */ extern tree c_build_qualified_type (tree, int); diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index f1d83f3c20c..83188baf22f 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -8107,12 +8107,12 @@ build_binary_op (location_t location, enum tree_code code, /* Handle the pointer + int case. */ if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) { - ret = pointer_int_sum (PLUS_EXPR, op0, op1); + ret = pointer_int_sum (location, PLUS_EXPR, op0, op1); goto return_build_binary_op; } else if (code1 == POINTER_TYPE && code0 == INTEGER_TYPE) { - ret = pointer_int_sum (PLUS_EXPR, op1, op0); + ret = pointer_int_sum (location, PLUS_EXPR, op1, op0); goto return_build_binary_op; } else @@ -8131,7 +8131,7 @@ build_binary_op (location_t location, enum tree_code code, /* Handle pointer minus int. Just like pointer plus int. */ else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) { - ret = pointer_int_sum (MINUS_EXPR, op0, op1); + ret = pointer_int_sum (location, MINUS_EXPR, op0, op1); goto return_build_binary_op; } else diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c index f4f9d45e321..d1c964d02ea 100644 --- a/gcc/config/bfin/bfin.c +++ b/gcc/config/bfin/bfin.c @@ -3854,9 +3854,17 @@ bfin_optimize_loop (loop_info loop) /* Make sure the predecessor is before the loop start label, as required by the LSETUP instruction. */ length = 0; - for (insn = BB_END (loop->incoming_src); - insn && insn != loop->start_label; - insn = NEXT_INSN (insn)) + insn = BB_END (loop->incoming_src); + /* If we have to insert the LSETUP before a jump, count that jump in the + length. */ + if (VEC_length (edge, loop->incoming) > 1 + || !(VEC_last (edge, loop->incoming)->flags & EDGE_FALLTHRU)) + { + gcc_assert (JUMP_P (insn)); + insn = PREV_INSN (insn); + } + + for (; insn && insn != loop->start_label; insn = NEXT_INSN (insn)) length += length_for_loop (insn); if (!insn) diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index 3c57730b83e..c8f4c85ee75 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -5966,7 +5966,9 @@ calc_live_regs (HARD_REG_SET *live_regs_mask) && crtl->args.info.call_cookie && reg == PIC_OFFSET_TABLE_REGNUM) || (df_regs_ever_live_p (reg) - && (!call_really_used_regs[reg] + && ((!call_really_used_regs[reg] + && !(reg != PIC_OFFSET_TABLE_REGNUM + && fixed_regs[reg] && call_used_regs[reg])) || (trapa_handler && reg == FPSCR_REG && TARGET_FPU_ANY))) || (crtl->calls_eh_return && (reg == EH_RETURN_DATA_REGNO (0) diff --git a/gcc/config/spu/divv2df3.c b/gcc/config/spu/divv2df3.c new file mode 100644 index 00000000000..cd7126bb733 --- /dev/null +++ b/gcc/config/spu/divv2df3.c @@ -0,0 +1,198 @@ +/* Copyright (C) 2009 Free Software Foundation, Inc. + + This file is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your option) + any later version. + + This file is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with this file; see the file COPYING. If not, write to the Free + Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +/* As a special exception, if you link this library with files compiled with + GCC to produce an executable, this does not cause the resulting executable + to be covered by the GNU General Public License. The exception does not + however invalidate any other reasons why the executable file might be covered + by the GNU General Public License. */ + + +#include <spu_intrinsics.h> + +vector double __divv2df3 (vector double a_in, vector double b_in); + +/* __divv2df3 divides the vector dividend a by the vector divisor b and + returns the resulting vector quotient. Maximum error about 0.5 ulp + over entire double range including denorms, compared to true result + in round-to-nearest rounding mode. Handles Inf or NaN operands and + results correctly. */ + +vector double +__divv2df3 (vector double a_in, vector double b_in) +{ + /* Variables */ + vec_int4 exp, exp_bias; + vec_uint4 no_underflow, overflow; + vec_float4 mant_bf, inv_bf; + vec_ullong2 exp_a, exp_b; + vec_ullong2 a_nan, a_zero, a_inf, a_denorm, a_denorm0; + vec_ullong2 b_nan, b_zero, b_inf, b_denorm, b_denorm0; + vec_ullong2 nan; + vec_uint4 a_exp, b_exp; + vec_ullong2 a_mant_0, b_mant_0; + vec_ullong2 a_exp_1s, b_exp_1s; + vec_ullong2 sign_exp_mask; + + vec_double2 a, b; + vec_double2 mant_a, mant_b, inv_b, q0, q1, q2, mult; + + /* Constants */ + vec_uint4 exp_mask_u32 = spu_splats((unsigned int)0x7FF00000); + vec_uchar16 splat_hi = (vec_uchar16){0,1,2,3, 0,1,2,3, 8, 9,10,11, 8,9,10,11}; + vec_uchar16 swap_32 = (vec_uchar16){4,5,6,7, 0,1,2,3, 12,13,14,15, 8,9,10,11}; + vec_ullong2 exp_mask = spu_splats(0x7FF0000000000000ULL); + vec_ullong2 sign_mask = spu_splats(0x8000000000000000ULL); + vec_float4 onef = spu_splats(1.0f); + vec_double2 one = spu_splats(1.0); + vec_double2 exp_53 = (vec_double2)spu_splats(0x0350000000000000ULL); + + sign_exp_mask = spu_or(sign_mask, exp_mask); + + /* Extract the floating point components from each of the operands including + * exponent and mantissa. + */ + a_exp = (vec_uint4)spu_and((vec_uint4)a_in, exp_mask_u32); + a_exp = spu_shuffle(a_exp, a_exp, splat_hi); + b_exp = (vec_uint4)spu_and((vec_uint4)b_in, exp_mask_u32); + b_exp = spu_shuffle(b_exp, b_exp, splat_hi); + + a_mant_0 = (vec_ullong2)spu_cmpeq((vec_uint4)spu_andc((vec_ullong2)a_in, sign_exp_mask), 0); + a_mant_0 = spu_and(a_mant_0, spu_shuffle(a_mant_0, a_mant_0, swap_32)); + + b_mant_0 = (vec_ullong2)spu_cmpeq((vec_uint4)spu_andc((vec_ullong2)b_in, sign_exp_mask), 0); + b_mant_0 = spu_and(b_mant_0, spu_shuffle(b_mant_0, b_mant_0, swap_32)); + + a_exp_1s = (vec_ullong2)spu_cmpeq(a_exp, exp_mask_u32); + b_exp_1s = (vec_ullong2)spu_cmpeq(b_exp, exp_mask_u32); + + /* Identify all possible special values that must be accomodated including: + * +-denorm, +-0, +-infinity, and NaNs. + */ + a_denorm0= (vec_ullong2)spu_cmpeq(a_exp, 0); + a_nan = spu_andc(a_exp_1s, a_mant_0); + a_zero = spu_and (a_denorm0, a_mant_0); + a_inf = spu_and (a_exp_1s, a_mant_0); + a_denorm = spu_andc(a_denorm0, a_zero); + + b_denorm0= (vec_ullong2)spu_cmpeq(b_exp, 0); + b_nan = spu_andc(b_exp_1s, b_mant_0); + b_zero = spu_and (b_denorm0, b_mant_0); + b_inf = spu_and (b_exp_1s, b_mant_0); + b_denorm = spu_andc(b_denorm0, b_zero); + + /* Scale denorm inputs to into normalized numbers by conditionally scaling the + * input parameters. + */ + a = spu_sub(spu_or(a_in, exp_53), spu_sel(exp_53, a_in, sign_mask)); + a = spu_sel(a_in, a, a_denorm); + + b = spu_sub(spu_or(b_in, exp_53), spu_sel(exp_53, b_in, sign_mask)); + b = spu_sel(b_in, b, b_denorm); + + /* Extract the divisor and dividend exponent and force parameters into the signed + * range [1.0,2.0) or [-1.0,2.0). + */ + exp_a = spu_and((vec_ullong2)a, exp_mask); + exp_b = spu_and((vec_ullong2)b, exp_mask); + + mant_a = spu_sel(a, one, (vec_ullong2)exp_mask); + mant_b = spu_sel(b, one, (vec_ullong2)exp_mask); + + /* Approximate the single reciprocal of b by using + * the single precision reciprocal estimate followed by one + * single precision iteration of Newton-Raphson. + */ + mant_bf = spu_roundtf(mant_b); + inv_bf = spu_re(mant_bf); + inv_bf = spu_madd(spu_nmsub(mant_bf, inv_bf, onef), inv_bf, inv_bf); + + /* Perform 2 more Newton-Raphson iterations in double precision. The + * result (q1) is in the range (0.5, 2.0). + */ + inv_b = spu_extend(inv_bf); + inv_b = spu_madd(spu_nmsub(mant_b, inv_b, one), inv_b, inv_b); + q0 = spu_mul(mant_a, inv_b); + q1 = spu_madd(spu_nmsub(mant_b, q0, mant_a), inv_b, q0); + + /* Determine the exponent correction factor that must be applied + * to q1 by taking into account the exponent of the normalized inputs + * and the scale factors that were applied to normalize them. + */ + exp = spu_rlmaska(spu_sub((vec_int4)exp_a, (vec_int4)exp_b), -20); + exp = spu_add(exp, (vec_int4)spu_add(spu_and((vec_int4)a_denorm, -0x34), spu_and((vec_int4)b_denorm, 0x34))); + + /* Bias the quotient exponent depending on the sign of the exponent correction + * factor so that a single multiplier will ensure the entire double precision + * domain (including denorms) can be achieved. + * + * exp bias q1 adjust exp + * ===== ======== ========== + * positive 2^+65 -65 + * negative 2^-64 +64 + */ + exp_bias = spu_xor(spu_rlmaska(exp, -31), 64); + exp = spu_sub(exp, exp_bias); + + q1 = spu_sel(q1, (vec_double2)spu_add((vec_int4)q1, spu_sl(exp_bias, 20)), exp_mask); + + /* Compute a multiplier (mult) to applied to the quotient (q1) to produce the + * expected result. On overflow, clamp the multiplier to the maximum non-infinite + * number in case the rounding mode is not round-to-nearest. + */ + exp = spu_add(exp, 0x3FF); + no_underflow = spu_cmpgt(exp, 0); + overflow = spu_cmpgt(exp, 0x7FE); + exp = spu_and(spu_sl(exp, 20), (vec_int4)no_underflow); + exp = spu_and(exp, (vec_int4)exp_mask); + + mult = spu_sel((vec_double2)exp, (vec_double2)(spu_add((vec_uint4)exp_mask, -1)), (vec_ullong2)overflow); + + /* Handle special value conditions. These include: + * + * 1) IF either operand is a NaN OR both operands are 0 or INFINITY THEN a NaN + * results. + * 2) ELSE IF the dividend is an INFINITY OR the divisor is 0 THEN a INFINITY results. + * 3) ELSE IF the dividend is 0 OR the divisor is INFINITY THEN a 0 results. + */ + mult = spu_andc(mult, (vec_double2)spu_or(a_zero, b_inf)); + mult = spu_sel(mult, (vec_double2)exp_mask, spu_or(a_inf, b_zero)); + + nan = spu_or(a_nan, b_nan); + nan = spu_or(nan, spu_and(a_zero, b_zero)); + nan = spu_or(nan, spu_and(a_inf, b_inf)); + + mult = spu_or(mult, (vec_double2)nan); + + /* Scale the final quotient */ + + q2 = spu_mul(q1, mult); + + return (q2); +} + + +/* We use the same function for vector and scalar division. Provide the + scalar entry point as an alias. */ +double __divdf3 (double a, double b) + __attribute__ ((__alias__ ("__divv2df3"))); + +/* Some toolchain builds used the __fast_divdf3 name for this helper function. + Provide this as another alternate entry point for compatibility. */ +double __fast_divdf3 (double a, double b) + __attribute__ ((__alias__ ("__divv2df3"))); + diff --git a/gcc/config/spu/t-spu-elf b/gcc/config/spu/t-spu-elf index 2e1928707df..f8c5ba5b01d 100644 --- a/gcc/config/spu/t-spu-elf +++ b/gcc/config/spu/t-spu-elf @@ -29,6 +29,10 @@ TARGET_LIBGCC2_CFLAGS = -fPIC -mwarn-reloc -D__IN_LIBGCC2 # own versions below. LIB2FUNCS_EXCLUDE = _floatdisf _floatundisf +# We provide our own version of __divdf3 that performs better and has +# better support for non-default rounding modes. +DPBIT_FUNCS := $(filter-out _div_df, $(DPBIT_FUNCS)) + LIB2FUNCS_STATIC_EXTRA = $(srcdir)/config/spu/float_unssidf.c \ $(srcdir)/config/spu/float_unsdidf.c \ $(srcdir)/config/spu/float_unsdisf.c \ @@ -39,7 +43,8 @@ LIB2FUNCS_STATIC_EXTRA = $(srcdir)/config/spu/float_unssidf.c \ $(srcdir)/config/spu/mfc_multi_tag_reserve.c \ $(srcdir)/config/spu/mfc_multi_tag_release.c \ $(srcdir)/config/spu/multi3.c \ - $(srcdir)/config/spu/divmodti4.c + $(srcdir)/config/spu/divmodti4.c \ + $(srcdir)/config/spu/divv2df3.c LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde.c \ $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2d4c9f3aa21..6fcd92a8822 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,35 @@ +2009-03-27 Andrew Pinski <andrew_pinski@playstation.sony.com> + + PR c++/38638 + * parser.c (cp_parser_elaborated_type_specifier): If we have a + typename tag and don't have either a TYPE_DECL or a + TEMPLATE_ID_EXPR, set the type to NULL. + +2009-03-27 Simon Martin <simartin@users.sourceforge.net> + + PR c++/37647 + * decl.c (grokdeclarator): Reject [con|de]stuctors in a non-class + scope. + +2009-03-27 Simon Martin <simartin@users.sourceforge.net> + + PR c++/29727 + * decl.c (check_array_designated_initializer): Handle error_mark_node. + +2009-03-27 Manuel Lopez-Ibanez <manu@gcc.gnu.org> + + PR c++/35652 + * typeck.c (cp_pointer_sum): Adjust call to pointer_int_sum. + +2009-03-26 Andrew Haley <aph@redhat.com> + + PR C++/39380 + * decl2.c (possibly_inlined_p): If java exceptions are in use + don't inline a decl unless it is explicitly marked inline. + * lex.c: (pragma_java_exceptions): New variable. + (handle_pragma_java_exceptions): Set pragma_java_exceptions. + * cp-tree.h (pragma_java_exceptions): Declare new variable. + 2009-03-24 Jason Merrill <jason@redhat.com> PR c++/28274 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 1745ede53c3..6b67d2dd62c 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4171,6 +4171,9 @@ struct tinst_level GTY(()) e.g "int f(void)". */ extern cp_parameter_declarator *no_parameters; +/* True if we saw "#pragma GCC java_exceptions". */ +extern bool pragma_java_exceptions; + /* in call.c */ extern bool check_dtor_name (tree, tree); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index a96e606ad4f..b16ae262bea 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -4419,9 +4419,15 @@ check_array_designated_initializer (const constructor_elt *ce) { /* The parser only allows identifiers as designated initializers. */ - gcc_assert (TREE_CODE (ce->index) == IDENTIFIER_NODE); - error ("name %qD used in a GNU-style designated " - "initializer for an array", ce->index); + if (ce->index == error_mark_node) + error ("name used in a GNU-style designated " + "initializer for an array"); + else + { + gcc_assert (TREE_CODE (ce->index) == IDENTIFIER_NODE); + error ("name %qD used in a GNU-style designated " + "initializer for an array", ce->index); + } return false; } @@ -9340,6 +9346,14 @@ grokdeclarator (const cp_declarator *declarator, error ("virtual non-class function %qs", name); virtualp = 0; } + else if (sfk == sfk_constructor + || sfk == sfk_destructor) + { + error (funcdef_flag + ? "%qs defined in a non-class scope" + : "%qs declared in a non-class scope", name); + sfk = sfk_none; + } } else if (TREE_CODE (type) == FUNCTION_TYPE && staticp < 2 && !NEW_DELETE_OPNAME_P (original_name)) diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index deba8b4e01c..2be621da7c5 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -3772,7 +3772,7 @@ possibly_inlined_p (tree decl) gcc_assert (TREE_CODE (decl) == FUNCTION_DECL); if (DECL_UNINLINABLE (decl)) return false; - if (!optimize) + if (!optimize || pragma_java_exceptions) return DECL_DECLARED_INLINE_P (decl); /* When optimizing, we might inline everything when flatten attribute or heuristics inlining for size or autoinlining diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index d708b09658b..66377ff1564 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -81,6 +81,8 @@ struct impl_files static struct impl_files *impl_file_chain; +/* True if we saw "#pragma GCC java_exceptions". */ +bool pragma_java_exceptions; void cxx_finish (void) @@ -430,6 +432,7 @@ handle_pragma_java_exceptions (cpp_reader* dfile ATTRIBUTE_UNUSED) warning (0, "junk at end of #pragma GCC java_exceptions"); choose_personality_routine (lang_java); + pragma_java_exceptions = true; } /* Issue an error message indicating that the lookup of NAME (an diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 02a96ccc4a4..63ac0709ebf 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -11588,7 +11588,11 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, type = make_typename_type (parser->scope, decl, typename_type, /*complain=*/tf_error); - else + /* If the `typename' keyword is in effect and DECL is not a type + decl. Then type is non existant. */ + else if (tag_type == typename_type && TREE_CODE (decl) != TYPE_DECL) + type = NULL_TREE; + else type = TREE_TYPE (decl); } diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index a6986f94b63..3788a7e8b9e 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -4031,7 +4031,7 @@ cp_pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop) pointer_int_sum() anyway. */ complete_type (TREE_TYPE (res_type)); - return pointer_int_sum (resultcode, ptrop, + return pointer_int_sum (input_location, resultcode, ptrop, fold_if_not_in_template (intop)); } diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index efef455d6a8..1d58f06879a 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -826,6 +826,10 @@ See RS/6000 and PowerPC Options. @emph{x86-64 Options} See i386 and x86-64 Options. +@emph{i386 and x86-64 Windows Options} +@gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll +-mnop-fun-dllimport -mthread -mwin32 -mwindows} + @emph{Xstormy16 Options} @gccoptlist{-msim} @@ -8827,6 +8831,7 @@ platform. * H8/300 Options:: * HPPA Options:: * i386 and x86-64 Options:: +* i386 and x86-64 Windows Options:: * IA-64 Options:: * M32C Options:: * M32R/D Options:: @@ -9140,10 +9145,6 @@ long_calls_off} directive. Note these switches have no effect on how the compiler generates code to handle function calls via function pointers. -@item -mnop-fun-dllimport -@opindex mnop-fun-dllimport -Disable support for the @code{dllimport} attribute. - @item -msingle-pic-base @opindex msingle-pic-base Treat the register used for PIC addressing as read-only, rather than @@ -15470,6 +15471,71 @@ is defined for compatibility with Diab. These are listed under @xref{i386 and x86-64 Options}. +@node i386 and x86-64 Windows Options +@subsection i386 and x86-64 Windows Options +@cindex i386 and x86-64 Windows Options + +These additional options are available for Windows targets: + +@table @gcctabopt +@item -mconsole +@opindex mconsole +This option is available for Cygwin and MinGW targets. It +specifies that a console application is to be generated, by +instructing the linker to set the PE header subsystem type +required for console applications. +This is the default behaviour for Cygwin and MinGW targets. + +@item -mcygwin +@opindex mcygwin +This option is available for Cygwin targets. It specifies that +the Cygwin internal interface is to be used for predefined +preprocessor macros, C runtime libraries and related linker +paths and options. For Cygwin targets this is the default behaviour. +This option is deprecated and will be removed in a future release. + +@item -mno-cygwin +@opindex mno-cygwin +This option is available for Cygwin targets. It specifies that +the MinGW internal interface is to be used instead of Cygwin's, by +setting MinGW-related predefined macros and linker paths and default +library options. +This option is deprecated and will be removed in a future release. + +@item -mdll +@opindex mdll +This option is available for Cygwin and MinGW targets. It +specifies that a DLL - a dynamic link library - is to be +generated, enabling the selection of the required runtime +startup object and entry point. + +@item -mnop-fun-dllimport +@opindex mnop-fun-dllimport +This option is available for Cygwin and MinGW targets. It +specifies that the dllimport attribute should be ignored. + +@item -mthread +@opindex mthread +This option is available for MinGW targets. It specifies +that MinGW-specific thread support is to be used. + +@item -mwin32 +@opindex mwin32 +This option is available for Cygwin and MinGW targets. It +specifies that the typical Windows pre-defined macros are to +be set in the pre-processor, but does not influence the choice +of runtime library/startup code. + +@item -mwindows +@opindex mwindows +This option is available for Cygwin and MinGW targets. It +specifies that a GUI application is to be generated by +instructing the linker to set the PE header subsystem type +appropriately. +@end table + +See also under @ref{i386 and x86-64 Options} for standard options. + @node Xstormy16 Options @subsection Xstormy16 Options @cindex Xstormy16 Options diff --git a/gcc/ginclude/stdarg.h b/gcc/ginclude/stdarg.h index c9ddd6b7fc1..5061f34e119 100644 --- a/gcc/ginclude/stdarg.h +++ b/gcc/ginclude/stdarg.h @@ -50,7 +50,7 @@ typedef __builtin_va_list __gnuc_va_list; #define va_start(v,l) __builtin_va_start(v,l) #define va_end(v) __builtin_va_end(v) #define va_arg(v,l) __builtin_va_arg(v,l) -#if !defined(__STRICT_ANSI__) || __STDC_VERSION__ + 0 >= 199900L +#if !defined(__STRICT_ANSI__) || __STDC_VERSION__ + 0 >= 199900L || defined(__GXX_EXPERIMENTAL_CXX0X__) #define va_copy(d,s) __builtin_va_copy(d,s) #endif #define __va_copy(d,s) __builtin_va_copy(d,s) diff --git a/gcc/opts.c b/gcc/opts.c index 631977097ec..2d5184fcb0e 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -745,13 +745,21 @@ flag_instrument_functions_exclude_p (tree fndecl) void warn_if_disallowed_function_p (const_tree exp) { - if (TREE_CODE(exp) == CALL_EXPR + if (TREE_CODE (exp) == CALL_EXPR && VEC_length (char_p, warning_disallowed_functions) > 0) { int i; char *s; - const char *fnname = - IDENTIFIER_POINTER (DECL_NAME (get_callee_fndecl (exp))); + tree fndecl = get_callee_fndecl (exp); + const char *fnname; + + if (fndecl == NULL) + return; + + fnname = get_name (fndecl); + if (fnname == NULL) + return; + for (i = 0; VEC_iterate (char_p, warning_disallowed_functions, i, s); ++i) { diff --git a/gcc/reload1.c b/gcc/reload1.c index 9a485f08300..fcf0bd3fc4d 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -4367,29 +4367,39 @@ reload_as_needed (int live_known) SET_REGNO_REG_SET (®_has_output_reload, REGNO (XEXP (in_reg, 0))); } - else if ((code == PRE_INC || code == PRE_DEC - || code == POST_INC || code == POST_DEC)) + else if (code == PRE_INC || code == PRE_DEC + || code == POST_INC || code == POST_DEC) { - int in_hard_regno; int in_regno = REGNO (XEXP (in_reg, 0)); if (reg_last_reload_reg[in_regno] != NULL_RTX) { + int in_hard_regno; + bool forget_p = true; + in_hard_regno = REGNO (reg_last_reload_reg[in_regno]); - gcc_assert (TEST_HARD_REG_BIT (reg_reloaded_valid, - in_hard_regno)); - for (x = old_prev ? NEXT_INSN (old_prev) : insn; - x != old_next; - x = NEXT_INSN (x)) - if (x == reg_reloaded_insn[in_hard_regno]) - break; + if (TEST_HARD_REG_BIT (reg_reloaded_valid, + in_hard_regno)) + { + for (x = old_prev ? NEXT_INSN (old_prev) : insn; + x != old_next; + x = NEXT_INSN (x)) + if (x == reg_reloaded_insn[in_hard_regno]) + { + forget_p = false; + break; + } + } /* If for some reasons, we didn't set up reg_last_reload_reg in this insn, invalidate inheritance from previous insns for the incremented/decremented register. Such registers will be not in - reg_has_output_reload. */ - if (x == old_next) + reg_has_output_reload. Invalidate it + also if the corresponding element in + reg_reloaded_insn is also + invalidated. */ + if (forget_p) forget_old_reloads_1 (XEXP (in_reg, 0), NULL_RTX, NULL); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index afe6b7eb81d..38567f69fbf 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,6 +1,54 @@ +2009-03-27 Xinliang David Li <davidxl@google.com> + + PR tree-optimization/39557 + * g++.dg/tree-ssa/dom-invalid.C: New test. + +2009-03-27 Xinliang David Li <davidxl@google.com> + + PR tree-optimization/39548 + * g++.dg/tree-ssa/copyprop.C: New test. + +2009-03-27 Andrew Pinski <andrew_pinski@playstation.sony.com> + + PR c++/38638 + * g++.dg/template/typename17.C: New testcase. + * g++.dg/template/typename18.C: New testcase. + +2009-03-27 Andrew Pinski <andrew_pinski@playstation.sony.com> + + PR c++/36799 + * g++.dg/other/var_copy-1.C: New test. + +2009-03-27 Simon Martin <simartin@users.sourceforge.net> + + PR c++/37647 + * g++.dg/parse/ctor9.C: New test. + +2009-03-27 Simon Martin <simartin@users.sourceforge.net> + + PR c++/29727 + * g++.dg/init/error2.C: New test. + +2009-03-27 Manuel Lopez-Ibanez <manu@gcc.gnu.org> + + PR c++/35652 + * gcc.dg/pr35652.C: New. + * g++.dg/warn/pr35652.C: New. + * gcc.dg/format/plus-1.c: Adjust message. + +2009-03-26 Jakub Jelinek <jakub@redhat.com> + + PR c++/39554 + * gcc.dg/wdisallowed-functions-3.c: New test. + * g++.dg/warn/Wdisallowed-functions-3.C: New test. + +2009-03-26 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> + + * gcc.dg/inline-33.c: Fix when pic. + 2009-03-25 Alexander Monakov <amonakov@ispras.ru> - * gcc.target/ia64/20090324-1.c: New test. + * gcc.target/ia64/20090324-1.c: New test. 2009-03-25 Jakub Jelinek <jakub@redhat.com> diff --git a/gcc/testsuite/g++.dg/init/error2.C b/gcc/testsuite/g++.dg/init/error2.C new file mode 100644 index 00000000000..8cf59b368b6 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/error2.C @@ -0,0 +1,15 @@ +/* PR c++/29727 */ +/* { dg-do "compile" } */ + +template<int> struct A +{ + static int a[1]; +}; +template<int N> int A<N>::a[1] = { X:0 }; /* { dg-error "does not allow designated|was not declared|designated initializer for an array" } */ + +void foo() +{ + A<0>::a; +} + + diff --git a/gcc/testsuite/g++.dg/other/var_copy-1.C b/gcc/testsuite/g++.dg/other/var_copy-1.C new file mode 100644 index 00000000000..2fc6b780e18 --- /dev/null +++ b/gcc/testsuite/g++.dg/other/var_copy-1.C @@ -0,0 +1,14 @@ +// { dg-options "-std=c++0x" } +// { dg-do compile } + +// Test to allow for va_copy with C++0x standard. + +#include <cstdarg> + +va_list x; +va_list y; + +int main () +{ + va_copy (y, x); +} diff --git a/gcc/testsuite/g++.dg/parse/ctor9.C b/gcc/testsuite/g++.dg/parse/ctor9.C new file mode 100644 index 00000000000..b80f7289253 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/ctor9.C @@ -0,0 +1,7 @@ +/* PR c++/37647 */ +/* { dg-do "compile" } */ + +struct A +{ + A() { void A(); } /* { dg-error "return type specification for constructor invalid|non-class scope" } */ +}; diff --git a/gcc/testsuite/g++.dg/template/typename17.C b/gcc/testsuite/g++.dg/template/typename17.C new file mode 100644 index 00000000000..748b1f7ab18 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typename17.C @@ -0,0 +1,10 @@ +// { dg-do compile } + +// This should fail as A::foo<0> is not a typename at all. +struct A +{ + template<int> void foo(int i) + { + typename A::foo<0>(i1); // { dg-error "" } + } +}; diff --git a/gcc/testsuite/g++.dg/template/typename18.C b/gcc/testsuite/g++.dg/template/typename18.C new file mode 100644 index 00000000000..4134ef6f64b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typename18.C @@ -0,0 +1,14 @@ +// { dg-do compile } + +// These typename should work as they are types. +struct A +{ + typedef int a; + template <int> + struct f {}; + template<int> void foo(int i) + { + typename A::a(i1); + typename A::f<0>(i2); + } +}; diff --git a/gcc/testsuite/g++.dg/tree-ssa/copyprop.C b/gcc/testsuite/g++.dg/tree-ssa/copyprop.C new file mode 100644 index 00000000000..e785755eb07 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/copyprop.C @@ -0,0 +1,739 @@ +// PR 39548 verify ssa ICE +// +// { dg-do compile { target { lp64 } } } +// { dg-options "-Wno-error -fno-exceptions -fno-tree-vrp -O2 -fprofile-generate -finline-limit=500" } +// + +#include <map> +#include <vector> +#include <iostream> +using namespace std; +extern void free (void *); +template<typename _FIter, typename _Tp> _FIter lower_bound(_FIter, _FIter, _Tp&); +template<class _Key> struct hash { }; +template<class _Val> struct _Hashtable_node { + _Hashtable_node* _M_next; + _Val _M_val; +}; +static const unsigned long __stl_prime_list[] = { 2, 3, 5 }; +inline unsigned long prime(unsigned long __n) { + const unsigned long* __first = __stl_prime_list; + const unsigned long* __last = __stl_prime_list + 29; + const unsigned long* pos = lower_bound(__first, __last, __n); + return pos == __last ? *(__last - 1) : *pos; +} +template<class _Val, class _Key, class _HashFcn, class _ExtractKey, class _EqualKey, class _Alloc> struct hashtable { + typedef _Key key_type; + typedef _Val value_type; + typedef _HashFcn hasher; + typedef _EqualKey key_equal; + typedef size_t size_type; + typedef value_type& reference; + typedef _Hashtable_node<_Val> _Node; + typedef typename _Alloc::template rebind<value_type>::other allocator_type; + allocator_type get_allocator() const { } + typedef typename _Alloc::template rebind<_Node>::other _Node_Alloc; + typedef typename _Alloc::template rebind<_Node*>::other _Nodeptr_Alloc; + typedef vector<_Node*, _Nodeptr_Alloc> _Vector_type; + _Node_Alloc _M_node_allocator; + void _M_put_node(_Node* __p) { + _M_node_allocator.deallocate(__p, 1); + } + hasher _M_hash; + key_equal _M_equals; + _ExtractKey _M_get_key; + _Vector_type _M_buckets; + size_type _M_num_elements; + hashtable(size_type __n, const _HashFcn& __hf, const _EqualKey& __eql, const allocator_type& __a = allocator_type()) : _M_num_elements(0) { + _M_initialize_buckets(__n); + } + ~hashtable() { clear(); } + reference find_or_insert(const value_type& __obj); + size_type count(const key_type& __key) const { + const size_type __n = _M_bkt_num_key(__key); + size_type __result = 0; + for (const _Node* __cur = _M_buckets[__n]; __cur; __cur = __cur->_M_next) + if (_M_equals(_M_get_key(__cur->_M_val), __key)) ++__result; + } + size_type erase(const key_type& __key); + void clear(); + size_type _M_next_size(size_type __n) const { return prime(__n); } + void _M_initialize_buckets(size_type __n) { + const size_type __n_buckets = _M_next_size(__n); + _M_buckets.reserve(__n_buckets); + _M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*) 0); + } + size_type _M_bkt_num_key(const key_type& __key) const { + return _M_bkt_num_key(__key, _M_buckets.size()); + } + size_type _M_bkt_num_key(const key_type& __key, size_t __n) const { + return _M_hash(__key) % __n; + } + void _M_delete_node(_Node* __n) { + this->get_allocator().destroy(&__n->_M_val); + _M_put_node(__n); + } +}; +template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::size_type hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: erase(const key_type& __key) { + const size_type __n = _M_bkt_num_key(__key); + _Node* __first = _M_buckets[__n]; + if (__first) _Node* __cur = __first; +} +template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: clear() { + for (size_type __i = 0; __i < _M_buckets.size(); ++__i) { + _Node* __cur = _M_buckets[__i]; + while (__cur != 0) { _M_delete_node(__cur); } + } +} +template<class _Key, class _Tp, class _HashFn = hash<_Key>, class _EqualKey = equal_to<_Key>, class _Alloc = allocator<_Tp> > struct hash_map { + typedef hashtable<pair<const _Key, _Tp>,_Key, _HashFn, _Select1st<pair<const _Key, _Tp> >, _EqualKey, _Alloc> _Ht; + _Ht _M_ht; + typedef typename _Ht::key_type key_type; + typedef typename _Ht::value_type value_type; + typedef typename _Ht::hasher hasher; + typedef typename _Ht::key_equal key_equal; + typedef typename _Ht::size_type size_type; + typedef typename _Ht::allocator_type allocator_type; + hash_map() : _M_ht(100, hasher(), key_equal(), allocator_type()) { } + _Tp& operator[](const key_type& __key) { + return _M_ht.find_or_insert(value_type(__key, _Tp())).second; + } + size_type count(const key_type& __key) const { return _M_ht.count(__key); } + size_type erase(const key_type& __key) { + return _M_ht.erase(__key); + } +}; +extern size_t strlen (__const char *__s); +template <class C> struct scoped_ptr { + explicit scoped_ptr(C* p = __null) : ptr_(p) { delete ptr_; } + void reset(C* p = __null) { + if (p != ptr_) { delete ptr_; } + } + C& operator*() const {} + C* operator->() const {} + bool operator==(C* p) const { return ptr_ == p; } + bool operator!=(C* p) const { return ptr_ != p; } + C* ptr_; +}; +namespace std { +class strstreambuf : public basic_streambuf<char, char_traits<char> > { +}; +class strstream : public basic_iostream<char> { + public: int pcount() const; + char* str(); + strstreambuf _M_buf; +}; +}; +const int INFO = 0, WARNING = 1, ERROR = 2, FATAL = 3, NUM_SEVERITIES = 4; +struct foo_1 { + foo_1(string* str) : str_(str) { } + operator bool() const { + return (__builtin_expect(str_ != __null, 0)); + } + string* str_; +}; +template<class t1, class t2> string* Makefoo_1(const t1& v1, const t2& v2, const char* names) { + strstream ss; + ss << names << " (" << v1 << " vs. " << v2 << ")"; + return new string(ss.str(), ss.pcount()); +} +template <class t1, class t2> inline string* Check_GTImpl(const t1& v1, const t2& v2, const char* names) { + if (v1 > v2) return __null; + else return Makefoo_1(v1, v2, names); +} +struct blah_54 { + blah_54(const char* file, int line, int severity); + ~blah_54(); + ostream& stream() { }; +}; +class blah_0 : public blah_54 { + public: blah_0(const char* file, int line); + blah_0(const char* file, int line, const foo_1& result); +}; +template <class Value, class Key, class HashFcn, class ExtractKey, class EqualKey, class Alloc> class dense_hashtable; +template <class V, class K, class HF, class ExK, class EqK, class A> struct dense_hashtable_iterator { + typedef V* pointer; + dense_hashtable_iterator(const dense_hashtable<V,K,HF,ExK,EqK,A> *h, pointer it, pointer it_end, bool advance) : ht(h), pos(it), end(it_end) { + if (advance) advance_past_empty_and_deleted(); + } + pointer operator->() const { } + void advance_past_empty_and_deleted() { + while ( pos != end && (ht->test_empty(*this) || ht->test_deleted(*this)) ) ++pos; + } + const dense_hashtable<V,K,HF,ExK,EqK,A> *ht; + pointer pos, end; +}; +template <class V, class K, class HF, class ExK, class EqK, class A> struct dense_hashtable_const_iterator { + typedef dense_hashtable_iterator<V,K,HF,ExK,EqK,A> iterator; + typedef dense_hashtable_const_iterator<V,K,HF,ExK,EqK,A> const_iterator; + typedef const V& reference; + typedef const V* pointer; + dense_hashtable_const_iterator(const dense_hashtable<V,K,HF,ExK,EqK,A> *h, pointer it, pointer it_end, bool advance) : ht(h), pos(it), end(it_end) { + if (advance) advance_past_empty_and_deleted(); + } + dense_hashtable_const_iterator(const iterator &it) : pos(it.pos), end(it.end) {} + reference operator*() const { return *pos; } + pointer operator->() const {} + void advance_past_empty_and_deleted() { + while ( pos != end && (ht->test_empty(*this) || ht->test_deleted(*this))) ++pos; + } + const_iterator& operator++() { } + bool operator!=(const const_iterator& it) const { } + const dense_hashtable<V,K,HF,ExK,EqK,A> *ht; + pointer pos, end; +}; +template <class Value, class Key, class HashFcn, class ExtractKey, class EqualKey, class Alloc> class dense_hashtable { + public: typedef Key key_type; + typedef Value value_type; + typedef HashFcn hasher; + typedef EqualKey key_equal; + typedef size_t size_type; + typedef dense_hashtable_iterator<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc> iterator; + typedef dense_hashtable_const_iterator<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc> const_iterator; + static const float HT_OCCUPANCY_FLT; + static const float HT_EMPTY_FLT; + static const size_t HT_MIN_BUCKETS = 32; + iterator end() { + return iterator(this, table + num_buckets, table + num_buckets, true); + } + const_iterator end() const { + return const_iterator(this, table + num_buckets, table+num_buckets,true); + } + void set_value(value_type* dst, const value_type& src) { + new(dst) value_type(src); + } + void destroy_buckets(size_type first, size_type last) { + for (; first != last; ++first) table[first].~value_type(); + } + private: void squash_deleted() { + if ( num_deleted ) { + dense_hashtable tmp(*this); + swap(tmp); + } + } + public: void set_deleted_key(const value_type &val) { squash_deleted(); } + bool test_deleted(size_type bucknum) const { + return (use_deleted && num_deleted > 0 && equals(get_key(delval), get_key(table[bucknum]))); + } + bool test_deleted(const const_iterator &it) const { + return (use_deleted && num_deleted > 0 && equals(get_key(delval), get_key(*it))); + } + bool set_deleted(const_iterator &it) { + set_value(const_cast<value_type*>(&(*it)), delval); + } + bool test_empty(size_type bucknum) const { + return equals(get_key(emptyval), get_key(table[bucknum])); + } + bool test_empty(const const_iterator &it) const { + return equals(get_key(emptyval), get_key(*it)); + } + void fill_range_with_empty(value_type* table_start, value_type* table_end) { + uninitialized_fill(table_start, table_end, emptyval); + } + void set_empty(size_type buckstart, size_type buckend) { + destroy_buckets(buckstart, buckend); + fill_range_with_empty(table + buckstart, table + buckend); + } + size_type size() const { + return num_elements - num_deleted; + } + size_type bucket_count() const { } + static const size_type ILLEGAL_BUCKET = size_type(-1); + size_type min_size(size_type num_elts, size_type min_buckets_wanted) { + size_type sz = HT_MIN_BUCKETS; + while ( sz < min_buckets_wanted || num_elts >= sz * enlarge_resize_percent ) sz *= 2; + } + void maybe_shrink() { + if (shrink_threshold > 0 && (num_elements-num_deleted) < shrink_threshold && bucket_count() > HT_MIN_BUCKETS ) { + size_type sz = bucket_count() / 2; + sz /= 2; + dense_hashtable tmp(*this, sz); + swap(tmp); + } + } + void resize_delta(size_type delta, size_type min_buckets_wanted = 0) { + if ( consider_shrink ) maybe_shrink(); + const size_type needed_size = min_size(num_elements + delta, min_buckets_wanted); + if ( needed_size > bucket_count() ) { + const size_type resize_to = min_size(num_elements - num_deleted + delta, min_buckets_wanted); + dense_hashtable tmp(*this, resize_to); + swap(tmp); + } + } + void copy_from(const dense_hashtable &ht, size_type min_buckets_wanted = 0) { + clear(); + const size_type resize_to = min_size(ht.size(), min_buckets_wanted); + num_elements++; + } + explicit dense_hashtable(size_type n = 0, const HashFcn& hf = HashFcn(), const EqualKey& eql = EqualKey(),const ExtractKey& ext = ExtractKey()) : num_deleted(0), use_deleted(false), use_empty(false), delval(), emptyval(), enlarge_resize_percent(HT_OCCUPANCY_FLT), shrink_resize_percent(HT_EMPTY_FLT), table(__null), num_buckets(min_size(0, n)), num_elements(0) { + reset_thresholds(); + } + dense_hashtable(const dense_hashtable& ht, size_type min_buckets_wanted = 0) : num_deleted(0), use_deleted(ht.use_deleted), use_empty(ht.use_empty), delval(ht.delval), emptyval(ht.emptyval), enlarge_resize_percent(ht.enlarge_resize_percent), shrink_resize_percent(ht.shrink_resize_percent), table(__null), num_buckets(0), num_elements(0) { + reset_thresholds(); + copy_from(ht, min_buckets_wanted); + set_value(&emptyval, ht.emptyval); + enlarge_resize_percent = ht.enlarge_resize_percent; + copy_from(ht); + } + ~dense_hashtable() { + if (table) { + destroy_buckets(0, num_buckets); + free(table); + } + } + void swap(dense_hashtable& ht) { + std::swap(equals, ht.equals); + { + value_type tmp; + set_value(&delval, ht.delval); + set_value(&ht.delval, tmp); + set_value(&ht.emptyval, tmp); + } + std::swap(table, ht.table); + std::swap(num_buckets, ht.num_buckets); + reset_thresholds(); + ht.reset_thresholds(); + } + void clear() { + if (table) destroy_buckets(0, num_buckets); + num_buckets = min_size(0,0); + set_empty(0, num_buckets); + } + pair<size_type, size_type> find_position(const key_type &key) const { + const size_type bucket_count_minus_one = bucket_count() - 1; + size_type bucknum = hash(key) & bucket_count_minus_one; + size_type insert_pos = ILLEGAL_BUCKET; + while ( 1 ) { + if ( test_empty(bucknum) ) { + if ( insert_pos == ILLEGAL_BUCKET ) return pair<size_type,size_type>(ILLEGAL_BUCKET, insert_pos); + } + else if ( test_deleted(bucknum) ) { + if ( insert_pos == ILLEGAL_BUCKET ) insert_pos = bucknum; + } + else if ( equals(key, get_key(table[bucknum])) ) { + return pair<size_type,size_type>(bucknum, ILLEGAL_BUCKET); + } + } + } + iterator find(const key_type& key) { + if ( size() == 0 ) return end(); + pair<size_type, size_type> pos = find_position(key); + if ( pos.first == ILLEGAL_BUCKET ) return end(); + return iterator(this, table + pos.first, table + num_buckets, false); + } + const_iterator find(const key_type& key) const { + if ( size() == 0 ) return end(); + pair<size_type, size_type> pos = find_position(key); + if ( pos.first == ILLEGAL_BUCKET ) return end(); + return const_iterator(this, table + pos.first, table+num_buckets, false); + } + size_type count(const key_type &key) const { + pair<size_type, size_type> pos = find_position(key); } + pair<iterator, bool> insert_noresize(const value_type& obj) { + const pair<size_type,size_type> pos = find_position(get_key(obj)); + if ( pos.first != ILLEGAL_BUCKET) { + return pair<iterator,bool>(iterator(this, table + pos.first, table + num_buckets, false), false); + } + else { + if ( test_deleted(pos.second) ) { ++num_elements; } + return pair<iterator,bool>(iterator(this, table + pos.second, table + num_buckets, false), true); + } + } + pair<iterator, bool> insert(const value_type& obj) { + resize_delta(1); + return insert_noresize(obj); + } + size_type erase(const key_type& key) { + const_iterator pos = find(key); + if ( pos != end() ) { + set_deleted(pos); + } + } + hasher hash; + key_equal equals; + ExtractKey get_key; + size_type num_deleted; + bool use_deleted; + bool use_empty; + value_type delval; + value_type emptyval; + float enlarge_resize_percent; + float shrink_resize_percent; + size_type shrink_threshold; + size_type enlarge_threshold; + value_type *table; + size_type num_buckets; + size_type num_elements; + bool consider_shrink; + void reset_thresholds() { + enlarge_threshold = static_cast<size_type>(num_buckets * shrink_resize_percent); + } +}; +template<> struct hash<long> { + size_t operator()(long x) const { + } +}; +template<> struct hash<unsigned long> { + size_t operator()(unsigned long x) const { + } +}; +template <class Key, class T, class HashFcn = hash<Key>, class EqualKey = equal_to<Key>, class Alloc = allocator<T> > class dense_hash_map { + struct SelectKey { + const Key& operator()(const pair<const Key, T>& p) const { + return p.first; + } + }; + typedef dense_hashtable<pair<const Key, T>, Key, HashFcn, SelectKey, EqualKey, Alloc> ht; + ht rep; + public: typedef typename ht::key_type key_type; + typedef T data_type; + typedef typename ht::value_type value_type; + typedef typename ht::size_type size_type; + typedef typename ht::iterator iterator; + typedef typename ht::const_iterator const_iterator; + iterator end() { + return rep.end(); + } + iterator find(const key_type& key) { return rep.find(key); } + data_type& operator[](const key_type& key) { + iterator it = find(key); + return insert(value_type(key, data_type())).first->second; + } + pair<iterator, bool> insert(const value_type& obj) { + return rep.insert(obj); + } + void set_deleted_key(const key_type& key) { + rep.set_deleted_key(value_type(key, data_type())); + } + size_type erase(const key_type& key) { return rep.erase(key); } +}; +template <class Value, class HashFcn = hash<Value>, class EqualKey = equal_to<Value>, class Alloc = allocator<Value> > class dense_hash_set { + struct Identity { + const Value& operator()(const Value& v) const { return v; } + }; + typedef dense_hashtable<Value, Value, HashFcn, Identity, EqualKey, Alloc> ht; + ht rep; + public: typedef typename ht::key_type key_type; + typedef typename ht::value_type value_type; + typedef typename ht::size_type size_type; + typedef typename ht::const_iterator iterator; + size_type count(const key_type& key) const { + return rep.count(key); + } + pair<iterator, bool> insert(const value_type& obj) { + pair<typename ht::iterator, bool> p = rep.insert(obj); + } + size_type erase(const key_type& key) { + return rep.erase(key); + } +}; +class linked_ptr_internal { + public: bool depart() { if (next_ == this) return true; } + mutable linked_ptr_internal const* next_; +}; +template <typename T> class linked_ptr { + public: explicit linked_ptr(T* ptr = __null) { + } + ~linked_ptr() { depart(); } + T& operator*() const { } + T* value_; + linked_ptr_internal link_; + void depart() { + if (link_.depart()) delete value_; + } +}; +class blah_3 { + const char* ptr_; + int length_; + public: blah_3(const char* str) : ptr_(str), length_((str == __null) ? 0 : static_cast<int>(strlen(str))) { } +}; +class blah_5; +class Bitmap { + public: Bitmap(unsigned int size) : array_size_(RequiredArraySize(size)) { } + static unsigned int RequiredArraySize(unsigned int num_bits) { return (num_bits + 31) >> 5; } + unsigned int array_size_; +}; +enum blah_31 { CREATIVE_FORMAT_TEXT_NARROW, kNumblah_31s }; +enum blah_33 { BLACKLISTED }; +template <typename EnumT> class blah_55; +typedef blah_55<blah_31> blah_31Set; +enum blah_36 { APPROVAL_STATUS_APPROVED, APPROVAL_STATUS_UNKNOWN }; +enum blah_37 { hahah_INVALID, hahah_KEYWORD }; +template<typename EnumT> class blah_55 { + public: blah_55(int enum_size); + bool Insert(EnumT x); + const int enum_size_; + Bitmap elements_; +}; +template<typename EnumT> blah_55<EnumT>::blah_55(int enum_size) :enum_size_(enum_size), elements_(enum_size) { + while (foo_1 _result = Check_GTImpl(1, 0, "enum_size" " " ">" " " "0")) blah_0(".h", 1902, _result).stream(); +}; +enum blah_38 { + ttttttt_9, }; +class blah_46 { + public: blah_46() : hahaha_id_(0), type_(hahah_INVALID), approval_status_(APPROVAL_STATUS_APPROVED) { + } + blah_46(long cid) : hahaha_id_(cid), type_(hahah_INVALID), approval_status_(APPROVAL_STATUS_APPROVED) { + } + long id() const { + return (static_cast<long>(hahaha_id_) << 16) >> 16; + } + static const blah_46 kBlacklistedID; + bool operator == (const blah_46& x) const { return id() == x.id(); } + bool operator < (const blah_46& x) const { return id() < x.id(); } + long hahaha_id_ : 48; + blah_37 type_ : 8; + blah_36 approval_status_ : 4; +}; +template <> struct hash<blah_46> { + size_t operator()(const blah_46 &x) const { + return size_t(x.id()); + } +}; +class blah_57 { + public: blah_57(); + void AddReason(blah_33 reason, const blah_3& debug_str, const blah_46& hahaha_id, bool ); + void set_collects_multiple_reasons(bool t) { } + private: struct foo_3 { + string reject_desc; + }; + foo_3 first_reason_; +}; +template <class T> struct foo_5 : public unary_function<T*, long> { + long operator()(const T* p) const { + long id = reinterpret_cast<long>(p); + if (id < 2) return -id; + } +}; +template <class T> class DensePtrSet : public dense_hashtable<T*, long, hash<long>, foo_5<T>, equal_to<long>, allocator<T*> > { + public: DensePtrSet() { + this->set_deleted_key(reinterpret_cast<T*>(1)); + } + const T* Find(long key) const { + typename DensePtrSet<T>::const_iterator it = this->find(key); + return it != this->end() ? *it : __null; + } +}; +struct foo_7 { + foo_7(bool spell_correction, bool query_broadening, bool previous_query, bool near_aaaaa, bool same_length, float mult, float exp_score) : shengmo_0(spell_correction), shengmo_1(query_broadening), shengmo_2(previous_query), shengmo_3(near_aaaaa), shengmo_4(same_length), multiplier(mult), expansion_score(exp_score) { + } + int CompareSameKeywordMatch(const foo_7& compare) const; + bool shengmo_0, shengmo_1, shengmo_2, shengmo_3, shengmo_4; + float multiplier, expansion_score; +}; +enum blah_41 { + ACP_ECPM_EARLY = 2 }; +struct foo_8 { unsigned int packed_ctr1; }; +struct foo_9 { foo_9() {}}; +class blah_16; +class blah_17; +class foo_12 { public: foo_12() {} + unsigned long hahaha_id() const {} + unsigned int qbb_score() const {} + private: static const vector<blah_46> hmmmmh_4; + long hahaha_id_ : 40; +}; +class foo_13 { + public: typedef dense_hash_map<long, int> BestMap; + foo_13() { best_rrrrrrr_.set_deleted_key(-1); } + void erase(long ad_group_id) { + best_rrrrrrr_.erase(ad_group_id); + } + typedef BestMap::iterator iterator; + typedef BestMap::const_iterator const_iterator; + const_iterator begin() const { } + iterator end() { return best_rrrrrrr_.end(); } + iterator find(long ad_group_id) { return best_rrrrrrr_.find(ad_group_id); } + const foo_12& GetMatch(const_iterator it) const {} + void hmmmmh_27(long ad_group_id, const foo_12& addme); + private: BestMap best_rrrrrrr_; + vector<foo_12> rrrrrrr_buffer_; +}; +struct foo_10 : public dense_hash_set<blah_46> {}; +class foo_9Set : public DensePtrSet<foo_9> {}; +typedef map<blah_46, foo_7*> foo_6Data; +typedef hash_map<long, linked_ptr<blah_57> > RejectedAdGroupMap; +enum blah_43 {}; +class foo_14 { + public: foo_14(const unsigned int, const blah_16*, const int*); + bool GathersMultipleRejectionReasons() const; + void hmmmmh_30(blah_46 hahaha_id, blah_38 type); + const foo_7* Insertfoo_6(const blah_46 hahaha_id, bool shengmo_0, bool shengmo_1, bool shengmo_2, bool shengmo_3, bool shengmo_4_rewrite, float multiplier, float context_score); + void hmmmmh_7(blah_46 hahaha_id, blah_38 type); + foo_9* Insertfoo_9(); + bool hmmmmh_8(long ad_group_id, const foo_12 &entry); + void hmmmmh_9(long ad_group_id); + foo_13::iterator hmmmmh_0(long ad_group_id); + bool hmmmmh_8(long ad_group_id, foo_13::iterator best, const foo_12& entry); + void hmmmmh_5(const blah_46 hahaha_id); + void hmmmmh_29(const blah_46 hahaha_id); + bool hmmmmh_12(const blah_46 hahaha_id) const; + bool hmmmmh_13(const blah_46 hahaha_id) const; + const foo_9* Getfoo_9(const blah_46 hahaha_id) const; + bool Gathersfoo_9() const {} + const foo_10* rrrrrrr_type_data() const {} + const foo_10* negative_rrrrrrr_type_data() const {} + const foo_10* positive_rrrrrrr_type_data() const {} + const foo_9Set* kw_info_set() const { } + const foo_6Data* rewrite_data() const {} + const vector<blah_17>& query_rectangles() const {} + void hmmmmh_14(); + void AddQueryRectangle(const blah_17& query_rectangle); + void hmmmmh_15(long ad_group_id, const blah_46 hahaha_id, blah_33 reject_class, const char* reject_desc = __null); + void hmmmmh_16(const vector<long>& rejected_sssr_ids); + void Copy(const foo_14& cmi); + void hmmmmh_10(); + private: const blah_16* ad_request_; + const int* cr_query_; + blah_43 gather_flags_; + vector<blah_17> query_rectangles_; + foo_10 rrrrrrr_type_data_; + foo_9Set kw_info_set_; + foo_6Data rewrite_data_; + scoped_ptr<RejectedAdGroupMap> rejected_sssr_map_; + foo_13 ad_group_rrrrrrr_data_; + vector<blah_46> geo_hahaha_; + bool geo_hahaha_is_sorted_; + foo_10 negative_rrrrrrr_type_data_, positive_rrrrrrr_type_data_; + scoped_ptr<foo_10> extra_hahaha_set_; + int dimension_id_; + blah_31Set creative_formats_; + scoped_ptr<dense_hash_set<unsigned long> > near_aaaaa_rrrrrrr_fps_; + blah_41 comparison_policy_; + blah_46 next_virtual_hahaha_id_; + vector<void*>* sub_queries_; + bool allow_only_whitelisted_customers_, automatic_hahaha_rrrrrrr_; + scoped_ptr<blah_5> kw_arena_, expanded_rrrrrrr_arena_; +}; +class blah_19 { + void hmmmmh_3(); + enum blah_45 {}; +}; +void blah_19::hmmmmh_3() {} +class blah_16 { + public: int near_aaaaa_rrrrrrr_fps_size() const {} + unsigned long near_aaaaa_rrrrrrr_fps(int i) const {} +}; +class blah_21 { + protected: blah_21(char* first_block, const size_t block_size, bool align_to_page); + void* GetMemoryFallback(const size_t size, const int align); + void* GetMemory(const size_t size, const int align) { + if ( size > 0 && size < remaining_ && align == 1 ) { + last_alloc_ = freestart_; + } + return GetMemoryFallback(size, align); + } + char* freestart_; + char* last_alloc_; + size_t remaining_; +}; +class blah_5 : blah_21 { + public: char* Alloc(const size_t size) { + return reinterpret_cast<char*>(GetMemory(size, 1)); + } +}; +class blah_25 { + public: virtual ~blah_25(); +}; +class blah_17 : blah_25 { }; +void Fillfoo_8(const foo_12& x2, struct foo_8* out) { + out->packed_ctr1 = x2.qbb_score(); +} +const vector<blah_46> foo_12::hmmmmh_4; +foo_14::foo_14(const unsigned int gather_flags, const blah_16* ad_request, const int* cr_query): ad_request_(ad_request), cr_query_(cr_query), gather_flags_(static_cast<blah_43>(gather_flags)), geo_hahaha_is_sorted_(false), dimension_id_(0), creative_formats_(kNumblah_31s), comparison_policy_(ACP_ECPM_EARLY), sub_queries_(new vector<void*>()), allow_only_whitelisted_customers_(false), automatic_hahaha_rrrrrrr_(false) { + hmmmmh_10(); +} +void foo_14::hmmmmh_5(const blah_46 hahaha_id) { + negative_rrrrrrr_type_data_.insert(hahaha_id); +} +void foo_14::hmmmmh_7(blah_46 hahaha_id, blah_38 type) { } +foo_13::iterator foo_14::hmmmmh_0( long ad_group_id) { + return ad_group_rrrrrrr_data_.find(ad_group_id); +} +bool foo_14::hmmmmh_8(long ad_group_id, foo_13::iterator best, const foo_12& entry) { + rejected_sssr_map_->erase(ad_group_id); + ad_group_rrrrrrr_data_.hmmmmh_27(ad_group_id, entry); +} +bool foo_14::hmmmmh_8(long ad_group_id, const foo_12& entry) { + foo_13::iterator best = hmmmmh_0(ad_group_id); +} +void foo_14::hmmmmh_9(long ad_group_id) { + ad_group_rrrrrrr_data_.erase(ad_group_id); +} +void foo_14::hmmmmh_10() { + if (near_aaaaa_rrrrrrr_fps_ != __null) { + blah_54(".cc", 226, WARNING).stream() << ""; + for (int j = 0; + j < ad_request_->near_aaaaa_rrrrrrr_fps_size(); j++) { + near_aaaaa_rrrrrrr_fps_->insert(ad_request_->near_aaaaa_rrrrrrr_fps(j)); + } + } +} +const foo_7* foo_14::Insertfoo_6(const blah_46 hahaha_id, bool shengmo_0, bool shengmo_1, bool shengmo_2, bool shengmo_3, bool shengmo_4_rewrite, float multiplier, float context_score) { + if (rrrrrrr_type_data_.count(hahaha_id) > 0) return __null; + foo_7* new_info = new(expanded_rrrrrrr_arena_->Alloc(sizeof(foo_7))) foo_7(shengmo_0,shengmo_1, shengmo_2, shengmo_3, shengmo_4_rewrite, multiplier, context_score); + pair<foo_6Data::iterator, bool> status = rewrite_data_.insert( make_pair(hahaha_id, new_info)); + foo_7* inserted = status.first->second; + if (!status.second) { + if (inserted->CompareSameKeywordMatch(*new_info) < 0) *inserted = *new_info; + } +} +foo_9* foo_14::Insertfoo_9() { + foo_9* info = new(kw_arena_->Alloc(sizeof(foo_9))) foo_9; + if (Gathersfoo_9()) kw_info_set_.insert(info); + creative_formats_.Insert(CREATIVE_FORMAT_TEXT_NARROW); +} +bool foo_14::hmmmmh_12(const blah_46 hahaha_id) const { + if (rrrrrrr_type_data_.count(hahaha_id)) return true; +} +bool foo_14::hmmmmh_13(const blah_46 hahaha_id) const { + if (positive_rrrrrrr_type_data_.count(hahaha_id)) return true; +} +const foo_9* foo_14::Getfoo_9(const blah_46 hahaha_id) const { + if (Gathersfoo_9()) return kw_info_set_.Find(hahaha_id.id()); + static int occurrences_383 = 0, occurrences_mod_n_383 = 0; + if (++occurrences_mod_n_383 > 1000) occurrences_mod_n_383 -= 1000; +} +void foo_14::hmmmmh_15(long ad_group_id, const blah_46 hahaha_id, blah_33 reject_class, const char* reject_desc) { + if (rejected_sssr_map_ == __null) { + blah_54("a.cc", 413, ERROR).stream() << "re NULL"; + rejected_sssr_map_.reset(new RejectedAdGroupMap); + } + if (rejected_sssr_map_->count(ad_group_id) == 0) { + blah_57* ad_rejection = new blah_57(); + ad_rejection->set_collects_multiple_reasons( GathersMultipleRejectionReasons()); + (*rejected_sssr_map_)[ad_group_id] = linked_ptr<blah_57>(ad_rejection); + } + blah_57& ad_rejection = *(*rejected_sssr_map_)[ad_group_id]; + ad_rejection.AddReason(reject_class, reject_desc, hahaha_id, false); +} +void foo_14::hmmmmh_16(const vector<long>& rejected_sssr_ids) { + for (vector<long>::const_iterator it = rejected_sssr_ids.begin(); + it != rejected_sssr_ids.end(); ++it) { + ad_group_rrrrrrr_data_.erase(*it); + for (foo_13::const_iterator it = ad_group_rrrrrrr_data_.begin(); + it != ad_group_rrrrrrr_data_.end(); ++it) { + hmmmmh_15(it->first, ad_group_rrrrrrr_data_.GetMatch(it).hahaha_id(), BLACKLISTED); + } + } + hmmmmh_30(blah_46::kBlacklistedID, ttttttt_9); +} +void foo_14::Copy(const foo_14& cmi) { + rrrrrrr_type_data_ = *cmi.rrrrrrr_type_data(); + negative_rrrrrrr_type_data_ = *cmi.negative_rrrrrrr_type_data(); + positive_rrrrrrr_type_data_ = *cmi.positive_rrrrrrr_type_data(); + if (cmi.Gathersfoo_9()) { + kw_info_set_ = *cmi.kw_info_set(); + rewrite_data_ = *cmi.rewrite_data(); + } + hmmmmh_14(); + for (int i = 0; i < cmi.query_rectangles().size(); + ++i) AddQueryRectangle(cmi.query_rectangles()[i]); +} +void foo_13::hmmmmh_27(long ad_group_id, const foo_12& addme) { + int& best_index = best_rrrrrrr_[ad_group_id]; + rrrrrrr_buffer_.push_back(addme); +} +void foo_14::hmmmmh_29(const blah_46 hahaha_id) { + if (extra_hahaha_set_ != __null) extra_hahaha_set_->erase(hahaha_id); +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/dom-invalid.C b/gcc/testsuite/g++.dg/tree-ssa/dom-invalid.C new file mode 100644 index 00000000000..5513d3650c6 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/dom-invalid.C @@ -0,0 +1,52 @@ +// PR tree-optimization/39557 +// invalid post-dom info leads to infinite loop +// { dg-do run } +// { dg-options "-Wall -fno-exceptions -O2 -fprofile-use -fno-rtti" } + +struct C +{ + virtual const char *bar () const; +}; + +struct D +{ + D () : d1 (0) { } + C *d2[4]; + int d1; + inline const C & baz (int i) const { return *d2[i]; } +}; + +struct E +{ + unsigned char e1[2]; + D e2; + bool foo () const { return (e1[1] & 1) != 0; } + virtual const char *bar () const __attribute__ ((noinline)); +}; + +const char * +C::bar () const +{ + return 0; +} + +C c; + +const char * +E::bar () const +{ + const char *e = __null; + if (foo () && (e = c.C::bar ())) + return e; + for (int i = 0, n = e2.d1; i < n; i++) + if ((e = e2.baz (i).C::bar ())) + return e; + return e; +} + +int +main () +{ + E e; + e.bar (); +} // { dg-message "note: file" "" } diff --git a/gcc/testsuite/g++.dg/warn/Wdisallowed-functions-3.C b/gcc/testsuite/g++.dg/warn/Wdisallowed-functions-3.C new file mode 100644 index 00000000000..3ecfb0c2264 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wdisallowed-functions-3.C @@ -0,0 +1,10 @@ +// PR c++/39554 +// { dg-do compile } +// { dg-options "-Wdisallowed-function-list=bar" } + +void +foo (void (*p) (), void (*bar) ()) +{ + p (); + bar (); +} diff --git a/gcc/testsuite/g++.dg/warn/pr35652.C b/gcc/testsuite/g++.dg/warn/pr35652.C new file mode 100644 index 00000000000..7ce9431eb2b --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/pr35652.C @@ -0,0 +1,30 @@ +// PR c++/35652: wrong location and duplicated warning. +// { dg-do compile } +// { dg-options "-fshow-column" } +#include <string> +int foo() { + // blank line padding, could also be code... + // + // + // + // + // + // + // + // + // + std::string s = ""; + s += 'x' + "y"; // { dg-warning "14:offset '120' outside bounds of constant string" } + // { dg-bogus "offset '120' outside bounds of constant string.*offset '120' outside bounds of constant string" "duplicated" { target *-*-* } 17 } +} + +int bar() +{ + const char *s = 'z' + "y"; /* { dg-warning "25:offset '122' outside bounds of constant string" } */ +} + +int g() +{ + char str[2]; + const char *p = str + sizeof(str); +} diff --git a/gcc/testsuite/gcc.dg/format/plus-1.c b/gcc/testsuite/gcc.dg/format/plus-1.c index 02a213d417d..0d8b62cd3c5 100644 --- a/gcc/testsuite/gcc.dg/format/plus-1.c +++ b/gcc/testsuite/gcc.dg/format/plus-1.c @@ -15,6 +15,9 @@ foo (int i) printf (3 + "%d\n"); /* { dg-warning "zero-length" "zero-length string" } */ printf ("%d\n" + i, i); /* { dg-warning "not a string" "non-constant addend" } */ printf ("%d\n" + 10); /* { dg-warning "not a string" "too large addend" } */ + /* { dg-warning "offset '10' outside bounds of constant string" "offset" { target *-*-* } 17 } */ printf ("%d\n" - 1, i); /* { dg-warning "not a string" "minus constant" } */ + /* { dg-warning "offset '-1' outside bounds of constant string" "offset" { target *-*-* } 19 } */ printf ("%d\n" + -1, i); /* { dg-warning "not a string" "negative addend" } */ + /* { dg-warning "offset '-1' outside bounds of constant string" "offset" { target *-*-* } 21 } */ } diff --git a/gcc/testsuite/gcc.dg/inline-33.c b/gcc/testsuite/gcc.dg/inline-33.c index c830c7df634..ac577e3cb88 100644 --- a/gcc/testsuite/gcc.dg/inline-33.c +++ b/gcc/testsuite/gcc.dg/inline-33.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-O3 -fdump-tree-optimized" } */ +/* { dg-options "-O3 -fdump-tree-optimized -fpie" { target { ! nonpic } } } */ int i; diff --git a/gcc/testsuite/gcc.dg/pr35652.c b/gcc/testsuite/gcc.dg/pr35652.c new file mode 100644 index 00000000000..50ec3acf10a --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr35652.c @@ -0,0 +1,13 @@ +/* PR c++/35652: wrong location and duplicated warning. + { dg-do compile } + { dg-options "" } */ +int bar() +{ + const char *s = 'z' + "y"; /* { dg-warning "offset '122' outside bounds of constant string" } */ +} + +int g() +{ + char str[2]; + const char *p = str + sizeof(str); +} diff --git a/gcc/testsuite/gcc.dg/wdisallowed-functions-3.c b/gcc/testsuite/gcc.dg/wdisallowed-functions-3.c new file mode 100644 index 00000000000..5b8b31bdfc9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/wdisallowed-functions-3.c @@ -0,0 +1,10 @@ +/* PR c++/39554 */ +/* { dg-do compile } */ +/* { dg-options "-Wdisallowed-function-list=bar" } */ + +void +foo (void (*p) (void), void (*bar) (void)) +{ + p (); + bar (); +} diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c index 654ba950228..64c697a5196 100644 --- a/gcc/tree-ssa-copy.c +++ b/gcc/tree-ssa-copy.c @@ -908,7 +908,8 @@ copy_prop_visit_phi_node (gimple phi) } } - if (phi_val.value && set_copy_of_val (lhs, phi_val.value)) + if (phi_val.value && may_propagate_copy (lhs, phi_val.value) + && set_copy_of_val (lhs, phi_val.value)) retval = (phi_val.value != lhs) ? SSA_PROP_INTERESTING : SSA_PROP_VARYING; else retval = SSA_PROP_NOT_INTERESTING; diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index b26884b1b27..8be2961f895 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -1589,6 +1589,11 @@ warn_uninitialized_vars (bool warn_possibly_uninitialized) walk_gimple_op (gsi_stmt (gsi), warn_uninitialized_var, &wi); } } + + /* Post-dominator information can not be reliably updated. Free it + after the use. */ + + free_dominance_info (CDI_POST_DOMINATORS); return 0; } diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index eebffbded2b..23d43c1349e 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,7 +1,41 @@ +2009-03-25 Edward Smith-Rowland <3dw4rd@verizon.net> + + * include/std/fstream (basic_filebuf<>::open(const std::string&, + ios_base::openmode), basic_ifstream<>::basic_ifstream(const + std::string&, ios_base::openmode), basic_ifstream<>:: + open(const std::string&, ios_base::openmode), basic_ofstream<>:: + basic_ofstream(const std::string&, ios_base::openmode), + basic_ofstream<>::open(const std::string&, ios_base::openmode), + basic_fstream<>::basic_fstream(const std::string&, ios_base::openmode), + basic_fstream<>::open(const std::string&, ios_base::openmode)): + Add in C++0x mode. + * testsuite/27_io/basic_ofstream/open/char/2.cc: New. + * testsuite/27_io/basic_ofstream/cons/char/2.cc: Likewise. + * testsuite/27_io/basic_fstream/open/char/1.cc: Likewise. + * testsuite/27_io/basic_fstream/cons/char/1.cc: Likewise. + * testsuite/27_io/basic_ifstream/open/char/2.cc: Likewise. + * testsuite/27_io/basic_ifstream/cons/char/2.cc: Likewise. + * testsuite/27_io/basic_filebuf/open/char/5.cc: Likewise. + +2009-03-25 Paolo Carlini <paolo.carlini@oracle.com> + + * testsuite/27_io/basic_ofstream/cons/char/2.cc: Rename to... + * testsuite/27_io/basic_ofstream/cons/char/1.cc: ... this. + * testsuite/27_io/basic_fstream/cons/3.cc: Rename to... + * testsuite/27_io/basic_fstream/cons/1.cc: ... this. + +2009-03-25 Paolo Carlini <paolo.carlini@oracle.com> + + * include/bits/forward_list.h (_Fwd_list_node_base<>:: + _M_transfer_after, _M_reverse_after): Move out of line... + * include/bits/forward_list.tcc: ... here. + (forward_list<>::reverse): Move inline... + * include/bits/forward_list.h: ... here; minor cosmetic changes. + 2009-03-22 Mark Mitchell <mark@codesourcery.com> - * testsuite/21_strings/basic_string/inserters_extractors/wchar_t/28277.cc: - Likewise. + * testsuite/21_strings/basic_string/inserters_extractors/wchar_t/ + 28277.cc: Likewise. * testsuite/27_io/basic_ostream/inserters_character/wchar_t/28277-3.cc: Likewise. * testsuite/27_io/basic_ostream/inserters_character/wchar_t/28277-4.cc: diff --git a/libstdc++-v3/include/bits/forward_list.h b/libstdc++-v3/include/bits/forward_list.h index 55029c9647a..0a4bf3a6a95 100644 --- a/libstdc++-v3/include/bits/forward_list.h +++ b/libstdc++-v3/include/bits/forward_list.h @@ -62,52 +62,23 @@ _GLIBCXX_BEGIN_NAMESPACE(std) ::other::pointer _Pointer; typedef typename _Alloc::template rebind<_Fwd_list_node_base<_Alloc> > ::other::const_pointer _Const_pointer; - + _Pointer _M_next; - + _Fwd_list_node_base() : _M_next(0) { } - + static void swap(_Fwd_list_node_base& __x, _Fwd_list_node_base& __y) { std::swap(__x._M_next, __y._M_next); } - + void - _M_transfer_after(_Pointer __bbegin, _Pointer __bend) - { - _Pointer __keep = __bbegin->_M_next; - if (__bend) - { - __bbegin->_M_next = __bend->_M_next; - __bend->_M_next = this->_M_next; - } - else - __bbegin->_M_next = 0; - this->_M_next = __keep; - } - + _M_transfer_after(_Pointer __bbegin); + void - _M_transfer_after(_Pointer __bbegin) - { - _Pointer __bend = __bbegin; - while (__bend && __bend->_M_next) - __bend = __bend->_M_next; - _M_transfer_after(__bbegin, __bend); - } - + _M_transfer_after(_Pointer __bbegin, _Pointer __bend); + void - _M_reverse_after() - { - _Pointer __tail = this->_M_next; - if (!__tail) - return; - while (_Pointer __temp = __tail->_M_next) - { - _Pointer __keep = this->_M_next; - this->_M_next = __temp; - __tail->_M_next = __temp->_M_next; - this->_M_next->_M_next = __keep; - } - } + _M_reverse_after(); }; /** @@ -159,16 +130,16 @@ _GLIBCXX_BEGIN_NAMESPACE(std) reference operator*() const - { return __static_pointer_cast<_Node*>(this->_M_node)->_M_value; } + { return __static_pointer_cast<_Node*>(_M_node)->_M_value; } pointer operator->() const - { return &__static_pointer_cast<_Node*>(this->_M_node)->_M_value; } + { return &__static_pointer_cast<_Node*>(_M_node)->_M_value; } _Self& operator++() { - this->_M_node = this->_M_node->_M_next; + _M_node = _M_node->_M_next; return *this; } @@ -176,23 +147,23 @@ _GLIBCXX_BEGIN_NAMESPACE(std) operator++(int) { _Self __tmp(*this); - this->_M_node = this->_M_node->_M_next; + _M_node = _M_node->_M_next; return __tmp; } bool operator==(const _Self& __x) const - { return this->_M_node == __x._M_node; } + { return _M_node == __x._M_node; } bool operator!=(const _Self& __x) const - { return this->_M_node != __x._M_node; } + { return _M_node != __x._M_node; } _Self _M_next() const { if (_M_node) - return _Fwd_list_iterator(this->_M_node->_M_next); + return _Fwd_list_iterator(_M_node->_M_next); else return _Fwd_list_iterator(0); } @@ -230,16 +201,16 @@ _GLIBCXX_BEGIN_NAMESPACE(std) reference operator*() const - { return __static_pointer_cast<_Node*>(this->_M_node)->_M_value; } + { return __static_pointer_cast<_Node*>(_M_node)->_M_value; } pointer operator->() const - { return &__static_pointer_cast<_Node*>(this->_M_node)->_M_value; } + { return &__static_pointer_cast<_Node*>(_M_node)->_M_value; } _Self& operator++() { - this->_M_node = this->_M_node->_M_next; + _M_node = _M_node->_M_next; return *this; } @@ -247,23 +218,23 @@ _GLIBCXX_BEGIN_NAMESPACE(std) operator++(int) { _Self __tmp(*this); - this->_M_node = this->_M_node->_M_next; + _M_node = _M_node->_M_next; return __tmp; } bool operator==(const _Self& __x) const - { return this->_M_node == __x._M_node; } + { return _M_node == __x._M_node; } bool operator!=(const _Self& __x) const - { return this->_M_node != __x._M_node; } + { return _M_node != __x._M_node; } _Self _M_next() const { if (this->_M_node) - return _Fwd_list_const_iterator(this->_M_node->_M_next); + return _Fwd_list_const_iterator(_M_node->_M_next); else return _Fwd_list_const_iterator(0); } @@ -777,7 +748,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std) reference front() { - _Node* __front = __static_pointer_cast<_Node*>(this->_M_impl._M_head._M_next); + _Node* __front = + __static_pointer_cast<_Node*>(this->_M_impl._M_head._M_next); return __front->_M_value; } @@ -1229,7 +1201,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * Reverse the order of elements in the list in linear time. */ void - reverse(); + reverse() + { this->_M_impl._M_head._M_reverse_after(); } private: template<typename _Integer> @@ -1328,7 +1301,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) template<typename _Tp, typename _Alloc> inline void swap(forward_list<_Tp, _Alloc>& __lx, - forward_list<_Tp, _Alloc>&& __ly) + forward_list<_Tp, _Alloc>&& __ly) { __lx.swap(__ly); } _GLIBCXX_END_NAMESPACE // namespace std diff --git a/libstdc++-v3/include/bits/forward_list.tcc b/libstdc++-v3/include/bits/forward_list.tcc index bfc814df4a3..35fb9b30afc 100644 --- a/libstdc++-v3/include/bits/forward_list.tcc +++ b/libstdc++-v3/include/bits/forward_list.tcc @@ -1,6 +1,6 @@ // <forward_list.tcc> -*- C++ -*- -// Copyright (C) 2008 Free Software Foundation, Inc. +// Copyright (C) 2008, 2009 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -36,6 +36,50 @@ _GLIBCXX_BEGIN_NAMESPACE(std) + template<typename _Alloc> + void + _Fwd_list_node_base<_Alloc>:: + _M_transfer_after(_Pointer __bbegin) + { + _Pointer __bend = __bbegin; + while (__bend && __bend->_M_next) + __bend = __bend->_M_next; + _M_transfer_after(__bbegin, __bend); + } + + template<typename _Alloc> + void + _Fwd_list_node_base<_Alloc>:: + _M_transfer_after(_Pointer __bbegin, _Pointer __bend) + { + _Pointer __keep = __bbegin->_M_next; + if (__bend) + { + __bbegin->_M_next = __bend->_M_next; + __bend->_M_next = _M_next; + } + else + __bbegin->_M_next = 0; + _M_next = __keep; + } + + template<typename _Alloc> + void + _Fwd_list_node_base<_Alloc>:: + _M_reverse_after() + { + _Pointer __tail = _M_next; + if (!__tail) + return; + while (_Pointer __temp = __tail->_M_next) + { + _Pointer __keep = _M_next; + _M_next = __temp; + __tail->_M_next = __temp->_M_next; + _M_next->_M_next = __keep; + } + } + /** * @brief Sort the singly linked list starting after this node. * This node is assumed to be an empty head node (of type @@ -412,12 +456,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std) } template<typename _Tp, typename _Alloc> - void - forward_list<_Tp, _Alloc>:: - reverse() - { this->_M_impl._M_head._M_reverse_after(); } - - template<typename _Tp, typename _Alloc> bool operator==(const forward_list<_Tp, _Alloc>& __lx, const forward_list<_Tp, _Alloc>& __ly) diff --git a/libstdc++-v3/include/std/fstream b/libstdc++-v3/include/std/fstream index 097d5769fa2..11bc743db3c 100644 --- a/libstdc++-v3/include/std/fstream +++ b/libstdc++-v3/include/std/fstream @@ -45,8 +45,11 @@ #include <istream> #include <ostream> #include <bits/codecvt.h> -#include <cstdio> // For BUFSIZ +#include <cstdio> // For BUFSIZ #include <bits/basic_file.h> // For __basic_file, __c_lock +#ifdef __GXX_EXPERIMENTAL_CXX0X__ +#include <string> // For std::string overloads. +#endif _GLIBCXX_BEGIN_NAMESPACE(std) @@ -59,7 +62,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * external disk file, and maintains a joint file position for both * sequences. Many of its semantics are described in terms of similar * behavior in the Standard C Library's @c FILE streams. - */ + */ // Requirements on traits_type, specific to this class: // traits_type::pos_type must be fpos<traits_type::state_type> // traits_type::off_type must be streamoff @@ -114,19 +117,19 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * Actual size of internal buffer. This number is equal to the size * of the put area + 1 position, reserved for the overflow char of * a full area. - */ + */ size_t _M_buf_size; // Set iff _M_buf is allocated memory from _M_allocate_internal_buffer. bool _M_buf_allocated; /** - * _M_reading == false && _M_writing == false for 'uncommitted' mode; + * _M_reading == false && _M_writing == false for 'uncommitted' mode; * _M_reading == true for 'read' mode; * _M_writing == true for 'write' mode; * * NB: _M_reading == true && _M_writing == true is unused. - */ + */ bool _M_reading; bool _M_writing; @@ -135,11 +138,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * Necessary bits for putback buffer management. * * @note pbacks of over one character are not currently supported. - */ - char_type _M_pback; + */ + char_type _M_pback; char_type* _M_pback_cur_save; char_type* _M_pback_end_save; - bool _M_pback_init; + bool _M_pback_init; //@} // Cached codecvt facet. @@ -149,19 +152,19 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * Buffer for external characters. Used for input when * codecvt::always_noconv() == false. When valid, this corresponds * to eback(). - */ + */ char* _M_ext_buf; /** * Size of buffer held by _M_ext_buf. - */ + */ streamsize _M_ext_buf_size; /** * Pointers into the buffer held by _M_ext_buf that delimit a * subsequence of bytes that have been read but not yet converted. * When valid, _M_ext_next corresponds to egptr(). - */ + */ const char* _M_ext_next; char* _M_ext_end; @@ -169,7 +172,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * Initializes pback buffers, and moves normal buffers to safety. * Assumptions: * _M_in_cur has already been moved back - */ + */ void _M_create_pback() { @@ -186,7 +189,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * Deactivates pback buffer contents, and restores normal buffer. * Assumptions: * The pback buffer has only moved forward. - */ + */ void _M_destroy_pback() throw() { @@ -206,12 +209,12 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * * The default constructor initializes the parent class using its * own default ctor. - */ + */ basic_filebuf(); /** * @brief The destructor closes the file first. - */ + */ virtual ~basic_filebuf() { this->close(); } @@ -219,7 +222,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) // Members: /** * @brief Returns true if the external file is open. - */ + */ bool is_open() const throw() { return _M_file.is_open(); } @@ -266,6 +269,18 @@ _GLIBCXX_BEGIN_NAMESPACE(std) __filebuf_type* open(const char* __s, ios_base::openmode __mode); +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + /** + * @brief Opens an external file. + * @param s The name of the file. + * @param mode The open mode flags. + * @return @c this on success, NULL on failure + */ + __filebuf_type* + open(const std::string& __s, ios_base::openmode __mode) + { return open(__s.c_str(), __mode); } +#endif + /** * @brief Closes the currently associated file. * @return @c this on success, NULL on failure @@ -276,7 +291,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * all the characters. The file is then closed. * * If any operations fail, this function also fails. - */ + */ __filebuf_type* close(); @@ -328,7 +343,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * buffer; see * http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt11ch25s02.html * for more. - */ + */ virtual __streambuf_type* setbuf(char_type* __s, streamsize __n); @@ -367,11 +382,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * __off == egptr() - eback() upon underflow/uflow ('read' mode); * __off == 0 upon overflow ('write' mode); * __off == -1 upon open, setbuf, seekoff/pos ('uncommitted' mode). - * + * * NB: epptr() - pbase() == _M_buf_size - 1, since _M_buf_size * reflects the actual allocated memory and the last cell is reserved * for the overflow char of a full put area. - */ + */ void _M_set_buffer(streamsize __off) { @@ -399,7 +414,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * functions from std::basic_istream. To control the associated * sequence, an instance of std::basic_filebuf is used, which this page * refers to as @c sb. - */ + */ template<typename _CharT, typename _Traits> class basic_ifstream : public basic_istream<_CharT, _Traits> { @@ -426,7 +441,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * Initializes @c sb using its default constructor, and passes * @c &sb to the base class initializer. Does not open any files * (you haven't given it a filename to open). - */ + */ basic_ifstream() : __istream_type(), _M_filebuf() { this->init(&_M_filebuf); } @@ -439,7 +454,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * * Tip: When using std::string to hold the filename, you must use * .c_str() before passing it to this constructor. - */ + */ explicit basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in) : __istream_type(), _M_filebuf() @@ -448,12 +463,30 @@ _GLIBCXX_BEGIN_NAMESPACE(std) this->open(__s, __mode); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + /** + * @brief Create an input file stream. + * @param s std::string specifying the filename. + * @param mode Open file in specified mode (see std::ios_base). + * + * @c ios_base::in is automatically included in @a mode. + */ + explicit + basic_ifstream(const std::string& __s, + ios_base::openmode __mode = ios_base::in) + : __istream_type(), _M_filebuf() + { + this->init(&_M_filebuf); + this->open(__s, __mode); + } +#endif + /** * @brief The destructor does nothing. * * The file is closed by the filebuf object, not the formatting * stream. - */ + */ ~basic_ifstream() { } @@ -463,7 +496,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * @return The current basic_filebuf buffer. * * This hides both signatures of std::basic_ios::rdbuf(). - */ + */ __filebuf_type* rdbuf() const { return const_cast<__filebuf_type*>(&_M_filebuf); } @@ -471,7 +504,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) /** * @brief Wrapper to test for an open file. * @return @c rdbuf()->is_open() - */ + */ bool is_open() { return _M_filebuf.is_open(); } @@ -492,7 +525,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * * Tip: When using std::string to hold the filename, you must use * .c_str() before passing it to this constructor. - */ + */ void open(const char* __s, ios_base::openmode __mode = ios_base::in) { @@ -504,12 +537,33 @@ _GLIBCXX_BEGIN_NAMESPACE(std) this->clear(); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + /** + * @brief Opens an external file. + * @param s The name of the file. + * @param mode The open mode flags. + * + * Calls @c std::basic_filebuf::open(s,mode|in). If that function + * fails, @c failbit is set in the stream's error state. + */ + void + open(const std::string& __s, ios_base::openmode __mode = ios_base::in) + { + if (!_M_filebuf.open(__s, __mode | ios_base::in)) + this->setstate(ios_base::failbit); + else + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 409. Closing an fstream should clear error state + this->clear(); + } +#endif + /** * @brief Close the file. * * Calls @c std::basic_filebuf::close(). If that function * fails, @c failbit is set in the stream's error state. - */ + */ void close() { @@ -528,7 +582,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * functions from std::basic_ostream. To control the associated * sequence, an instance of std::basic_filebuf is used, which this page * refers to as @c sb. - */ + */ template<typename _CharT, typename _Traits> class basic_ofstream : public basic_ostream<_CharT,_Traits> { @@ -555,7 +609,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * Initializes @c sb using its default constructor, and passes * @c &sb to the base class initializer. Does not open any files * (you haven't given it a filename to open). - */ + */ basic_ofstream(): __ostream_type(), _M_filebuf() { this->init(&_M_filebuf); } @@ -569,7 +623,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * * Tip: When using std::string to hold the filename, you must use * .c_str() before passing it to this constructor. - */ + */ explicit basic_ofstream(const char* __s, ios_base::openmode __mode = ios_base::out|ios_base::trunc) @@ -579,12 +633,31 @@ _GLIBCXX_BEGIN_NAMESPACE(std) this->open(__s, __mode); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + /** + * @brief Create an output file stream. + * @param s std::string specifying the filename. + * @param mode Open file in specified mode (see std::ios_base). + * + * @c ios_base::out|ios_base::trunc is automatically included in + * @a mode. + */ + explicit + basic_ofstream(const std::string& __s, + ios_base::openmode __mode = ios_base::out|ios_base::trunc) + : __ostream_type(), _M_filebuf() + { + this->init(&_M_filebuf); + this->open(__s, __mode); + } +#endif + /** * @brief The destructor does nothing. * * The file is closed by the filebuf object, not the formatting * stream. - */ + */ ~basic_ofstream() { } @@ -594,7 +667,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * @return The current basic_filebuf buffer. * * This hides both signatures of std::basic_ios::rdbuf(). - */ + */ __filebuf_type* rdbuf() const { return const_cast<__filebuf_type*>(&_M_filebuf); } @@ -602,7 +675,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) /** * @brief Wrapper to test for an open file. * @return @c rdbuf()->is_open() - */ + */ bool is_open() { return _M_filebuf.is_open(); } @@ -623,7 +696,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * * Tip: When using std::string to hold the filename, you must use * .c_str() before passing it to this constructor. - */ + */ void open(const char* __s, ios_base::openmode __mode = ios_base::out | ios_base::trunc) @@ -636,12 +709,34 @@ _GLIBCXX_BEGIN_NAMESPACE(std) this->clear(); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + /** + * @brief Opens an external file. + * @param s The name of the file. + * @param mode The open mode flags. + * + * Calls @c std::basic_filebuf::open(s,mode|out|trunc). If that + * function fails, @c failbit is set in the stream's error state. + */ + void + open(const std::string& __s, + ios_base::openmode __mode = ios_base::out | ios_base::trunc) + { + if (!_M_filebuf.open(__s, __mode | ios_base::out)) + this->setstate(ios_base::failbit); + else + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 409. Closing an fstream should clear error state + this->clear(); + } +#endif + /** * @brief Close the file. * * Calls @c std::basic_filebuf::close(). If that function * fails, @c failbit is set in the stream's error state. - */ + */ void close() { @@ -660,7 +755,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * the inherited functions from std::basic_iostream. To control the * associated sequence, an instance of std::basic_filebuf is used, which * this page refers to as @c sb. - */ + */ template<typename _CharT, typename _Traits> class basic_fstream : public basic_iostream<_CharT, _Traits> { @@ -688,7 +783,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * Initializes @c sb using its default constructor, and passes * @c &sb to the base class initializer. Does not open any files * (you haven't given it a filename to open). - */ + */ basic_fstream() : __iostream_type(), _M_filebuf() { this->init(&_M_filebuf); } @@ -700,7 +795,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * * Tip: When using std::string to hold the filename, you must use * .c_str() before passing it to this constructor. - */ + */ explicit basic_fstream(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out) @@ -710,12 +805,28 @@ _GLIBCXX_BEGIN_NAMESPACE(std) this->open(__s, __mode); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + /** + * @brief Create an input/output file stream. + * @param s Null terminated string specifying the filename. + * @param mode Open file in specified mode (see std::ios_base). + */ + explicit + basic_fstream(const std::string& __s, + ios_base::openmode __mode = ios_base::in | ios_base::out) + : __iostream_type(NULL), _M_filebuf() + { + this->init(&_M_filebuf); + this->open(__s, __mode); + } +#endif + /** * @brief The destructor does nothing. * * The file is closed by the filebuf object, not the formatting * stream. - */ + */ ~basic_fstream() { } @@ -725,7 +836,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * @return The current basic_filebuf buffer. * * This hides both signatures of std::basic_ios::rdbuf(). - */ + */ __filebuf_type* rdbuf() const { return const_cast<__filebuf_type*>(&_M_filebuf); } @@ -733,7 +844,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) /** * @brief Wrapper to test for an open file. * @return @c rdbuf()->is_open() - */ + */ bool is_open() { return _M_filebuf.is_open(); } @@ -754,7 +865,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * * Tip: When using std::string to hold the filename, you must use * .c_str() before passing it to this constructor. - */ + */ void open(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out) @@ -767,12 +878,34 @@ _GLIBCXX_BEGIN_NAMESPACE(std) this->clear(); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + /** + * @brief Opens an external file. + * @param s The name of the file. + * @param mode The open mode flags. + * + * Calls @c std::basic_filebuf::open(s,mode). If that + * function fails, @c failbit is set in the stream's error state. + */ + void + open(const std::string& __s, + ios_base::openmode __mode = ios_base::in | ios_base::out) + { + if (!_M_filebuf.open(__s, __mode)) + this->setstate(ios_base::failbit); + else + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 409. Closing an fstream should clear error state + this->clear(); + } +#endif + /** * @brief Close the file. * * Calls @c std::basic_filebuf::close(). If that function * fails, @c failbit is set in the stream's error state. - */ + */ void close() { diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/open/char/5.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/open/char/5.cc new file mode 100644 index 00000000000..dddd2f16ff6 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/open/char/5.cc @@ -0,0 +1,31 @@ +// Copyright (C) 2009 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +#include <fstream> + +// Test member functions. +void test01() +{ + std::filebuf fb; + + const std::string name = "filebuf_name.txt"; + fb.open(name, std::ios_base::in | std::ios_base::ate); +} diff --git a/libstdc++-v3/testsuite/27_io/basic_fstream/cons/3.cc b/libstdc++-v3/testsuite/27_io/basic_fstream/cons/1.cc index 4b01bd10ef4..4b01bd10ef4 100644 --- a/libstdc++-v3/testsuite/27_io/basic_fstream/cons/3.cc +++ b/libstdc++-v3/testsuite/27_io/basic_fstream/cons/1.cc diff --git a/libstdc++-v3/testsuite/27_io/basic_fstream/cons/char/1.cc b/libstdc++-v3/testsuite/27_io/basic_fstream/cons/char/1.cc new file mode 100644 index 00000000000..5b0047aa19d --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_fstream/cons/char/1.cc @@ -0,0 +1,28 @@ +// Copyright (C) 2009 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +#include <fstream> + +void test01() +{ + const std::string name = "fstream_name.txt"; + std::fstream fs(name); +} diff --git a/libstdc++-v3/testsuite/27_io/basic_fstream/open/char/1.cc b/libstdc++-v3/testsuite/27_io/basic_fstream/open/char/1.cc new file mode 100644 index 00000000000..9277339e980 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_fstream/open/char/1.cc @@ -0,0 +1,32 @@ +// Copyright (C) 2009 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +#include <fstream> + +void test01() +{ + std::fstream fs; + + const std::string name = "fstream_name.txt"; + fs.open(name); + + fs.close(); +} diff --git a/libstdc++-v3/testsuite/27_io/basic_ifstream/cons/char/2.cc b/libstdc++-v3/testsuite/27_io/basic_ifstream/cons/char/2.cc new file mode 100644 index 00000000000..44d3b9d0d79 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_ifstream/cons/char/2.cc @@ -0,0 +1,28 @@ +// Copyright (C) 2009 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +#include <fstream> + +void test01() +{ + const std::string name = "ifstream_name.txt"; + std::ifstream ifs(name); +} diff --git a/libstdc++-v3/testsuite/27_io/basic_ifstream/open/char/2.cc b/libstdc++-v3/testsuite/27_io/basic_ifstream/open/char/2.cc new file mode 100644 index 00000000000..21b34fb907c --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_ifstream/open/char/2.cc @@ -0,0 +1,32 @@ +// Copyright (C) 2009 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +#include <fstream> + +void test01() +{ + std::ifstream ifs; + + const std::string name = "ifstream_name.txt"; + ifs.open(name); + + ifs.close(); +} diff --git a/libstdc++-v3/testsuite/27_io/basic_ofstream/cons/char/1.cc b/libstdc++-v3/testsuite/27_io/basic_ofstream/cons/char/1.cc new file mode 100644 index 00000000000..106639c16de --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_ofstream/cons/char/1.cc @@ -0,0 +1,51 @@ +// Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// 27.8.1.10 ofstream member functions +// @require@ %-*.tst +// @diff@ %-*.tst %-*.txt + +// { dg-require-fileio "" } + +#include <ostream> +#include <fstream> +#include <testsuite_hooks.h> + +const char name_02[] = "ofstream_members-1.txt"; + +// http://gcc.gnu.org/ml/libstdc++/2000-07/msg00004.html +void test02() +{ + bool test __attribute__((unused)) = true; + const int more_than_max_open_files = 8200; + + for(int i = 0; ++i < more_than_max_open_files;) + { + std::ofstream ifs(name_02); + VERIFY( static_cast<bool>(ifs) ); + } +} + +int main() +{ + test02(); + return 0; +} + + + diff --git a/libstdc++-v3/testsuite/27_io/basic_ofstream/cons/char/2.cc b/libstdc++-v3/testsuite/27_io/basic_ofstream/cons/char/2.cc index 106639c16de..dc47541eb03 100644 --- a/libstdc++-v3/testsuite/27_io/basic_ofstream/cons/char/2.cc +++ b/libstdc++-v3/testsuite/27_io/basic_ofstream/cons/char/2.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc. +// Copyright (C) 2009 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -16,36 +16,13 @@ // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. -// 27.8.1.10 ofstream member functions -// @require@ %-*.tst -// @diff@ %-*.tst %-*.txt +// { dg-do compile } +// { dg-options "-std=gnu++0x" } -// { dg-require-fileio "" } - -#include <ostream> #include <fstream> -#include <testsuite_hooks.h> - -const char name_02[] = "ofstream_members-1.txt"; - -// http://gcc.gnu.org/ml/libstdc++/2000-07/msg00004.html -void test02() -{ - bool test __attribute__((unused)) = true; - const int more_than_max_open_files = 8200; - - for(int i = 0; ++i < more_than_max_open_files;) - { - std::ofstream ifs(name_02); - VERIFY( static_cast<bool>(ifs) ); - } -} -int main() +void test01() { - test02(); - return 0; + const std::string name = "ofstream_name.txt"; + std::ofstream ofs(name); } - - - diff --git a/libstdc++-v3/testsuite/27_io/basic_ofstream/open/char/2.cc b/libstdc++-v3/testsuite/27_io/basic_ofstream/open/char/2.cc new file mode 100644 index 00000000000..f457c96ff5f --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_ofstream/open/char/2.cc @@ -0,0 +1,32 @@ +// Copyright (C) 2009 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +#include <fstream> + +void test01() +{ + std::ofstream ofs; + + const std::string name = "ofstream_name.txt"; + ofs.open(name); + + ofs.close(); +} |