diff options
author | Joseph Myers <joseph@codesourcery.com> | 2013-11-08 22:46:41 +0000 |
---|---|---|
committer | Joseph Myers <joseph@codesourcery.com> | 2013-11-08 22:46:41 +0000 |
commit | fb3f3b1678683afa84b77049e373b942476f4a26 (patch) | |
tree | 81d81cfbf7328090ebee52ccef1d6ae41c6b6d62 | |
parent | 168756e6efd81fafc03b809b2291c2cbbb685dff (diff) | |
parent | ec1c555d37fcda7b7bcd00051fc6c0bdb84ad1b2 (diff) |
Merge from trunk.C11-atomic
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/C11-atomic@204607 138bc75d-0d04-0410-961f-82ee72b054a4
45 files changed, 1071 insertions, 646 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 319256507b4..07f5d46e545 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,47 +1,5 @@ -2013-11-08 Joseph Myers <joseph@codesourcery.com> - - * ginclude/stdatomic.h: Reformat contents of file. Include macro - names in names of local temporaries. - (memory_order): Do not use enum tag. - (atomic_init): Use do { } while (0). - (atomic_thread_fence, atomic_signal_fence): Make function-like - macros. - (atomic_is_lock_free): Pass object pointer to - __atomic_is_lock_free. - (__atomic_type_lock_free): New macro. - (ATOMIC_BOOL_LOCK_FREE, ATOMIC_CHAR_LOCK_FREE) - (ATOMIC_CHAR16_T_LOCK_FREE, ATOMIC_CHAR32_T_LOCK_FREE) - (ATOMIC_WCHAR_T_LOCK_FREE, ATOMIC_SHORT_LOCK_FREE) - (ATOMIC_INT_LOCK_FREE, ATOMIC_LONG_LOCK_FREE) - (ATOMIC_LLONG_LOCK_FREE, ATOMIC_POINTER_LOCK_FREE): Define using - __atomic_type_lock_free. - (atomic_load_explicit): Use given memory order, not - __ATOMIC_SEQ_CST. - (atomic_exchange_explicit): Use __atomic_exchange with pointer to - temporary for value. - (atomic_compare_exchange_strong_explicit) - (atomic_compare_exchange_weak_explicit): Use - __atomic_compare_exchange. - (atomic_flag): Make into a structure type. - (ATOMIC_FLAG_INIT): Use braced initializer. - (atomic_flag_test_and_set, atomic_flag_test_and_set_explicit): Use - __atomic_test_and_set. - (atomic_flag_clear, atomic_flag_clear_explicit): Use - __atomic_clear. - -2013-10-19 Joseph Myers <joseph@codesourcery.com> - - * ginclude/stdatomic.h: Add missing semicolons to typedefs. - (kill_dependency): Use temporary variable. - 2013-10-17 Joseph Myers <joseph@codesourcery.com> - * Makefile.in (USER_H): Add stdatomic.h. - * ginclude/stdatomic.h: Fix formatting and typos. Use correct - types or predefined macros for atomic_* typedefs. Use - __extension__ in macro definitions. - (enum memory_order): Specify values of enumeration constants using - __ATOMIC_* predefined macros. * tree.c (build_common_tree_nodes): Fix typos. 2013-09-25 Andrew MacLeod <amacleod@redhat.com> @@ -63,6 +21,72 @@ * doc/tm.texi (TARGET_ATOMIC_ALIGN_FOR_MODE): Define. * doc/tm.texi.in (TARGET_ATOMIC_ALIGN_FOR_MODE): Add. +2013-11-08 H.J. Lu <hongjiu.lu@intel.com> + + PR other/59055 + * doc/extend.texi: Move Cilk Plus Builtins node before Other + Builtins node. + +2013-11-08 Andrew MacLeod <amacleod@redhat.com> + Joseph Myers <joseph@codesourcery.com> + + * ginclude/stdatomic.h: New file. + * Makefile.in (USER_H): Add stdatomic.h. + +2013-11-08 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + + * config/arm/arm.c (arm_new_rtx_costs): Break after handling + comparisons. + +2013-11-08 Jeff Law <law@redhat.com> + + * tree-ssa-threadupdate.h (delete_thread_path): Declare. + * tree-ssa-threadupdate.c (delete_thread_path): New function. + (ssa_redirect_edges, thread_block_1): Use it. + (thread_through_loop_header, mark_threaded_blocks): Likewise. + (thread_through_all_blocks, register_jump_thread): Likewise. + * tree-ssa-threadedge.c (thread_across_edge): Likewise. + +2013-11-08 James Greenhalgh <james.greenhalgh@arm.com> + + * config/arm/aarch-common.c + (search_term): New typedef. + (shift_rtx_costs): New array. + (arm_rtx_shift_left_p): New. + (arm_find_sub_rtx_with_search_term): Likewise. + (arm_find_sub_rtx_with_code): Likewise. + (arm_early_load_addr_dep): Add sanity checking. + (arm_no_early_alu_shift_dep): Likewise. + (arm_no_early_alu_shift_value_dep): Likewise. + (arm_no_early_mul_dep): Likewise. + (arm_no_early_store_addr_dep): Likewise. + +2013-11-08 Richard Biener <rguenther@suse.de> + + PR tree-optimization/59047 + * tree-predcom.c (ref_at_iteration): Handle bitfield accesses + properly. + +2013-11-08 Ilya Enkovich <ilya.enkovich@intel.com> + + * common.opt (fcheck-pointer-bounds): Move to ... + * c-family/c.opt: ... here. + * langhooks-def.h (LANG_HOOKS_CHKP_SUPPORTED): Remove. + (LANG_HOOKS_INITIALIZER): Remove LANG_HOOKS_CHKP_SUPPORTED. + * langhooks.h (lang_hooks): Remove chkp_supported field. + * toplev.c (process_options): Remove chkp_supported check. + +2013-11-08 Richard Biener <rguenther@suse.de> + + PR tree-optimization/59038 + PR tree-optimization/58955 + * tree-loop-distribution.c (pg_add_dependence_edges): Revert + previous change. Handle known dependences correctly. + +2013-11-08 Tom de Vries <tom@codesourcery.com> + + * config/rs6000/t-xilinx: Remove duplicate contents. + 2013-11-07 Andrew MacLeod <amacleod@redhat.com> Joseph Myers <joseph@codesourcery.com> diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 2042aaf99a1..30b0820adcf 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20131107 +20131108 diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 46391fa496c..0026683730e 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -854,6 +854,11 @@ fcanonical-system-headers C ObjC C++ ObjC++ Where shorter, use canonicalized paths to systems headers. +fcheck-pointer-bounds +C ObjC C++ ObjC++ LTO Report Var(flag_check_pointer_bounds) +Add Pointer Bounds Checker instrumentation. fchkp-* flags are used to +control instrumentation. + fcilkplus C ObjC C++ ObjC++ LTO Report Var(flag_enable_cilkplus) Init(0) Enable Cilk Plus diff --git a/gcc/common.opt b/gcc/common.opt index 7e1e3ded458..d5971df6418 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -874,11 +874,6 @@ fbounds-check Common Report Var(flag_bounds_check) Generate code to check bounds before indexing arrays -fcheck-pointer-bounds -Common Report Var(flag_check_pointer_bounds) -Add Pointer Bounds Checker instrumentation. fchkp-* flags are used to -control instrumentation. Currently available for C, C++ and ObjC. - fbranch-count-reg Common Report Var(flag_branch_on_count_reg) Init(1) Optimization Replace add, compare, branch with branch on count register diff --git a/gcc/config/arm/aarch-common.c b/gcc/config/arm/aarch-common.c index 3111ae99fce..201e581a4a6 100644 --- a/gcc/config/arm/aarch-common.c +++ b/gcc/config/arm/aarch-common.c @@ -31,30 +31,139 @@ #include "c-family/c-common.h" #include "rtl.h" -/* Return nonzero if the CONSUMER instruction (a load) does need - PRODUCER's value to calculate the address. */ +typedef struct +{ + rtx_code search_code; + rtx search_result; + bool find_any_shift; +} search_term; + +/* Return TRUE if X is either an arithmetic shift left, or + is a multiplication by a power of two. */ +static bool +arm_rtx_shift_left_p (rtx x) +{ + enum rtx_code code = GET_CODE (x); -int -arm_early_load_addr_dep (rtx producer, rtx consumer) + if (code == MULT && CONST_INT_P (XEXP (x, 1)) + && exact_log2 (INTVAL (XEXP (x, 1))) > 0) + return true; + + if (code == ASHIFT) + return true; + + return false; +} + +static rtx_code shift_rtx_codes[] = + { ASHIFT, ROTATE, ASHIFTRT, LSHIFTRT, + ROTATERT, ZERO_EXTEND, SIGN_EXTEND }; + +/* Callback function for arm_find_sub_rtx_with_code. + DATA is safe to treat as a SEARCH_TERM, ST. This will + hold a SEARCH_CODE. PATTERN is checked to see if it is an + RTX with that code. If it is, write SEARCH_RESULT in ST + and return 1. Otherwise, or if we have been passed a NULL_RTX + return 0. If ST.FIND_ANY_SHIFT then we are interested in + anything which can reasonably be described as a SHIFT RTX. */ +static int +arm_find_sub_rtx_with_search_term (rtx *pattern, void *data) { - rtx value = PATTERN (producer); - rtx addr = PATTERN (consumer); - - if (GET_CODE (value) == COND_EXEC) - value = COND_EXEC_CODE (value); - if (GET_CODE (value) == PARALLEL) - value = XVECEXP (value, 0, 0); - value = XEXP (value, 0); - if (GET_CODE (addr) == COND_EXEC) - addr = COND_EXEC_CODE (addr); - if (GET_CODE (addr) == PARALLEL) + search_term *st = (search_term *) data; + rtx_code pattern_code; + int found = 0; + + gcc_assert (pattern); + gcc_assert (st); + + /* Poorly formed patterns can really ruin our day. */ + if (*pattern == NULL_RTX) + return 0; + + pattern_code = GET_CODE (*pattern); + + if (st->find_any_shift) { - if (GET_CODE (XVECEXP (addr, 0, 0)) == RETURN) - addr = XVECEXP (addr, 0, 1); + unsigned i = 0; + + /* Left shifts might have been canonicalized to a MULT of some + power of two. Make sure we catch them. */ + if (arm_rtx_shift_left_p (*pattern)) + found = 1; else - addr = XVECEXP (addr, 0, 0); + for (i = 0; i < ARRAY_SIZE (shift_rtx_codes); i++) + if (pattern_code == shift_rtx_codes[i]) + found = 1; + } + + if (pattern_code == st->search_code) + found = 1; + + if (found) + st->search_result = *pattern; + + return found; +} + +/* Traverse PATTERN looking for a sub-rtx with RTX_CODE CODE. */ +static rtx +arm_find_sub_rtx_with_code (rtx pattern, rtx_code code, bool find_any_shift) +{ + search_term st; + int result = 0; + + gcc_assert (pattern != NULL_RTX); + st.search_code = code; + st.search_result = NULL_RTX; + st.find_any_shift = find_any_shift; + result = for_each_rtx (&pattern, arm_find_sub_rtx_with_search_term, &st); + if (result) + return st.search_result; + else + return NULL_RTX; +} + +/* Traverse PATTERN looking for any sub-rtx which looks like a shift. */ +static rtx +arm_find_shift_sub_rtx (rtx pattern) +{ + return arm_find_sub_rtx_with_code (pattern, ASHIFT, true); +} + +/* PRODUCER and CONSUMER are two potentially dependant RTX. PRODUCER + (possibly) contains a SET which will provide a result we can access + using the SET_DEST macro. We will place the RTX which would be + written by PRODUCER in SET_SOURCE. + Similarly, CONSUMER (possibly) contains a SET which has an operand + we can access using SET_SRC. We place this operand in + SET_DESTINATION. + + Return nonzero if we found the SET RTX we expected. */ +static int +arm_get_set_operands (rtx producer, rtx consumer, + rtx *set_source, rtx *set_destination) +{ + rtx set_producer = arm_find_sub_rtx_with_code (producer, SET, false); + rtx set_consumer = arm_find_sub_rtx_with_code (consumer, SET, false); + + if (set_producer && set_consumer) + { + *set_source = SET_DEST (set_producer); + *set_destination = SET_SRC (set_consumer); + return 1; } - addr = XEXP (addr, 1); + return 0; +} + +/* Return nonzero if the CONSUMER instruction (a load) does need + PRODUCER's value to calculate the address. */ +int +arm_early_load_addr_dep (rtx producer, rtx consumer) +{ + rtx value, addr; + + if (!arm_get_set_operands (producer, consumer, &value, &addr)) + return 0; return reg_overlap_mentioned_p (value, addr); } @@ -62,88 +171,56 @@ arm_early_load_addr_dep (rtx producer, rtx consumer) /* Return nonzero if the CONSUMER instruction (an ALU op) does not have an early register shift value or amount dependency on the result of PRODUCER. */ - int arm_no_early_alu_shift_dep (rtx producer, rtx consumer) { - rtx value = PATTERN (producer); - rtx op = PATTERN (consumer); + rtx value, op; rtx early_op; - if (GET_CODE (value) == COND_EXEC) - value = COND_EXEC_CODE (value); - if (GET_CODE (value) == PARALLEL) - value = XVECEXP (value, 0, 0); - value = XEXP (value, 0); - if (GET_CODE (op) == COND_EXEC) - op = COND_EXEC_CODE (op); - if (GET_CODE (op) == PARALLEL) - op = XVECEXP (op, 0, 0); - op = XEXP (op, 1); - - early_op = XEXP (op, 0); - /* This is either an actual independent shift, or a shift applied to - the first operand of another operation. We want the whole shift - operation. */ - if (REG_P (early_op)) - early_op = op; - - return !reg_overlap_mentioned_p (value, early_op); + if (!arm_get_set_operands (producer, consumer, &value, &op)) + return 0; + + if ((early_op = arm_find_shift_sub_rtx (op))) + { + if (REG_P (early_op)) + early_op = op; + + return !reg_overlap_mentioned_p (value, early_op); + } + + return 0; } /* Return nonzero if the CONSUMER instruction (an ALU op) does not have an early register shift value dependency on the result of PRODUCER. */ - int arm_no_early_alu_shift_value_dep (rtx producer, rtx consumer) { - rtx value = PATTERN (producer); - rtx op = PATTERN (consumer); + rtx value, op; rtx early_op; - if (GET_CODE (value) == COND_EXEC) - value = COND_EXEC_CODE (value); - if (GET_CODE (value) == PARALLEL) - value = XVECEXP (value, 0, 0); - value = XEXP (value, 0); - if (GET_CODE (op) == COND_EXEC) - op = COND_EXEC_CODE (op); - if (GET_CODE (op) == PARALLEL) - op = XVECEXP (op, 0, 0); - op = XEXP (op, 1); - - early_op = XEXP (op, 0); - - /* This is either an actual independent shift, or a shift applied to - the first operand of another operation. We want the value being - shifted, in either case. */ - if (!REG_P (early_op)) - early_op = XEXP (early_op, 0); - - return !reg_overlap_mentioned_p (value, early_op); + if (!arm_get_set_operands (producer, consumer, &value, &op)) + return 0; + + if ((early_op = arm_find_shift_sub_rtx (op))) + /* We want to check the value being shifted. */ + if (!reg_overlap_mentioned_p (value, XEXP (early_op, 0))) + return 1; + + return 0; } /* Return nonzero if the CONSUMER (a mul or mac op) does not have an early register mult dependency on the result of PRODUCER. */ - int arm_no_early_mul_dep (rtx producer, rtx consumer) { - rtx value = PATTERN (producer); - rtx op = PATTERN (consumer); - - if (GET_CODE (value) == COND_EXEC) - value = COND_EXEC_CODE (value); - if (GET_CODE (value) == PARALLEL) - value = XVECEXP (value, 0, 0); - value = XEXP (value, 0); - if (GET_CODE (op) == COND_EXEC) - op = COND_EXEC_CODE (op); - if (GET_CODE (op) == PARALLEL) - op = XVECEXP (op, 0, 0); - op = XEXP (op, 1); + rtx value, op; + + if (!arm_get_set_operands (producer, consumer, &value, &op)) + return 0; if (GET_CODE (op) == PLUS || GET_CODE (op) == MINUS) { @@ -162,19 +239,17 @@ arm_no_early_mul_dep (rtx producer, rtx consumer) int arm_no_early_store_addr_dep (rtx producer, rtx consumer) { - rtx value = PATTERN (producer); - rtx addr = PATTERN (consumer); - - if (GET_CODE (value) == COND_EXEC) - value = COND_EXEC_CODE (value); - if (GET_CODE (value) == PARALLEL) - value = XVECEXP (value, 0, 0); - value = XEXP (value, 0); - if (GET_CODE (addr) == COND_EXEC) - addr = COND_EXEC_CODE (addr); - if (GET_CODE (addr) == PARALLEL) - addr = XVECEXP (addr, 0, 0); - addr = XEXP (addr, 0); + rtx value = arm_find_sub_rtx_with_code (producer, SET, false); + rtx addr = arm_find_sub_rtx_with_code (consumer, SET, false); + + if (value) + value = SET_DEST (value); + + if (addr) + addr = SET_DEST (addr); + + if (!value || !addr) + return 0; return !reg_overlap_mentioned_p (value, addr); } diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 7757e86691f..930bdf67826 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -9965,6 +9965,7 @@ arm_new_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code, *cost = 0; return true; } + break; case ABS: if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT diff --git a/gcc/config/rs6000/t-xilinx b/gcc/config/rs6000/t-xilinx index 2abb333d585..1e05215e221 100644 --- a/gcc/config/rs6000/t-xilinx +++ b/gcc/config/rs6000/t-xilinx @@ -26,31 +26,3 @@ MULTILIB_OPTIONS = mfpu=sp_lite/mfpu=dp_lite MULTILIB_DIRNAMES = single double -# Multilibs for Xilinx powerpc embedded ELF targets. -# -# Copyright (C) 2009-2013 Free Software Foundation, Inc. -# Contributed by Michael Eager, eager@eagercon.com -# -# This file is part of GCC. -# -# GCC 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 3, or (at your option) -# any later version. -# -# GCC 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 GCC; see the file COPYING3. If not see -# <http://www.gnu.org/licenses/>. - -# Switch synonyms -MULTILIB_MATCHES = mfpu?sp_lite=msingle-float mfpu?dp_lite=mdouble-float mfpu?dp_lite=mhard-float mfpu?sp_lite=mfpu?sp_full mfpu?dp_lite=mfpu?dp_full - -MULTILIB_OPTIONS = mfpu=sp_lite/mfpu=dp_lite - -MULTILIB_DIRNAMES = single double - diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 0d72819b1b0..2132b1e5602 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -8012,6 +8012,32 @@ returns -1. @end deftypefn +@node Cilk Plus Builtins +@section Cilk Plus C/C++ language extension Built-in Functions. + +GCC provides support for the following built-in reduction funtions if Cilk Plus +is enabled. Cilk Plus can be enabled using the @option{-fcilkplus} flag. + +@itemize @bullet +@item __sec_implicit_index +@item __sec_reduce +@item __sec_reduce_add +@item __sec_reduce_all_nonzero +@item __sec_reduce_all_zero +@item __sec_reduce_any_nonzero +@item __sec_reduce_any_zero +@item __sec_reduce_max +@item __sec_reduce_min +@item __sec_reduce_max_ind +@item __sec_reduce_min_ind +@item __sec_reduce_mul +@item __sec_reduce_mutating +@end itemize + +Further details and examples about these built-in functions are described +in the Cilk Plus language manual which can be found at +@uref{http://www.cilkplus.org}. + @node Other Builtins @section Other Built-in Functions Provided by GCC @cindex built-in functions @@ -9136,32 +9162,6 @@ Similar to @code{__builtin_bswap32}, except the argument and return types are 64 bit. @end deftypefn -@node Cilk Plus Builtins -@section Cilk Plus C/C++ language extension Built-in Functions. - -GCC provides support for the following built-in reduction funtions if Cilk Plus -is enabled. Cilk Plus can be enabled using the @option{-fcilkplus} flag. - -@itemize @bullet -@item __sec_implicit_index -@item __sec_reduce -@item __sec_reduce_add -@item __sec_reduce_all_nonzero -@item __sec_reduce_all_zero -@item __sec_reduce_any_nonzero -@item __sec_reduce_any_zero -@item __sec_reduce_max -@item __sec_reduce_min -@item __sec_reduce_max_ind -@item __sec_reduce_min_ind -@item __sec_reduce_mul -@item __sec_reduce_mutating -@end itemize - -Further details and examples about these built-in functions are described -in the Cilk Plus language manual which can be found at -@uref{http://www.cilkplus.org}. - @node Target Builtins @section Built-in Functions Specific to Particular Target Machines diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index c7096219a26..8e2e10c8539 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,8 @@ +2013-11-07 Janus Weil <janus@gcc.gnu.org> + + PR fortran/58471 + * primary.c (gfc_expr_attr): Check for result symbol. + 2013-11-06 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> * gfortran.texi: Fix typo. diff --git a/gcc/fortran/primary.c b/gcc/fortran/primary.c index 80d45eaea12..c9a26b09be4 100644 --- a/gcc/fortran/primary.c +++ b/gcc/fortran/primary.c @@ -2258,7 +2258,7 @@ gfc_expr_attr (gfc_expr *e) case EXPR_FUNCTION: gfc_clear_attr (&attr); - if (e->value.function.esym != NULL) + if (e->value.function.esym && e->value.function.esym->result) { gfc_symbol *sym = e->value.function.esym->result; attr = sym->attr; diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index c4d32686178..aefb51cec5e 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -3351,9 +3351,10 @@ Type_conversion_expression::do_get_tree(Translate_context* context) return se->get_tree(context); } - Call_expression* i2s_expr = + Expression* i2s_expr = Runtime::make_call(Runtime::INT_TO_STRING, this->location(), 1, this->expr_); + i2s_expr = Expression::make_cast(type, i2s_expr, this->location()); ret = i2s_expr->get_tree(context); } else if (type->is_string_type() && expr_type->is_slice_type()) @@ -3405,7 +3406,7 @@ Type_conversion_expression::do_get_tree(Translate_context* context) Type* e = type->array_type()->element_type()->forwarded(); go_assert(e->integer_type() != NULL); - Call_expression* s2a_expr; + Expression* s2a_expr; if (e->integer_type()->is_byte()) s2a_expr = Runtime::make_call(Runtime::STRING_TO_BYTE_ARRAY, this->location(), 1, this->expr_); @@ -3415,6 +3416,8 @@ Type_conversion_expression::do_get_tree(Translate_context* context) s2a_expr = Runtime::make_call(Runtime::STRING_TO_INT_ARRAY, this->location(), 1, this->expr_); } + s2a_expr = Expression::make_unsafe_cast(type, s2a_expr, + this->location()); ret = s2a_expr->get_tree(context); } else if ((type->is_unsafe_pointer_type() @@ -13485,10 +13488,52 @@ class Composite_literal_expression : public Parser_expression int Composite_literal_expression::do_traverse(Traverse* traverse) { - if (this->vals_ != NULL - && this->vals_->traverse(traverse) == TRAVERSE_EXIT) + if (Type::traverse(this->type_, traverse) == TRAVERSE_EXIT) return TRAVERSE_EXIT; - return Type::traverse(this->type_, traverse); + + // If this is a struct composite literal with keys, then the keys + // are field names, not expressions. We don't want to traverse them + // in that case. If we do, we can give an erroneous error "variable + // initializer refers to itself." See bug482.go in the testsuite. + if (this->has_keys_ && this->vals_ != NULL) + { + // The type may not be resolvable at this point. + Type* type = this->type_; + while (true) + { + if (type->classification() == Type::TYPE_NAMED) + type = type->named_type()->real_type(); + else if (type->classification() == Type::TYPE_FORWARD) + { + Type* t = type->forwarded(); + if (t == type) + break; + type = t; + } + else + break; + } + + if (type->classification() == Type::TYPE_STRUCT) + { + Expression_list::iterator p = this->vals_->begin(); + while (p != this->vals_->end()) + { + // Skip key. + ++p; + go_assert(p != this->vals_->end()); + if (Expression::traverse(&*p, traverse) == TRAVERSE_EXIT) + return TRAVERSE_EXIT; + ++p; + } + return TRAVERSE_CONTINUE; + } + } + + if (this->vals_ != NULL) + return this->vals_->traverse(traverse); + + return TRAVERSE_CONTINUE; } // Lower a generic composite literal into a specific version based on diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h index 67eb2faa778..411cf74b666 100644 --- a/gcc/langhooks-def.h +++ b/gcc/langhooks-def.h @@ -118,7 +118,6 @@ extern bool lhd_omp_mappable_type (tree); #define LANG_HOOKS_BLOCK_MAY_FALLTHRU hook_bool_const_tree_true #define LANG_HOOKS_EH_USE_CXA_END_CLEANUP false #define LANG_HOOKS_DEEP_UNSHARING false -#define LANG_HOOKS_CHKP_SUPPORTED false /* Attribute hooks. */ #define LANG_HOOKS_ATTRIBUTE_TABLE NULL @@ -319,8 +318,7 @@ extern void lhd_end_section (void); LANG_HOOKS_EH_PROTECT_CLEANUP_ACTIONS, \ LANG_HOOKS_BLOCK_MAY_FALLTHRU, \ LANG_HOOKS_EH_USE_CXA_END_CLEANUP, \ - LANG_HOOKS_DEEP_UNSHARING, \ - LANG_HOOKS_CHKP_SUPPORTED \ + LANG_HOOKS_DEEP_UNSHARING \ } #endif /* GCC_LANG_HOOKS_DEF_H */ diff --git a/gcc/langhooks.h b/gcc/langhooks.h index 48f18ac8269..9539e7d5b7a 100644 --- a/gcc/langhooks.h +++ b/gcc/langhooks.h @@ -491,9 +491,6 @@ struct lang_hooks gimplification. */ bool deep_unsharing; - /* True if this language allows pointers checker instrumentation. */ - bool chkp_supported; - /* Whenever you add entries here, make sure you adjust langhooks-def.h and langhooks.c accordingly. */ }; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 29c984461b7..1931f5d386a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2013-09-25 Andrew MacLeod <amacleod@redhat.com> + + * gcc.dg/atomic-exchange-{1-5}.c: Change atomic var to use + __attribute__((atomic)). + * gcc.dg/atomic-op-{1-5}.c: Add --std=c11 and change atomic var to + use _Atomic keyword. + 2013-11-08 Joseph Myers <joseph@codesourcery.com> * gcc.dg/atomic/stdatomic-compare-exchange-1.c, @@ -24,12 +31,26 @@ gcc.dg/atomic/stdatomic-store-4.c, gcc.dg/c11-stdatomic-1.c: New tests. -2013-09-25 Andrew MacLeod <amacleod@redhat.com> +2013-11-08 Cong Hou <congh@google.com> - * gcc.dg/atomic-exchange-{1-5}.c: Change atomic var to use - __attribute__((atomic)). - * gcc.dg/atomic-op-{1-5}.c: Add --std=c11 and change atomic var to - use _Atomic keyword. + PR tree-optimization/58508 + * gcc.dg/vect/pr58508.c: Update. + +2013-11-08 Richard Biener <rguenther@suse.de> + + PR tree-optimization/59047 + * gcc.dg/torture/pr59047.c: New testcase. + +2013-11-08 Richard Biener <rguenther@suse.de> + + PR tree-optimization/59038 + PR tree-optimization/58955 + * gcc.dg/torture/pr59038.c: New testcase. + +2013-11-07 Janus Weil <janus@gcc.gnu.org> + + PR fortran/58471 + * gfortran.dg/constructor_9.f90: New. 2013-11-07 Joseph Myers <joseph@codesourcery.com> diff --git a/gcc/testsuite/gcc.dg/torture/pr59038.c b/gcc/testsuite/gcc.dg/torture/pr59038.c new file mode 100644 index 00000000000..1694eca4300 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr59038.c @@ -0,0 +1,25 @@ +/* { dg-do run } */ + +extern void abort (void); + +unsigned char first_ones_8bit[256]; +unsigned char connected_passed[256]; + +int +main () +{ + int i, j; + for (i=0;i<256;i++){ + connected_passed[i]=0; + first_ones_8bit[i]=0; + for (j=7;j>0;j--){ + if ((i & (3<<(7-j))) == (3<<(7-j))){ + connected_passed[i]=j; + break; + } + } + } + if (connected_passed[3] != 7) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr59047.c b/gcc/testsuite/gcc.dg/torture/pr59047.c new file mode 100644 index 00000000000..fcedfcba870 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr59047.c @@ -0,0 +1,39 @@ +/* { dg-do run } */ + +extern void abort (void); + +struct +{ + int f0; + int f1:1; + int f2:2; +} a = {0, 0, 1}; + +int b, c, *d, e, f; + +int +fn1 () +{ + for (; b < 1; ++b) + { + for (e = 0; e < 1; e = 1) + { + int **g = &d; + *g = &c; + } + *d = 0; + f = a.f1; + if (f) + return 0; + } + return 0; +} + +int +main () +{ + fn1 (); + if (b != 1) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/vect/pr58508.c b/gcc/testsuite/gcc.dg/vect/pr58508.c index 2db761e2627..c4921bb768f 100644 --- a/gcc/testsuite/gcc.dg/vect/pr58508.c +++ b/gcc/testsuite/gcc.dg/vect/pr58508.c @@ -1,3 +1,4 @@ +/* { dg-require-effective-target vect_int } */ /* { dg-do compile } */ diff --git a/gcc/testsuite/gfortran.dg/constructor_9.f90 b/gcc/testsuite/gfortran.dg/constructor_9.f90 new file mode 100644 index 00000000000..5196703031a --- /dev/null +++ b/gcc/testsuite/gfortran.dg/constructor_9.f90 @@ -0,0 +1,22 @@ +! { dg-do compile } +! { dg-options "-Wall" } +! +! PR 58471: [4.8/4.9 Regression] ICE on invalid with missing type constructor and -Wall +! +! Contributed by Andrew Benson <abensonca@gmail.com> + +module cf + implicit none + type :: cfmde + end type + interface cfmde + module procedure mdedc ! { dg-error "is neither function nor subroutine" } + end interface +contains + subroutine cfi() + type(cfmde), pointer :: cfd + cfd=cfmde() ! { dg-error "Can't convert" } + end subroutine +end module + +! { dg-final { cleanup-modules "cf" } } diff --git a/gcc/toplev.c b/gcc/toplev.c index f78912e09db..ad6849996e1 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -1286,9 +1286,6 @@ process_options (void) { if (targetm.chkp_bound_mode () == VOIDmode) error ("-fcheck-pointers is not supported for this target"); - - if (!lang_hooks.chkp_supported) - flag_check_pointer_bounds = 0; } /* One region RA really helps to decrease the code size. */ diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c index 4f9b848847a..45efad3f110 100644 --- a/gcc/tree-loop-distribution.c +++ b/gcc/tree-loop-distribution.c @@ -1324,7 +1324,7 @@ pg_add_dependence_edges (struct graph *rdg, vec<loop_p> loops, int dir, for (int ii = 0; drs1.iterate (ii, &dr1); ++ii) for (int jj = 0; drs2.iterate (jj, &dr2); ++jj) { - int this_dir = -1; + int this_dir = 1; ddr_p ddr; /* Re-shuffle data-refs to be in dominator order. */ if (rdg_vertex_for_stmt (rdg, DR_STMT (dr1)) @@ -1350,8 +1350,17 @@ pg_add_dependence_edges (struct graph *rdg, vec<loop_p> loops, int dir, } /* Known dependences can still be unordered througout the iteration space, see gcc.dg/tree-ssa/ldist-16.c. */ - if (DDR_NUM_DIST_VECTS (ddr) == 0) + if (DDR_NUM_DIST_VECTS (ddr) != 1) this_dir = 2; + /* If the overlap is exact preserve stmt order. */ + else if (lambda_vector_zerop (DDR_DIST_VECT (ddr, 0), 1)) + ; + else + { + /* Else as the distance vector is lexicographic positive + swap the dependence direction. */ + this_dir = -this_dir; + } } else this_dir = 0; diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c index 3358f8b9331..6084cf62ef6 100644 --- a/gcc/tree-predcom.c +++ b/gcc/tree-predcom.c @@ -1353,10 +1353,24 @@ ref_at_iteration (data_reference_p dr, int iter, gimple_seq *stmts) tree addr = fold_build_pointer_plus (DR_BASE_ADDRESS (dr), off); addr = force_gimple_operand_1 (addr, stmts, is_gimple_mem_ref_addr, NULL_TREE); - return fold_build2 (MEM_REF, TREE_TYPE (DR_REF (dr)), - addr, - fold_convert (reference_alias_ptr_type (DR_REF (dr)), - coff)); + tree alias_ptr = fold_convert (reference_alias_ptr_type (DR_REF (dr)), coff); + /* While data-ref analysis punts on bit offsets it still handles + bitfield accesses at byte boundaries. Cope with that. Note that + we cannot simply re-apply the outer COMPONENT_REF because the + byte-granular portion of it is already applied via DR_INIT and + DR_OFFSET, so simply build a BIT_FIELD_REF knowing that the bits + start at offset zero. */ + if (TREE_CODE (DR_REF (dr)) == COMPONENT_REF + && DECL_BIT_FIELD (TREE_OPERAND (DR_REF (dr), 1))) + { + tree field = TREE_OPERAND (DR_REF (dr), 1); + return build3 (BIT_FIELD_REF, TREE_TYPE (DR_REF (dr)), + build2 (MEM_REF, DECL_BIT_FIELD_TYPE (field), + addr, alias_ptr), + DECL_SIZE (field), bitsize_zero_node); + } + else + return fold_build2 (MEM_REF, TREE_TYPE (DR_REF (dr)), addr, alias_ptr); } /* Get the initialization expression for the INDEX-th temporary variable diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c index 4cff16d6846..cd2b34ae6ff 100644 --- a/gcc/tree-ssa-threadedge.c +++ b/gcc/tree-ssa-threadedge.c @@ -1086,9 +1086,7 @@ thread_across_edge (gimple dummy_cond, } else { - for (unsigned int i = 0; i < path->length (); i++) - delete (*path)[i]; - path->release(); + delete_jump_thread_path (path); } } BITMAP_FREE (visited); diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c index 10271919786..24e7767c3b7 100644 --- a/gcc/tree-ssa-threadupdate.c +++ b/gcc/tree-ssa-threadupdate.c @@ -555,9 +555,7 @@ ssa_redirect_edges (struct redirection_data **slot, /* Go ahead and clear E->aux. It's not needed anymore and failure to clear it will cause all kinds of unpleasant problems later. */ - for (unsigned int i = 0; i < path->length (); i++) - delete (*path)[i]; - path->release (); + delete_jump_thread_path (path); e->aux = NULL; } @@ -703,9 +701,7 @@ thread_block_1 (basic_block bb, bool noloop_only, bool joiners) /* Since this case is not handled by our special code to thread through a loop header, we must explicitly cancel the threading request here. */ - for (unsigned int i = 0; i < path->length (); i++) - delete (*path)[i]; - path->release (); + delete_jump_thread_path (path); e->aux = NULL; continue; } @@ -1161,9 +1157,7 @@ thread_through_loop_header (struct loop *loop, bool may_peel_loop_headers) if (e->src->loop_father != e2->dest->loop_father && e2->dest != loop->header) { - for (unsigned int i = 0; i < path->length (); i++) - delete (*path)[i]; - path->release (); + delete_jump_thread_path (path); e->aux = NULL; } } @@ -1213,9 +1207,7 @@ fail: if (path) { - for (unsigned int i = 0; i < path->length (); i++) - delete (*path)[i]; - path->release (); + delete_jump_thread_path (path); e->aux = NULL; } } @@ -1310,9 +1302,7 @@ mark_threaded_blocks (bitmap threaded_blocks) if (e2 && !phi_args_equal_on_edges (e2, final_edge)) { - for (unsigned int i = 0; i < path->length (); i++) - delete (*path)[i]; - path->release (); + delete_jump_thread_path (path); e->aux = NULL; } } @@ -1336,9 +1326,7 @@ mark_threaded_blocks (bitmap threaded_blocks) if (e->aux) { vec<jump_thread_edge *> *path = THREAD_PATH (e); - for (unsigned int i = 0; i < path->length (); i++) - delete (*path)[i]; - path->release (); + delete_jump_thread_path (path); e->aux = NULL; } } @@ -1395,9 +1383,7 @@ mark_threaded_blocks (bitmap threaded_blocks) || (path->last ()->type == EDGE_COPY_SRC_JOINER_BLOCK)) { - for (unsigned int i = 0; i < path->length (); i++) - delete (*path)[i]; - path->release (); + delete_jump_thread_path (path); e->aux = NULL; } break; @@ -1498,9 +1484,7 @@ thread_through_all_blocks (bool may_peel_loop_headers) { vec<jump_thread_edge *> *path = THREAD_PATH (e); - for (unsigned int i = 0; i < path->length (); i++) - delete (*path)[i]; - path->release (); + delete_jump_thread_path (path); e->aux = NULL; } } @@ -1520,6 +1504,17 @@ thread_through_all_blocks (bool may_peel_loop_headers) return retval; } +/* Delete the jump threading path PATH. We have to explcitly delete + each entry in the vector, then the container. */ + +void +delete_jump_thread_path (vec<jump_thread_edge *> *path) +{ + for (unsigned int i = 0; i < path->length (); i++) + delete (*path)[i]; + path->release(); +} + /* Dump a jump threading path, including annotations about each edge in the path. */ @@ -1565,9 +1560,7 @@ register_jump_thread (vec<jump_thread_edge *> *path) { if (!dbg_cnt (registered_jump_thread)) { - for (unsigned int i = 0; i < path->length (); i++) - delete (*path)[i]; - path->release (); + delete_jump_thread_path (path); return; } @@ -1583,9 +1576,7 @@ register_jump_thread (vec<jump_thread_edge *> *path) dump_jump_thread_path (dump_file, *path); } - for (unsigned int i = 0; i < path->length (); i++) - delete (*path)[i]; - path->release (); + delete_jump_thread_path (path); return; } diff --git a/gcc/tree-ssa-threadupdate.h b/gcc/tree-ssa-threadupdate.h index f84c02e9b3c..4617b9c1d3e 100644 --- a/gcc/tree-ssa-threadupdate.h +++ b/gcc/tree-ssa-threadupdate.h @@ -42,4 +42,5 @@ public: }; extern void register_jump_thread (vec <class jump_thread_edge *> *); +extern void delete_jump_thread_path (vec <class jump_thread_edge *> *); #endif diff --git a/libcilkrts/ChangeLog b/libcilkrts/ChangeLog index 024eda57231..7f94aefb65f 100644 --- a/libcilkrts/ChangeLog +++ b/libcilkrts/ChangeLog @@ -1,3 +1,9 @@ +2013-11-08 Balaji V. Iyer <balaji.v.iyer@intel.com> + + PR c/59039 + * runtime/cilk_fiber-unix.cpp: Fixed a crash in run() function + when optimization is turned on. + 2013-11-04 Balaji V. Iyer <balaji.v.iyer@intel.com> PR bootstrap/58951 diff --git a/libcilkrts/runtime/cilk_fiber-unix.cpp b/libcilkrts/runtime/cilk_fiber-unix.cpp index 4895c9c5d71..b0ed53ad052 100644 --- a/libcilkrts/runtime/cilk_fiber-unix.cpp +++ b/libcilkrts/runtime/cilk_fiber-unix.cpp @@ -44,24 +44,27 @@ #include <cstdio> #include <cstdlib> +#include <errno.h> +#include <sys/mman.h> +#include <unistd.h> + +// You'd think that getting a defintion for alloca would be easy. But you'd +// be wrong. Here's a variant on what's recommended in the autoconf doc. I've +// remove the Windows portion since this is Unix-specific code. #if defined HAVE_ALLOCA_H -# include <alloca.h> +# include <alloca.h> #elif defined __GNUC__ -# define alloca __builtin_alloca +# define alloca __builtin_alloca #elif defined _AIX -# define alloca __alloca +# define alloca __alloca #else -# include <stddef.h> -# ifdef __cplusplus +# include <stddef.h> +# ifdef __cplusplus extern "C" -# endif +# endif void *alloca (size_t); #endif -#include <errno.h> -#include <sys/mman.h> -#include <unistd.h> - // MAP_ANON is deprecated on Linux, but seems to be required on Mac... #ifndef MAP_ANONYMOUS #define MAP_ANONYMOUS MAP_ANON @@ -163,8 +166,15 @@ NORETURN cilk_fiber_sysdep::jump_to_resume_other_sysdep(cilk_fiber_sysdep* other __cilkrts_bug("Should not get here"); } -#pragma GCC push_options -#pragma GCC optimize ("-O0") +// GCC doesn't allow us to call __builtin_longjmp in the same function that +// calls __builtin_setjmp, so create a new function to house the call to +// __builtin_longjmp +static void __attribute__((noinline)) +do_cilk_longjmp(__CILK_JUMP_BUFFER jmpbuf) +{ + CILK_LONGJMP(jmpbuf); +} + NORETURN cilk_fiber_sysdep::run() { // Only fibers created from a pool have a proc method to run and execute. @@ -201,7 +211,11 @@ NORETURN cilk_fiber_sysdep::run() // switching to for any temporaries required for this run() // function. JMPBUF_SP(m_resume_jmpbuf) = m_stack_base - frame_size; - CILK_LONGJMP(m_resume_jmpbuf); + + // GCC doesn't allow us to call __builtin_longjmp in the same function + // that calls __builtin_setjmp, so it's been moved into it's own + // function that cannot be inlined. + do_cilk_longjmp(m_resume_jmpbuf); } // Note: our resetting of the stack pointer is valid only if the @@ -228,7 +242,6 @@ NORETURN cilk_fiber_sysdep::run() // User proc should never return. __cilkrts_bug("Should not get here"); } -#pragma GCC pop_options void cilk_fiber_sysdep::make_stack(size_t stack_size) { diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 8a644d74528..0bfba640e21 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,9 +1,16 @@ +2013-11-08 Bernhard Reutner-Fischer <aldot@gcc.gnu.org> + + * configure.ac (libgcc_cv_dfp): Extend check to probe fenv.h + availability. + * configure: Regenerate + 2013-11-07 Uros Bizjak <ubizjak@gmail.com> * config/i386/sfp-exceptions.c (__sfp_handle_exceptions): Handle FP_EX_DENORM. Store result to volatile location after SSE division to close interrupt window. Remove unneeded fwait after x87 division since interrupt window will be closed by emitted fstp. + Rewrite FP_EX_INEXACT handling. 2013-11-06 Joseph Myers <joseph@codesourcery.com> diff --git a/libgcc/config/i386/sfp-exceptions.c b/libgcc/config/i386/sfp-exceptions.c index 6d449ec6093..3504c4aedd1 100644 --- a/libgcc/config/i386/sfp-exceptions.c +++ b/libgcc/config/i386/sfp-exceptions.c @@ -48,7 +48,7 @@ __sfp_handle_exceptions (int _fex) { float f = 0.0f; #ifdef __x86_64__ - volatile float r; + volatile float r __attribute__ ((unused)); asm volatile ("%vdivss\t{%0, %d0|%d0, %0}" : "+x" (f)); r = f; /* Needed to trigger exception. */ #else @@ -68,7 +68,7 @@ __sfp_handle_exceptions (int _fex) { float f = 1.0f, g = 0.0f; #ifdef __x86_64__ - volatile float r; + volatile float r __attribute__ ((unused)); asm volatile ("%vdivss\t{%1, %d0|%d0, %1}" : "+x" (f) : "xm" (g)); r = f; /* Needed to trigger exception. */ #else @@ -94,11 +94,15 @@ __sfp_handle_exceptions (int _fex) } if (_fex & FP_EX_INEXACT) { - struct fenv temp; - asm volatile ("fnstenv\t%0" : "=m" (temp)); - temp.__status_word |= FP_EX_INEXACT; - asm volatile ("fldenv\t%0" : : "m" (temp)); - asm volatile ("fwait"); + float f = 1.0f, g = 3.0f; +#ifdef __x86_64__ + volatile float r __attribute__ ((unused)); + asm volatile ("%vdivss\t{%1, %d0|%d0, %1}" : "+x" (f) : "xm" (g)); + r = f; /* Needed to trigger exception. */ +#else + asm volatile ("fdivs\t%1" : "+t" (f) : "m" (g)); + /* No need for fwait, exception is triggered by emitted fstp. */ +#endif } }; #endif diff --git a/libgcc/configure b/libgcc/configure index 29fa46f597a..2bb1fb2d94f 100644 --- a/libgcc/configure +++ b/libgcc/configure @@ -4066,7 +4066,20 @@ if test "${libgcc_cv_dfp+set}" = set; then : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ + +#include <fenv.h> + +int +main () +{ + _Decimal32 x; +int fe_except = + FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW|FE_UNDERFLOW|FE_INEXACT; + + ; + return 0; +} _ACEOF if ac_fn_c_try_compile "$LINENO"; then : libgcc_cv_dfp=yes diff --git a/libgcc/configure.ac b/libgcc/configure.ac index 186cd6e9cd7..560e988e048 100644 --- a/libgcc/configure.ac +++ b/libgcc/configure.ac @@ -182,7 +182,14 @@ AC_SUBST(long_double_type_size) # Check for decimal float support. AC_CACHE_CHECK([whether decimal floating point is supported], [libgcc_cv_dfp], - [AC_COMPILE_IFELSE([_Decimal32 x;], [libgcc_cv_dfp=yes], + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include <fenv.h> +]], [[ +_Decimal32 x; +int fe_except = + FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW|FE_UNDERFLOW|FE_INEXACT; +]])], + [libgcc_cv_dfp=yes], [libgcc_cv_dfp=no])]) decimal_float=$libgcc_cv_dfp AC_SUBST(decimal_float) diff --git a/libgo/runtime/mheap.c b/libgo/runtime/mheap.c index 1b6cfd3dcde..62070f37943 100644 --- a/libgo/runtime/mheap.c +++ b/libgo/runtime/mheap.c @@ -68,6 +68,7 @@ runtime_MHeap_Init(MHeap *h) void runtime_MHeap_MapSpans(MHeap *h) { + uintptr pagesize; uintptr n; // Map spans array, PageSize at a time. @@ -76,6 +77,8 @@ runtime_MHeap_MapSpans(MHeap *h) n -= (uintptr)h->arena_start; n = n / PageSize * sizeof(h->spans[0]); n = ROUND(n, PageSize); + pagesize = getpagesize(); + n = ROUND(n, pagesize); if(h->spans_mapped >= n) return; runtime_SysMap((byte*)h->spans + h->spans_mapped, n - h->spans_mapped, &mstats.other_sys); diff --git a/libgo/runtime/proc.c b/libgo/runtime/proc.c index ab7cde43863..7011f14f8a5 100644 --- a/libgo/runtime/proc.c +++ b/libgo/runtime/proc.c @@ -2098,7 +2098,7 @@ runtime_malg(int32 stacksize, byte** ret_stack, size_t* ret_stacksize) __splitstack_block_signals_context(&newg->stack_context[0], &dont_block_signals, nil); #else - *ret_stack = runtime_mallocgc(stacksize, FlagNoProfiling|FlagNoGC, 0, 0); + *ret_stack = runtime_mallocgc(stacksize, 0, FlagNoProfiling|FlagNoGC); *ret_stacksize = stacksize; newg->gcinitial_sp = *ret_stack; newg->gcstack_size = stacksize; diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 964717d05a3..53ac56cf941 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -7,6 +7,63 @@ * include/std/atomic (struct atomic): Add __attribute__((atomic)) to member data element. +2013-11-08 François Dumont <fdumont@gcc.gnu.org> + + * include/debug/safe_iterator.h (_BeforeBeginHelper<>::_S_Is): + Take only a const safe iterator reference. + (_BeforeBeginHelper<>::_S_Is_beginnest): Likewise. + (__get_distance): Take only one type of iterator. + (_Safe_iterator<>::_M_valid_range<>): Not template anymore. + (_Safe_iterator<>::_M_get_sequence()): Return pointer to const + sequence from a const_iterator and a pointer to sequence from an + iterator. + * include/debug/safe_iterator.tcc: Adapt. + * include/debug/safe_local_iterator.h + (_Safe_local_iterator<>::_M_valid_range<>): Not template anymore. + (_Safe_local_iterator<>::_M_get_sequence()): Return pointer to + const sequence from a const_iterator and a pointer to sequence + from an iterator. + * include/debug/safe_local_iterator.tcc: Adapt. + * include/debug/forward_list + (_BeforeBeginHelper<std::__debug::forward_list<>>): Adapt. + +2013-11-08 Jonathan Wakely <jwakely.gcc@gmail.com> + + * include/bits/regex_automaton.h (__detail::_State): Split + non-dependent parts into new _State_base. + (__detail::_NFA): Likewise for _NFA_base. Use std::move() to avoid + copies when inserting _MatcherT and _StateT objects. + * include/bits/regex_automaton.tcc: Move member definitions to base + class. Qualify dependent names. + * include/bits/regex_compiler.h (__detail::_Compiler::_M_get_nfa): Make + non-const and use std::move to avoid copying. + * include/bits/regex_compiler.tcc: Likewise. + * include/bits/regex_executor.h (__detail::_Executor::_M_is_word): Use + array, so past-the-end iterator is valid. + + * include/bits/regex_automaton.h (__detail::_State, __detail::_NFA, + __detail::_StateSeq): Remove redundant _CharT template parameters. + * include/bits/regex_automaton.tcc: Likewise. + * include/bits/regex_compiler.h (__detail::_Compiler): Likewise. + (__compile_nfa): Add object generator for _Compiler. + * include/bits/regex_compiler.tcc: Remove _CharT template parameters. + * include/bits/regex_executor.h: Likewise. + * include/bits/regex_executor.tcc: Likewise. + * include/bits/regex.h (basic_regex): Assert char_type matches. Use + __compile_nfa object generator. Remove _CharT template parameter. + + * include/bits/regex_compiler.h (__detail::_AnyMatcher, + __detail::_CharMatcher, __detail::_BracketMatcher): Remove redundant + _CharT template parameters. + * include/bits/regex_compiler.tcc: Likewise. + + * include/bits/regex_compiler.h (__detail::__compile_nfa): Overload + so that std::basic_string<C> and std::vector<C> iterators dispatch to + the const C* compiler. + + * include/bits/regex_compiler.h (__detail::__has_contiguous_iter): + vector<bool> storage is not contiguous. + 2013-11-06 Jonathan Wakely <jwakely.gcc@gmail.com> * include/bits/regex_automaton.h (_S_opcode_word_boundry): Rename to diff --git a/libstdc++-v3/include/bits/regex.h b/libstdc++-v3/include/bits/regex.h index b1bda462be1..84b8cf1dd4f 100644 --- a/libstdc++-v3/include/bits/regex.h +++ b/libstdc++-v3/include/bits/regex.h @@ -377,10 +377,13 @@ _GLIBCXX_END_NAMESPACE_VERSION * Storage for the regular expression is allocated and deallocated as * necessary by the member functions of this class. */ - template<typename _Ch_type, typename _Rx_traits = regex_traits<_Ch_type> > + template<typename _Ch_type, typename _Rx_traits = regex_traits<_Ch_type>> class basic_regex { public: + static_assert(is_same<_Ch_type, typename _Rx_traits::char_type>::value, + "regex traits class must have the same char_type"); + // types: typedef _Ch_type value_type; typedef _Rx_traits traits_type; @@ -498,8 +501,8 @@ _GLIBCXX_END_NAMESPACE_VERSION basic_regex(_FwdIter __first, _FwdIter __last, flag_type __f = ECMAScript) : _M_flags(__f), - _M_automaton(__detail::_Compiler<_FwdIter, _Ch_type, _Rx_traits> - (__first, __last, _M_traits, _M_flags)._M_get_nfa()) + _M_automaton(__detail::__compile_nfa(__first, __last, _M_traits, + _M_flags)) { } /** @@ -634,9 +637,8 @@ _GLIBCXX_END_NAMESPACE_VERSION flag_type __flags = ECMAScript) { _M_flags = __flags; - _M_automaton = - __detail::_Compiler<decltype(__s.begin()), _Ch_type, _Rx_traits> - (__s.begin(), __s.end(), _M_traits, _M_flags)._M_get_nfa(); + _M_automaton = __detail::__compile_nfa(__s.begin(), __s.end(), + _M_traits, _M_flags); return *this; } @@ -730,8 +732,7 @@ _GLIBCXX_END_NAMESPACE_VERSION #endif protected: - typedef std::shared_ptr<__detail::_NFA<_Ch_type, _Rx_traits>> - _AutomatonPtr; + typedef std::shared_ptr<__detail::_NFA<_Rx_traits>> _AutomatonPtr; template<typename _Bp, typename _Ap, typename _Cp, typename _Rp, __detail::_RegexExecutorPolicy, bool> diff --git a/libstdc++-v3/include/bits/regex_automaton.h b/libstdc++-v3/include/bits/regex_automaton.h index e6305123703..1be51221ecd 100644 --- a/libstdc++-v3/include/bits/regex_automaton.h +++ b/libstdc++-v3/include/bits/regex_automaton.h @@ -65,81 +65,114 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _S_opcode_accept, }; - template<typename _CharT, typename _TraitsT> - class _State + struct _State_base + { + _Opcode _M_opcode; // type of outgoing transition + _StateIdT _M_next; // outgoing transition + union // Since they are mutually exclusive. { - public: - typedef _Matcher<_CharT> _MatcherT; - - _Opcode _M_opcode; // type of outgoing transition - _StateIdT _M_next; // outgoing transition - union // Since they are mutually exclusive. + size_t _M_subexpr; // for _S_opcode_subexpr_* + size_t _M_backref_index; // for _S_opcode_backref + struct { - size_t _M_subexpr; // for _S_opcode_subexpr_* - size_t _M_backref_index; // for _S_opcode_backref - struct - { - // for _S_opcode_alternative. - _StateIdT _M_quant_index; - // for _S_opcode_alternative or _S_opcode_subexpr_lookahead - _StateIdT _M_alt; - // for _S_opcode_word_boundary or _S_opcode_subexpr_lookahead or - // quantifiers(ungreedy if set true) - bool _M_neg; - }; + // for _S_opcode_alternative. + _StateIdT _M_quant_index; + // for _S_opcode_alternative or _S_opcode_subexpr_lookahead + _StateIdT _M_alt; + // for _S_opcode_word_boundary or _S_opcode_subexpr_lookahead or + // quantifiers (ungreedy if set true) + bool _M_neg; }; - _MatcherT _M_matches; // for _S_opcode_match + }; - explicit _State(_Opcode __opcode) - : _M_opcode(__opcode), _M_next(_S_invalid_state_id) - { } + explicit _State_base(_Opcode __opcode) + : _M_opcode(__opcode), _M_next(_S_invalid_state_id) + { } + protected: + ~_State_base() = default; + + public: #ifdef _GLIBCXX_DEBUG - std::ostream& - _M_print(std::ostream& ostr) const; + std::ostream& + _M_print(std::ostream& ostr) const; - // Prints graphviz dot commands for state. - std::ostream& - _M_dot(std::ostream& __ostr, _StateIdT __id) const; + // Prints graphviz dot commands for state. + std::ostream& + _M_dot(std::ostream& __ostr, _StateIdT __id) const; #endif - }; + }; - template<typename _CharT, typename _TraitsT> - class _NFA - : public std::vector<_State<_CharT, _TraitsT>> + template<typename _TraitsT> + struct _State : _State_base { - public: - typedef _State<_CharT, _TraitsT> _StateT; - typedef const _Matcher<_CharT>& _MatcherT; - typedef size_t _SizeT; - typedef regex_constants::syntax_option_type _FlagT; - - _NFA(_FlagT __f) - : _M_flags(__f), _M_start_state(0), _M_subexpr_count(0), - _M_quant_count(0), _M_has_backref(false) - { } + typedef _Matcher<typename _TraitsT::char_type> _MatcherT; - _FlagT - _M_options() const - { return _M_flags; } + _MatcherT _M_matches; // for _S_opcode_match - _StateIdT - _M_start() const - { return _M_start_state; } + explicit _State(_Opcode __opcode) : _State_base(__opcode) { } + }; - const _StateSet& - _M_final_states() const - { return _M_accepting_states; } + struct _NFA_base + { + typedef size_t _SizeT; + typedef regex_constants::syntax_option_type _FlagT; + + explicit + _NFA_base(_FlagT __f) + : _M_flags(__f), _M_start_state(0), _M_subexpr_count(0), + _M_quant_count(0), _M_has_backref(false) + { } + + _NFA_base(_NFA_base&&) = default; + + protected: + ~_NFA_base() = default; + + public: + _FlagT + _M_options() const + { return _M_flags; } + + _StateIdT + _M_start() const + { return _M_start_state; } + + const _StateSet& + _M_final_states() const + { return _M_accepting_states; } + + _SizeT + _M_sub_count() const + { return _M_subexpr_count; } + + std::vector<size_t> _M_paren_stack; + _StateSet _M_accepting_states; + _FlagT _M_flags; + _StateIdT _M_start_state; + _SizeT _M_subexpr_count; + _SizeT _M_quant_count; + bool _M_has_backref; + }; + + template<typename _TraitsT> + struct _NFA + : _NFA_base, std::vector<_State<_TraitsT>> + { + typedef _State<_TraitsT> _StateT; + typedef _Matcher<typename _TraitsT::char_type> _MatcherT; - _SizeT - _M_sub_count() const - { return _M_subexpr_count; } + using _NFA_base::_NFA_base; + + // for performance reasons _NFA objects should only be moved not copied + _NFA(const _NFA&) = delete; + _NFA(_NFA&&) = default; _StateIdT _M_insert_accept() { auto __ret = _M_insert_state(_StateT(_S_opcode_accept)); - _M_accepting_states.insert(__ret); + this->_M_accepting_states.insert(__ret); return __ret; } @@ -149,38 +182,38 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _StateT __tmp(_S_opcode_alternative); // It labels every quantifier to make greedy comparison easier in BFS // approach. - __tmp._M_quant_index = _M_quant_count++; + __tmp._M_quant_index = this->_M_quant_count++; __tmp._M_next = __next; __tmp._M_alt = __alt; __tmp._M_neg = __neg; - return _M_insert_state(__tmp); + return _M_insert_state(std::move(__tmp)); } _StateIdT _M_insert_matcher(_MatcherT __m) { _StateT __tmp(_S_opcode_match); - __tmp._M_matches = __m; - return _M_insert_state(__tmp); + __tmp._M_matches = std::move(__m); + return _M_insert_state(std::move(__tmp)); } _StateIdT _M_insert_subexpr_begin() { - auto __id = _M_subexpr_count++; - _M_paren_stack.push_back(__id); + auto __id = this->_M_subexpr_count++; + this->_M_paren_stack.push_back(__id); _StateT __tmp(_S_opcode_subexpr_begin); __tmp._M_subexpr = __id; - return _M_insert_state(__tmp); + return _M_insert_state(std::move(__tmp)); } _StateIdT _M_insert_subexpr_end() { _StateT __tmp(_S_opcode_subexpr_end); - __tmp._M_subexpr = _M_paren_stack.back(); - _M_paren_stack.pop_back(); - return _M_insert_state(__tmp); + __tmp._M_subexpr = this->_M_paren_stack.back(); + this->_M_paren_stack.pop_back(); + return _M_insert_state(std::move(__tmp)); } _StateIdT @@ -199,7 +232,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { _StateT __tmp(_S_opcode_word_boundary); __tmp._M_neg = __neg; - return _M_insert_state(__tmp); + return _M_insert_state(std::move(__tmp)); } _StateIdT @@ -208,7 +241,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _StateT __tmp(_S_opcode_subexpr_lookahead); __tmp._M_alt = __alt; __tmp._M_neg = __neg; - return _M_insert_state(__tmp); + return _M_insert_state(std::move(__tmp)); } _StateIdT @@ -218,7 +251,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _StateIdT _M_insert_state(_StateT __s) { - this->push_back(__s); + this->push_back(std::move(__s)); return this->size()-1; } @@ -230,28 +263,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::ostream& _M_dot(std::ostream& __ostr) const; #endif - - std::vector<size_t> _M_paren_stack; - _StateSet _M_accepting_states; - _FlagT _M_flags; - _StateIdT _M_start_state; - _SizeT _M_subexpr_count; - _SizeT _M_quant_count; - bool _M_has_backref; }; /// Describes a sequence of one or more %_State, its current start /// and end(s). This structure contains fragments of an NFA during /// construction. - template<typename _CharT, typename _TraitsT> + template<typename _TraitsT> class _StateSeq { public: - typedef _NFA<_CharT, _TraitsT> _RegexT; + typedef _NFA<_TraitsT> _RegexT; public: _StateSeq(_RegexT& __nfa, _StateIdT __s) - : _StateSeq(__nfa, __s, __s) + : _M_nfa(__nfa), _M_start(__s), _M_end(__s) { } _StateSeq(_RegexT& __nfa, _StateIdT __s, _StateIdT __end) diff --git a/libstdc++-v3/include/bits/regex_automaton.tcc b/libstdc++-v3/include/bits/regex_automaton.tcc index 258d22de2da..b0734cf2988 100644 --- a/libstdc++-v3/include/bits/regex_automaton.tcc +++ b/libstdc++-v3/include/bits/regex_automaton.tcc @@ -35,118 +35,116 @@ namespace __detail _GLIBCXX_BEGIN_NAMESPACE_VERSION #ifdef _GLIBCXX_DEBUG - template<typename _CharT, typename _TraitsT> - std::ostream& _State<_CharT, _TraitsT>:: - _M_print(std::ostream& ostr) const + std::ostream& + _State_base::_M_print(std::ostream& ostr) const + { + switch (_M_opcode) { - switch (_M_opcode) - { - case _S_opcode_alternative: - ostr << "alt next=" << _M_next << " alt=" << _M_alt; - break; - case _S_opcode_subexpr_begin: - ostr << "subexpr begin next=" << _M_next << " index=" << _M_subexpr; - break; - case _S_opcode_subexpr_end: - ostr << "subexpr end next=" << _M_next << " index=" << _M_subexpr; - break; - case _S_opcode_backref: - ostr << "backref next=" << _M_next << " index=" << _M_backref_index; - break; - case _S_opcode_match: - ostr << "match next=" << _M_next; - break; - case _S_opcode_accept: - ostr << "accept next=" << _M_next; - break; - default: - ostr << "unknown next=" << _M_next; - break; - } - return ostr; + case _S_opcode_alternative: + ostr << "alt next=" << _M_next << " alt=" << _M_alt; + break; + case _S_opcode_subexpr_begin: + ostr << "subexpr begin next=" << _M_next << " index=" << _M_subexpr; + break; + case _S_opcode_subexpr_end: + ostr << "subexpr end next=" << _M_next << " index=" << _M_subexpr; + break; + case _S_opcode_backref: + ostr << "backref next=" << _M_next << " index=" << _M_backref_index; + break; + case _S_opcode_match: + ostr << "match next=" << _M_next; + break; + case _S_opcode_accept: + ostr << "accept next=" << _M_next; + break; + default: + ostr << "unknown next=" << _M_next; + break; } + return ostr; + } // Prints graphviz dot commands for state. - template<typename _CharT, typename _TraitsT> - std::ostream& _State<_CharT, _TraitsT>:: - _M_dot(std::ostream& __ostr, _StateIdT __id) const + std::ostream& + _State_base::_M_dot(std::ostream& __ostr, _StateIdT __id) const + { + switch (_M_opcode) { - switch (_M_opcode) - { - case _S_opcode_alternative: - __ostr << __id << " [label=\"" << __id << "\\nALT\"];\n" - << __id << " -> " << _M_next - << " [label=\"epsilon\", tailport=\"s\"];\n" - << __id << " -> " << _M_alt - << " [label=\"epsilon\", tailport=\"n\"];\n"; - break; - case _S_opcode_backref: - __ostr << __id << " [label=\"" << __id << "\\nBACKREF " - << _M_subexpr << "\"];\n" - << __id << " -> " << _M_next << " [label=\"<match>\"];\n"; - break; - case _S_opcode_line_begin_assertion: - __ostr << __id << " [label=\"" << __id << "\\nLINE_BEGIN \"];\n" - << __id << " -> " << _M_next << " [label=\"epsilon\"];\n"; - break; - case _S_opcode_line_end_assertion: - __ostr << __id << " [label=\"" << __id << "\\nLINE_END \"];\n" - << __id << " -> " << _M_next << " [label=\"epsilon\"];\n"; - break; - case _S_opcode_word_boundary: - __ostr << __id << " [label=\"" << __id << "\\nWORD_BOUNDRY " - << _M_neg << "\"];\n" - << __id << " -> " << _M_next << " [label=\"epsilon\"];\n"; - break; - case _S_opcode_subexpr_lookahead: - __ostr << __id << " [label=\"" << __id << "\\nLOOK_AHEAD\"];\n" - << __id << " -> " << _M_next - << " [label=\"epsilon\", tailport=\"s\"];\n" - << __id << " -> " << _M_alt - << " [label=\"<assert>\", tailport=\"n\"];\n"; - break; - case _S_opcode_subexpr_begin: - __ostr << __id << " [label=\"" << __id << "\\nSBEGIN " - << _M_subexpr << "\"];\n" - << __id << " -> " << _M_next << " [label=\"epsilon\"];\n"; - break; - case _S_opcode_subexpr_end: - __ostr << __id << " [label=\"" << __id << "\\nSEND " - << _M_subexpr << "\"];\n" - << __id << " -> " << _M_next << " [label=\"epsilon\"];\n"; - break; - case _S_opcode_dummy: - break; - case _S_opcode_match: - __ostr << __id << " [label=\"" << __id << "\\nMATCH\"];\n" - << __id << " -> " << _M_next << " [label=\"<match>\"];\n"; - break; - case _S_opcode_accept: - __ostr << __id << " [label=\"" << __id << "\\nACC\"];\n" ; - break; - default: - _GLIBCXX_DEBUG_ASSERT(false); - break; - } - return __ostr; + case _S_opcode_alternative: + __ostr << __id << " [label=\"" << __id << "\\nALT\"];\n" + << __id << " -> " << _M_next + << " [label=\"epsilon\", tailport=\"s\"];\n" + << __id << " -> " << _M_alt + << " [label=\"epsilon\", tailport=\"n\"];\n"; + break; + case _S_opcode_backref: + __ostr << __id << " [label=\"" << __id << "\\nBACKREF " + << _M_subexpr << "\"];\n" + << __id << " -> " << _M_next << " [label=\"<match>\"];\n"; + break; + case _S_opcode_line_begin_assertion: + __ostr << __id << " [label=\"" << __id << "\\nLINE_BEGIN \"];\n" + << __id << " -> " << _M_next << " [label=\"epsilon\"];\n"; + break; + case _S_opcode_line_end_assertion: + __ostr << __id << " [label=\"" << __id << "\\nLINE_END \"];\n" + << __id << " -> " << _M_next << " [label=\"epsilon\"];\n"; + break; + case _S_opcode_word_boundary: + __ostr << __id << " [label=\"" << __id << "\\nWORD_BOUNDRY " + << _M_neg << "\"];\n" + << __id << " -> " << _M_next << " [label=\"epsilon\"];\n"; + break; + case _S_opcode_subexpr_lookahead: + __ostr << __id << " [label=\"" << __id << "\\nLOOK_AHEAD\"];\n" + << __id << " -> " << _M_next + << " [label=\"epsilon\", tailport=\"s\"];\n" + << __id << " -> " << _M_alt + << " [label=\"<assert>\", tailport=\"n\"];\n"; + break; + case _S_opcode_subexpr_begin: + __ostr << __id << " [label=\"" << __id << "\\nSBEGIN " + << _M_subexpr << "\"];\n" + << __id << " -> " << _M_next << " [label=\"epsilon\"];\n"; + break; + case _S_opcode_subexpr_end: + __ostr << __id << " [label=\"" << __id << "\\nSEND " + << _M_subexpr << "\"];\n" + << __id << " -> " << _M_next << " [label=\"epsilon\"];\n"; + break; + case _S_opcode_dummy: + break; + case _S_opcode_match: + __ostr << __id << " [label=\"" << __id << "\\nMATCH\"];\n" + << __id << " -> " << _M_next << " [label=\"<match>\"];\n"; + break; + case _S_opcode_accept: + __ostr << __id << " [label=\"" << __id << "\\nACC\"];\n" ; + break; + default: + _GLIBCXX_DEBUG_ASSERT(false); + break; } + return __ostr; + } - template<typename _CharT, typename _TraitsT> - std::ostream& _NFA<_CharT, _TraitsT>:: - _M_dot(std::ostream& __ostr) const + template<typename _TraitsT> + std::ostream& + _NFA<_TraitsT>::_M_dot(std::ostream& __ostr) const { __ostr << "digraph _Nfa {\n" - << " rankdir=LR;\n"; + " rankdir=LR;\n"; for (size_t __i = 0; __i < this->size(); ++__i) - { this->at(__i)._M_dot(__ostr, __i); } + (*this)[__i]._M_dot(__ostr, __i); __ostr << "}\n"; return __ostr; } #endif - template<typename _CharT, typename _TraitsT> - _StateIdT _NFA<_CharT, _TraitsT>:: - _M_insert_backref(size_t __index) + template<typename _TraitsT> + _StateIdT + _NFA<_TraitsT>::_M_insert_backref(size_t __index) { // To figure out whether a backref is valid, a stack is used to store // unfinished sub-expressions. For example, when parsing @@ -157,18 +155,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // time, "\\2" is valid, but "\\1" and "\\3" are not. if (__index >= _M_subexpr_count) __throw_regex_error(regex_constants::error_backref); - for (auto __it : _M_paren_stack) + for (auto __it : this->_M_paren_stack) if (__index == __it) __throw_regex_error(regex_constants::error_backref); - _M_has_backref = true; + this->_M_has_backref = true; _StateT __tmp(_S_opcode_backref); __tmp._M_backref_index = __index; - return _M_insert_state(__tmp); + return _M_insert_state(std::move(__tmp)); } - template<typename _CharT, typename _TraitsT> - void _NFA<_CharT, _TraitsT>:: - _M_eliminate_dummy() + template<typename _TraitsT> + void + _NFA<_TraitsT>::_M_eliminate_dummy() { for (auto& __it : *this) { @@ -184,9 +182,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } // Just apply DFS on the sequence and re-link their links. - template<typename _CharT, typename _TraitsT> - _StateSeq<_CharT, _TraitsT> _StateSeq<_CharT, _TraitsT>:: - _M_clone() + template<typename _TraitsT> + _StateSeq<_TraitsT> + _StateSeq<_TraitsT>::_M_clone() { std::map<_StateIdT, _StateIdT> __m; std::stack<_StateIdT> __stack; diff --git a/libstdc++-v3/include/bits/regex_compiler.h b/libstdc++-v3/include/bits/regex_compiler.h index 7e4e6adafd5..b9f81272bb9 100644 --- a/libstdc++-v3/include/bits/regex_compiler.h +++ b/libstdc++-v3/include/bits/regex_compiler.h @@ -39,32 +39,32 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @{ */ - template<typename _CharT, typename _TraitsT> + template<typename _TraitsT> struct _BracketMatcher; /// Builds an NFA from an input iterator interval. - template<typename _FwdIter, typename _CharT, typename _TraitsT> + template<typename _FwdIter, typename _TraitsT> class _Compiler { public: typedef typename _TraitsT::string_type _StringT; - typedef _NFA<_CharT, _TraitsT> _RegexT; + typedef _NFA<_TraitsT> _RegexT; typedef regex_constants::syntax_option_type _FlagT; _Compiler(_FwdIter __b, _FwdIter __e, const _TraitsT& __traits, _FlagT __flags); std::shared_ptr<_RegexT> - _M_get_nfa() const - { return make_shared<_RegexT>(_M_nfa); } + _M_get_nfa() + { return make_shared<_RegexT>(std::move(_M_nfa)); } private: typedef _Scanner<_FwdIter> _ScannerT; typedef typename _ScannerT::_TokenT _TokenT; - typedef _StateSeq<_CharT, _TraitsT> _StateSeqT; + typedef _StateSeq<_TraitsT> _StateSeqT; typedef std::stack<_StateSeqT, std::vector<_StateSeqT>> _StackT; - typedef _BracketMatcher<_CharT, _TraitsT> _BMatcherT; - typedef std::ctype<_CharT> _CtypeT; + typedef _BracketMatcher<_TraitsT> _BMatcherT; + typedef std::ctype<typename _TraitsT::char_type> _CtypeT; // accepts a specific token or returns false. bool @@ -129,9 +129,67 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _StackT _M_stack; }; - template<typename _CharT, typename _TraitsT> + template<typename _Tp> + struct __has_contiguous_iter : std::false_type { }; + + template<typename _Ch, typename _Tr, typename _Alloc> + struct __has_contiguous_iter<std::basic_string<_Ch, _Tr, _Alloc>> + : std::true_type // string<Ch> storage is contiguous + { }; + + template<typename _Tp, typename _Alloc> + struct __has_contiguous_iter<std::vector<_Tp, _Alloc>> + : std::true_type // vector<Tp> storage is contiguous + { }; + + template<typename _Alloc> + struct __has_contiguous_iter<std::vector<bool, _Alloc>> + : std::false_type // vector<bool> storage is not contiguous + { }; + + template<typename _Tp> + struct __is_contiguous_normal_iter : std::false_type { }; + + template<typename _Tp, typename _Cont> + struct + __is_contiguous_normal_iter<__gnu_cxx::__normal_iterator<_Tp, _Cont>> + : __has_contiguous_iter<_Cont>::type + { }; + + template<typename _Iter, typename _TraitsT> + using __enable_if_contiguous_normal_iter + = typename enable_if< __is_contiguous_normal_iter<_Iter>::value, + std::shared_ptr<_NFA<_TraitsT>> >::type; + + template<typename _Iter, typename _TraitsT> + using __disable_if_contiguous_normal_iter + = typename enable_if< !__is_contiguous_normal_iter<_Iter>::value, + std::shared_ptr<_NFA<_TraitsT>> >::type; + + template<typename _FwdIter, typename _TraitsT> + inline __disable_if_contiguous_normal_iter<_FwdIter, _TraitsT> + __compile_nfa(_FwdIter __first, _FwdIter __last, const _TraitsT& __traits, + regex_constants::syntax_option_type __flags) + { + using _Cmplr = _Compiler<_FwdIter, _TraitsT>; + return _Cmplr(__first, __last, __traits, __flags)._M_get_nfa(); + } + + template<typename _Iter, typename _TraitsT> + inline __enable_if_contiguous_normal_iter<_Iter, _TraitsT> + __compile_nfa(_Iter __first, _Iter __last, const _TraitsT& __traits, + regex_constants::syntax_option_type __flags) + { + size_t __len = __last - __first; + const auto* __cfirst = __len ? std::__addressof(*__first) : nullptr; + return __compile_nfa(__cfirst, __cfirst + __len, __traits, __flags); + } + + template<typename _TraitsT> struct _AnyMatcher { + typedef typename _TraitsT::char_type _CharT; + explicit _AnyMatcher(const _TraitsT& __traits) : _M_traits(__traits) @@ -149,9 +207,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const _TraitsT& _M_traits; }; - template<typename _CharT, typename _TraitsT> + template<typename _TraitsT> struct _CharMatcher { + typedef typename _TraitsT::char_type _CharT; typedef regex_constants::syntax_option_type _FlagT; explicit @@ -178,9 +237,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION }; /// Matches a character range (bracket expression) - template<typename _CharT, typename _TraitsT> + template<typename _TraitsT> struct _BracketMatcher { + typedef typename _TraitsT::char_type _CharT; typedef typename _TraitsT::char_class_type _CharClassT; typedef typename _TraitsT::string_type _StringT; typedef regex_constants::syntax_option_type _FlagT; diff --git a/libstdc++-v3/include/bits/regex_compiler.tcc b/libstdc++-v3/include/bits/regex_compiler.tcc index e3764b8d82a..f89498f35ed 100644 --- a/libstdc++-v3/include/bits/regex_compiler.tcc +++ b/libstdc++-v3/include/bits/regex_compiler.tcc @@ -59,8 +59,8 @@ namespace __detail { _GLIBCXX_BEGIN_NAMESPACE_VERSION - template<typename _FwdIter, typename _CharT, typename _TraitsT> - _Compiler<_FwdIter, _CharT, _TraitsT>:: + template<typename _FwdIter, typename _TraitsT> + _Compiler<_FwdIter, _TraitsT>:: _Compiler(_FwdIter __b, _FwdIter __e, const _TraitsT& __traits, _FlagT __flags) : _M_flags((__flags @@ -73,7 +73,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ? __flags : __flags | regex_constants::ECMAScript), _M_traits(__traits), - _M_ctype(std::use_facet<std::ctype<_CharT>>(_M_traits.getloc())), + _M_ctype(std::use_facet<_CtypeT>(_M_traits.getloc())), _M_scanner(__b, __e, _M_flags, _M_traits.getloc()), _M_nfa(_M_flags) { @@ -89,9 +89,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_nfa._M_eliminate_dummy(); } - template<typename _FwdIter, typename _CharT, typename _TraitsT> + template<typename _FwdIter, typename _TraitsT> void - _Compiler<_FwdIter, _CharT, _TraitsT>:: + _Compiler<_FwdIter, _TraitsT>:: _M_disjunction() { this->_M_alternative(); @@ -110,9 +110,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } - template<typename _FwdIter, typename _CharT, typename _TraitsT> + template<typename _FwdIter, typename _TraitsT> void - _Compiler<_FwdIter, _CharT, _TraitsT>:: + _Compiler<_FwdIter, _TraitsT>:: _M_alternative() { if (this->_M_term()) @@ -126,9 +126,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_stack.push(_StateSeqT(_M_nfa, _M_nfa._M_insert_dummy())); } - template<typename _FwdIter, typename _CharT, typename _TraitsT> + template<typename _FwdIter, typename _TraitsT> bool - _Compiler<_FwdIter, _CharT, _TraitsT>:: + _Compiler<_FwdIter, _TraitsT>:: _M_term() { if (this->_M_assertion()) @@ -141,17 +141,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return false; } - template<typename _FwdIter, typename _CharT, typename _TraitsT> + template<typename _FwdIter, typename _TraitsT> bool - _Compiler<_FwdIter, _CharT, _TraitsT>:: + _Compiler<_FwdIter, _TraitsT>:: _M_assertion() { if (_M_match_token(_ScannerT::_S_token_line_begin)) - _M_stack.push(_StateSeqT(_M_nfa, _M_nfa. - _M_insert_line_begin())); + _M_stack.push(_StateSeqT(_M_nfa, _M_nfa._M_insert_line_begin())); else if (_M_match_token(_ScannerT::_S_token_line_end)) - _M_stack.push(_StateSeqT(_M_nfa, _M_nfa. - _M_insert_line_end())); + _M_stack.push(_StateSeqT(_M_nfa, _M_nfa._M_insert_line_end())); else if (_M_match_token(_ScannerT::_S_token_word_bound)) // _M_value[0] == 'n' means it's negtive, say "not word boundary". _M_stack.push(_StateSeqT(_M_nfa, _M_nfa. @@ -174,9 +172,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return true; } - template<typename _FwdIter, typename _CharT, typename _TraitsT> + template<typename _FwdIter, typename _TraitsT> void - _Compiler<_FwdIter, _CharT, _TraitsT>:: + _Compiler<_FwdIter, _TraitsT>:: _M_quantifier() { bool __neg = (_M_flags & regex_constants::ECMAScript); @@ -280,19 +278,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } - template<typename _FwdIter, typename _CharT, typename _TraitsT> + template<typename _FwdIter, typename _TraitsT> bool - _Compiler<_FwdIter, _CharT, _TraitsT>:: + _Compiler<_FwdIter, _TraitsT>:: _M_atom() { if (_M_match_token(_ScannerT::_S_token_anychar)) _M_stack.push(_StateSeqT(_M_nfa, _M_nfa._M_insert_matcher - (_AnyMatcher<_CharT, _TraitsT>(_M_traits)))); + (_AnyMatcher<_TraitsT>(_M_traits)))); else if (_M_try_char()) _M_stack.push(_StateSeqT(_M_nfa, _M_nfa._M_insert_matcher - (_CharMatcher<_CharT, _TraitsT>(_M_value[0], + (_CharMatcher<_TraitsT>(_M_value[0], _M_traits, _M_flags)))); else if (_M_match_token(_ScannerT::_S_token_backref)) @@ -305,7 +303,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_traits, _M_flags); __matcher._M_add_character_class(_M_value); _M_stack.push(_StateSeqT(_M_nfa, - _M_nfa._M_insert_matcher(__matcher))); + _M_nfa._M_insert_matcher(std::move(__matcher)))); } else if (_M_match_token(_ScannerT::_S_token_subexpr_no_group_begin)) { @@ -331,9 +329,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return true; } - template<typename _FwdIter, typename _CharT, typename _TraitsT> + template<typename _FwdIter, typename _TraitsT> bool - _Compiler<_FwdIter, _CharT, _TraitsT>:: + _Compiler<_FwdIter, _TraitsT>:: _M_bracket_expression() { bool __neg = @@ -343,13 +341,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _BMatcherT __matcher(__neg, _M_traits, _M_flags); while (!_M_match_token(_ScannerT::_S_token_bracket_end)) _M_expression_term(__matcher); - _M_stack.push(_StateSeqT(_M_nfa, _M_nfa._M_insert_matcher(__matcher))); + _M_stack.push(_StateSeqT(_M_nfa, + _M_nfa._M_insert_matcher(std::move(__matcher)))); return true; } - template<typename _FwdIter, typename _CharT, typename _TraitsT> + template<typename _FwdIter, typename _TraitsT> void - _Compiler<_FwdIter, _CharT, _TraitsT>:: + _Compiler<_FwdIter, _TraitsT>:: _M_expression_term(_BMatcherT& __matcher) { if (_M_match_token(_ScannerT::_S_token_collsymbol)) @@ -384,9 +383,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __throw_regex_error(regex_constants::error_brack); } - template<typename _FwdIter, typename _CharT, typename _TraitsT> + template<typename _FwdIter, typename _TraitsT> bool - _Compiler<_FwdIter, _CharT, _TraitsT>:: + _Compiler<_FwdIter, _TraitsT>:: _M_try_char() { bool __is_char = false; @@ -405,9 +404,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __is_char; } - template<typename _FwdIter, typename _CharT, typename _TraitsT> + template<typename _FwdIter, typename _TraitsT> bool - _Compiler<_FwdIter, _CharT, _TraitsT>:: + _Compiler<_FwdIter, _TraitsT>:: _M_match_token(_TokenT token) { if (token == _M_scanner._M_get_token()) @@ -419,9 +418,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return false; } - template<typename _FwdIter, typename _CharT, typename _TraitsT> + template<typename _FwdIter, typename _TraitsT> int - _Compiler<_FwdIter, _CharT, _TraitsT>:: + _Compiler<_FwdIter, _TraitsT>:: _M_cur_int_value(int __radix) { long __v = 0; @@ -431,9 +430,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __v; } - template<typename _CharT, typename _TraitsT> - bool _BracketMatcher<_CharT, _TraitsT>:: - operator()(_CharT __ch) const + template<typename _TraitsT> + bool + _BracketMatcher<_TraitsT>::operator()(_CharT __ch) const { bool __ret = false; if (_M_traits.isctype(__ch, _M_class_set) diff --git a/libstdc++-v3/include/bits/regex_executor.h b/libstdc++-v3/include/bits/regex_executor.h index 57b3108b4b0..ded77475f6f 100644 --- a/libstdc++-v3/include/bits/regex_executor.h +++ b/libstdc++-v3/include/bits/regex_executor.h @@ -53,7 +53,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ template<typename _BiIter, typename _Alloc, typename _TraitsT, - bool __dfs_mode> + bool __dfs_mode> class _Executor { public: @@ -62,7 +62,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef std::vector<sub_match<_BiIter>, _Alloc> _ResultsVec; typedef regex_constants::match_flag_type _FlagT; typedef typename _TraitsT::char_class_type _ClassT; - typedef _NFA<_CharT, _TraitsT> _NFAT; + typedef _NFA<_TraitsT> _NFAT; public: _Executor(_BiIter __begin, @@ -117,9 +117,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION bool _M_is_word(_CharT __ch) const { - static const _CharT __s = 'w'; + static const _CharT __s[2] = { 'w' }; return _M_re._M_traits.isctype - (__ch, _M_re._M_traits.lookup_classname(&__s, &__s+1)); + (__ch, _M_re._M_traits.lookup_classname(__s, __s+1)); } bool @@ -138,10 +138,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } bool - _M_word_boundary(_State<_CharT, _TraitsT> __state) const; + _M_word_boundary(_State<_TraitsT> __state) const; bool - _M_lookahead(_State<_CharT, _TraitsT> __state); + _M_lookahead(_State<_TraitsT> __state); public: _ResultsVec _M_cur_results; diff --git a/libstdc++-v3/include/bits/regex_executor.tcc b/libstdc++-v3/include/bits/regex_executor.tcc index b310abab60b..22fd67cfa3b 100644 --- a/libstdc++-v3/include/bits/regex_executor.tcc +++ b/libstdc++-v3/include/bits/regex_executor.tcc @@ -143,8 +143,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _BiIter, typename _Alloc, typename _TraitsT, bool __dfs_mode> bool _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>:: - _M_lookahead(_State<_Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>:: - _CharT, _TraitsT> __state) + _M_lookahead(_State<_TraitsT> __state) { _ResultsVec __what(_M_cur_results.size()); auto __sub = std::unique_ptr<_Executor>(new _Executor(_M_current, @@ -348,7 +347,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _BiIter, typename _Alloc, typename _TraitsT, bool __dfs_mode> bool _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>:: - _M_word_boundary(_State<_CharT, _TraitsT> __state) const + _M_word_boundary(_State<_TraitsT> __state) const { // By definition. bool __ans = false; diff --git a/libstdc++-v3/include/debug/forward_list b/libstdc++-v3/include/debug/forward_list index 4c8ac371c94..5269f3978d3 100644 --- a/libstdc++-v3/include/debug/forward_list +++ b/libstdc++-v3/include/debug/forward_list @@ -785,23 +785,26 @@ namespace __gnu_debug struct _BeforeBeginHelper<std::__debug::forward_list<_Tp, _Alloc> > { typedef std::__debug::forward_list<_Tp, _Alloc> _Sequence; - typedef typename _Sequence::const_iterator _It; - typedef typename _It::iterator_type _BaseIt; - static bool - _S_Is(_BaseIt __it, const _Sequence* __seq) - { return __it == __seq->_M_base().cbefore_begin(); } + template<typename _Iterator> + static bool + _S_Is(const _Safe_iterator<_Iterator, _Sequence>& __it) + { + return + __it.base() == __it._M_get_sequence()->_M_base().before_begin(); + } - static bool - _S_Is_Beginnest(_BaseIt __it, const _Sequence* __seq) - { return _S_Is(__it, __seq); } + template<typename _Iterator> + static bool + _S_Is_Beginnest(const _Safe_iterator<_Iterator, _Sequence>& __it) + { return _S_Is(__it); } }; #ifndef _GLIBCXX_DEBUG_PEDANTIC template<class _Tp, class _Alloc> struct _Insert_range_from_self_is_safe< std::__debug::forward_list<_Tp, _Alloc> > - { enum { __value = 1 }; }; + { enum { __value = 1 }; }; #endif } diff --git a/libstdc++-v3/include/debug/safe_iterator.h b/libstdc++-v3/include/debug/safe_iterator.h index 9e73bcfd985..59ba602e411 100644 --- a/libstdc++-v3/include/debug/safe_iterator.h +++ b/libstdc++-v3/include/debug/safe_iterator.h @@ -44,16 +44,15 @@ namespace __gnu_debug template <typename _Sequence> struct _BeforeBeginHelper { - typedef typename _Sequence::const_iterator _It; - typedef typename _It::iterator_type _BaseIt; - - static bool - _S_Is(_BaseIt, const _Sequence*) - { return false; } - - static bool - _S_Is_Beginnest(_BaseIt __it, const _Sequence* __seq) - { return __it == __seq->_M_base().begin(); } + template<typename _Iterator> + static bool + _S_Is(const _Safe_iterator<_Iterator, _Sequence>&) + { return false; } + + template<typename _Iterator> + static bool + _S_Is_Beginnest(const _Safe_iterator<_Iterator, _Sequence>& __it) + { return __it.base() == __it._M_get_sequence()->_M_base().begin(); } }; /** Iterators that derive from _Safe_iterator_base can be determined singular @@ -76,26 +75,26 @@ namespace __gnu_debug /** Determine the distance between two iterators with some known * precision. */ - template<typename _Iterator1, typename _Iterator2> - inline std::pair<typename std::iterator_traits<_Iterator1>::difference_type, + template<typename _Iterator> + inline std::pair<typename std::iterator_traits<_Iterator>::difference_type, _Distance_precision> - __get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs, + __get_distance(const _Iterator& __lhs, const _Iterator& __rhs, std::random_access_iterator_tag) { return std::make_pair(__rhs - __lhs, __dp_exact); } - template<typename _Iterator1, typename _Iterator2> - inline std::pair<typename std::iterator_traits<_Iterator1>::difference_type, + template<typename _Iterator> + inline std::pair<typename std::iterator_traits<_Iterator>::difference_type, _Distance_precision> - __get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs, + __get_distance(const _Iterator& __lhs, const _Iterator& __rhs, std::forward_iterator_tag) { return std::make_pair(__lhs == __rhs? 0 : 1, __dp_equality); } - template<typename _Iterator1, typename _Iterator2> - inline std::pair<typename std::iterator_traits<_Iterator1>::difference_type, + template<typename _Iterator> + inline std::pair<typename std::iterator_traits<_Iterator>::difference_type, _Distance_precision> - __get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs) + __get_distance(const _Iterator& __lhs, const _Iterator& __rhs) { - typedef typename std::iterator_traits<_Iterator1>::iterator_category + typedef typename std::iterator_traits<_Iterator>::iterator_category _Category; return __get_distance(__lhs, __rhs, _Category()); } @@ -115,6 +114,7 @@ namespace __gnu_debug class _Safe_iterator : public _Safe_iterator_base { typedef _Safe_iterator _Self; + typedef typename _Sequence::const_iterator _Const_iterator; /// The underlying iterator _Iterator _M_current; @@ -122,10 +122,7 @@ namespace __gnu_debug /// Determine if this is a constant iterator. bool _M_constant() const - { - typedef typename _Sequence::const_iterator const_iterator; - return std::__are_same<const_iterator, _Safe_iterator>::__value; - } + { return std::__are_same<_Const_iterator, _Safe_iterator>::__value; } typedef std::iterator_traits<_Iterator> _Traits; @@ -445,37 +442,39 @@ namespace __gnu_debug _M_can_advance(const difference_type& __n) const; // Is the iterator range [*this, __rhs) valid? - template<typename _Other> - bool - _M_valid_range(const _Safe_iterator<_Other, _Sequence>& __rhs) const; + bool + _M_valid_range(const _Safe_iterator& __rhs) const; // The sequence this iterator references. - const _Sequence* + typename + __gnu_cxx::__conditional_type<std::__are_same<_Const_iterator, + _Safe_iterator>::__value, + const _Sequence*, + _Sequence*>::__type _M_get_sequence() const - { return static_cast<const _Sequence*>(_M_sequence); } + { return static_cast<_Sequence*>(_M_sequence); } /// Is this iterator equal to the sequence's begin() iterator? - bool _M_is_begin() const + bool + _M_is_begin() const { return base() == _M_get_sequence()->_M_base().begin(); } /// Is this iterator equal to the sequence's end() iterator? - bool _M_is_end() const + bool + _M_is_end() const { return base() == _M_get_sequence()->_M_base().end(); } /// Is this iterator equal to the sequence's before_begin() iterator if /// any? - bool _M_is_before_begin() const - { - return _BeforeBeginHelper<_Sequence>::_S_Is(base(), _M_get_sequence()); - } + bool + _M_is_before_begin() const + { return _BeforeBeginHelper<_Sequence>::_S_Is(*this); } /// Is this iterator equal to the sequence's before_begin() iterator if /// any or begin() otherwise? - bool _M_is_beginnest() const - { - return _BeforeBeginHelper<_Sequence>::_S_Is_Beginnest(base(), - _M_get_sequence()); - } + bool + _M_is_beginnest() const + { return _BeforeBeginHelper<_Sequence>::_S_Is_Beginnest(*this); } }; template<typename _IteratorL, typename _IteratorR, typename _Sequence> diff --git a/libstdc++-v3/include/debug/safe_iterator.tcc b/libstdc++-v3/include/debug/safe_iterator.tcc index daa9c6bfa72..7550a1d96ba 100644 --- a/libstdc++-v3/include/debug/safe_iterator.tcc +++ b/libstdc++-v3/include/debug/safe_iterator.tcc @@ -36,27 +36,22 @@ namespace __gnu_debug _Safe_iterator<_Iterator, _Sequence>:: _M_can_advance(const difference_type& __n) const { - typedef typename _Sequence::const_iterator const_debug_iterator; - typedef typename const_debug_iterator::iterator_type const_iterator; - if (this->_M_singular()) return false; if (__n == 0) return true; if (__n < 0) { - const_iterator __begin = _M_get_sequence()->_M_base().begin(); std::pair<difference_type, _Distance_precision> __dist = - __get_distance(__begin, base()); + __get_distance(_M_get_sequence()->_M_base().begin(), base()); bool __ok = ((__dist.second == __dp_exact && __dist.first >= -__n) || (__dist.second != __dp_exact && __dist.first > 0)); return __ok; } else { - const_iterator __end = _M_get_sequence()->_M_base().end(); std::pair<difference_type, _Distance_precision> __dist = - __get_distance(base(), __end); + __get_distance(base(), _M_get_sequence()->_M_base().end()); bool __ok = ((__dist.second == __dp_exact && __dist.first >= __n) || (__dist.second != __dp_exact && __dist.first > 0)); return __ok; @@ -64,42 +59,41 @@ namespace __gnu_debug } template<typename _Iterator, typename _Sequence> - template<typename _Other> - bool - _Safe_iterator<_Iterator, _Sequence>:: - _M_valid_range(const _Safe_iterator<_Other, _Sequence>& __rhs) const - { - if (!_M_can_compare(__rhs)) - return false; - - /* Determine if we can order the iterators without the help of - the container */ - std::pair<difference_type, _Distance_precision> __dist = - __get_distance(base(), __rhs.base()); - switch (__dist.second) { - case __dp_equality: - if (__dist.first == 0) - return true; - break; - - case __dp_sign: - case __dp_exact: - return __dist.first >= 0; - } + bool + _Safe_iterator<_Iterator, _Sequence>:: + _M_valid_range(const _Safe_iterator& __rhs) const + { + if (!_M_can_compare(__rhs)) + return false; - /* We can only test for equality, but check if one of the - iterators is at an extreme. */ - /* Optim for classic [begin, it) or [it, end) ranges, limit checks - * when code is valid. Note, for the special case of forward_list, - * before_begin replaces the role of begin. */ - if (_M_is_beginnest() || __rhs._M_is_end()) + /* Determine if we can order the iterators without the help of + the container */ + std::pair<difference_type, _Distance_precision> __dist = + __get_distance(base(), __rhs.base()); + switch (__dist.second) { + case __dp_equality: + if (__dist.first == 0) return true; - if (_M_is_end() || __rhs._M_is_beginnest()) - return false; + break; - // Assume that this is a valid range; we can't check anything else - return true; + case __dp_sign: + case __dp_exact: + return __dist.first >= 0; } + + /* We can only test for equality, but check if one of the + iterators is at an extreme. */ + /* Optim for classic [begin, it) or [it, end) ranges, limit checks + * when code is valid. Note, for the special case of forward_list, + * before_begin replaces the role of begin. */ + if (_M_is_beginnest() || __rhs._M_is_end()) + return true; + if (_M_is_end() || __rhs._M_is_beginnest()) + return false; + + // Assume that this is a valid range; we can't check anything else + return true; + } } // namespace __gnu_debug #endif diff --git a/libstdc++-v3/include/debug/safe_local_iterator.h b/libstdc++-v3/include/debug/safe_local_iterator.h index 82975b70722..6724798b377 100644 --- a/libstdc++-v3/include/debug/safe_local_iterator.h +++ b/libstdc++-v3/include/debug/safe_local_iterator.h @@ -52,6 +52,7 @@ namespace __gnu_debug class _Safe_local_iterator : public _Safe_local_iterator_base { typedef _Safe_local_iterator _Self; + typedef typename _Sequence::const_local_iterator _Const_local_iterator; typedef typename _Sequence::size_type size_type; /// The underlying iterator @@ -64,8 +65,8 @@ namespace __gnu_debug bool _M_constant() const { - typedef typename _Sequence::const_local_iterator const_iterator; - return std::__are_same<const_iterator, _Safe_local_iterator>::__value; + return std::__are_same<_Const_local_iterator, + _Safe_local_iterator>::__value; } typedef std::iterator_traits<_Iterator> _Traits; @@ -253,15 +254,17 @@ namespace __gnu_debug { return !this->_M_singular() && !_M_is_end(); } // Is the iterator range [*this, __rhs) valid? - template<typename _Other> - bool - _M_valid_range(const _Safe_local_iterator<_Other, - _Sequence>& __rhs) const; + bool + _M_valid_range(const _Safe_local_iterator& __rhs) const; // The sequence this iterator references. - const _Sequence* + typename + __gnu_cxx::__conditional_type<std::__are_same<_Const_local_iterator, + _Safe_local_iterator>::__value, + const _Sequence*, + _Sequence*>::__type _M_get_sequence() const - { return static_cast<const _Sequence*>(_M_sequence); } + { return static_cast<_Sequence*>(_M_sequence); } /// Is this iterator equal to the sequence's begin() iterator? bool _M_is_begin() const diff --git a/libstdc++-v3/include/debug/safe_local_iterator.tcc b/libstdc++-v3/include/debug/safe_local_iterator.tcc index fac971ec822..6633bdb7794 100644 --- a/libstdc++-v3/include/debug/safe_local_iterator.tcc +++ b/libstdc++-v3/include/debug/safe_local_iterator.tcc @@ -32,21 +32,20 @@ namespace __gnu_debug { template<typename _Iterator, typename _Sequence> - template<typename _Other> - bool - _Safe_local_iterator<_Iterator, _Sequence>:: - _M_valid_range(const _Safe_local_iterator<_Other, _Sequence>& __rhs) const - { - if (!_M_can_compare(__rhs)) - return false; - if (_M_bucket != __rhs._M_bucket) - return false; + bool + _Safe_local_iterator<_Iterator, _Sequence>:: + _M_valid_range(const _Safe_local_iterator& __rhs) const + { + if (!_M_can_compare(__rhs)) + return false; + if (_M_bucket != __rhs._M_bucket) + return false; - /* Determine if we can order the iterators without the help of - the container */ - std::pair<difference_type, _Distance_precision> __dist = - __get_distance(base(), __rhs.base()); - switch (__dist.second) + /* Determine if we can order the iterators without the help of + the container */ + std::pair<difference_type, _Distance_precision> __dist = + __get_distance(base(), __rhs.base()); + switch (__dist.second) { case __dp_equality: if (__dist.first == 0) @@ -58,18 +57,18 @@ namespace __gnu_debug return __dist.first >= 0; } - /* We can only test for equality, but check if one of the - iterators is at an extreme. */ - /* Optim for classic [begin, it) or [it, end) ranges, limit checks - * when code is valid. */ - if (_M_is_begin() || __rhs._M_is_end()) - return true; - if (_M_is_end() || __rhs._M_is_begin()) - return false; - - // Assume that this is a valid range; we can't check anything else + /* We can only test for equality, but check if one of the + iterators is at an extreme. */ + /* Optim for classic [begin, it) or [it, end) ranges, limit checks + * when code is valid. */ + if (_M_is_begin() || __rhs._M_is_end()) return true; - } + if (_M_is_end() || __rhs._M_is_begin()) + return false; + + // Assume that this is a valid range; we can't check anything else + return true; + } } // namespace __gnu_debug #endif |