From 6388aef0689d4d555a5f38fbc2e9ff276af7100e Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Thu, 7 Nov 2013 21:53:54 +0000 Subject: * config/i386/sfp-exceptions.c (__sfp_handle_exceptions): Rewrite FP_EX_INEXACT handling. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@204546 138bc75d-0d04-0410-961f-82ee72b054a4 --- libgcc/ChangeLog | 1 + libgcc/config/i386/sfp-exceptions.c | 18 +++++++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 8a644d74528..1b2a20b75bf 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -4,6 +4,7 @@ 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 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 -- cgit v1.2.3 From c63ab1c7edded562fda972f090f15bae891f4bbd Mon Sep 17 00:00:00 2001 From: Janus Weil Date: Thu, 7 Nov 2013 22:39:15 +0000 Subject: 2013-11-07 Janus Weil PR fortran/58471 * primary.c (gfc_expr_attr): Check for result symbol. 2013-11-07 Janus Weil PR fortran/58471 * gfortran.dg/constructor_9.f90: New. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@204547 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/fortran/ChangeLog | 5 +++++ gcc/fortran/primary.c | 2 +- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gfortran.dg/constructor_9.f90 | 22 ++++++++++++++++++++++ 4 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gfortran.dg/constructor_9.f90 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 + + PR fortran/58471 + * primary.c (gfc_expr_attr): Check for result symbol. + 2013-11-06 Francois-Xavier Coudert * 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/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0e850816bfa..e83d64e4dbd 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-11-07 Janus Weil + + PR fortran/58471 + * gfortran.dg/constructor_9.f90: New. + 2013-11-07 Joseph Myers * gcc.dg/atomic-compare-exchange-1.c, 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 + +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" } } -- cgit v1.2.3 From db880971c054f7f12eb6138f8bc490e741589e13 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 7 Nov 2013 23:38:47 +0000 Subject: runtime: Fixes for Alpha. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@204551 138bc75d-0d04-0410-961f-82ee72b054a4 --- libgo/runtime/mheap.c | 3 +++ libgo/runtime/proc.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) 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; -- cgit v1.2.3 From 0c95f650d778b7c8cc6755afb419de1a43f9c5e0 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Fri, 8 Nov 2013 00:16:23 +0000 Subject: Daily bump. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@204554 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/DATESTAMP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 2042aaf99a1..30b0820adcf 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20131107 +20131108 -- cgit v1.2.3 From c2f1c3c6168b9b3fb4759d7ac8cfae821a1cf671 Mon Sep 17 00:00:00 2001 From: Tom de Vries Date: Fri, 8 Nov 2013 00:38:08 +0000 Subject: Remove duplicate contents in gcc/config/rs6000/t-xilinx 2013-11-08 Tom de Vries * config/rs6000/t-xilinx: Remove duplicate contents. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@204555 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 4 ++++ gcc/config/rs6000/t-xilinx | 28 ---------------------------- 2 files changed, 4 insertions(+), 28 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 23cf4eca02b..bd4715e2c42 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2013-11-08 Tom de Vries + + * config/rs6000/t-xilinx: Remove duplicate contents. + 2013-11-07 Andrew MacLeod Joseph Myers 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 -# . - -# 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 - -- cgit v1.2.3 From 0c2226dbf899f7abb1744c961334cfd7f46c762c Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 8 Nov 2013 05:46:22 +0000 Subject: compiler: Correct types when type conversion makes backend call. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@204559 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/go/gofrontend/expressions.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index c4d32686178..7269f5849f5 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() -- cgit v1.2.3 From a1bddb5c1c0da2366a936d70c73ed537feaae823 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 8 Nov 2013 08:44:02 +0000 Subject: 2013-11-08 Richard Biener PR tree-optimization/59038 PR tree-optimization/58955 * tree-loop-distribution.c (pg_add_dependence_edges): Revert previous change. Handle known dependences correctly. * gcc.dg/torture/pr59038.c: New testcase. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@204561 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 7 +++++++ gcc/testsuite/gcc.dg/torture/pr59038.c | 25 +++++++++++++++++++++++++ gcc/tree-loop-distribution.c | 13 +++++++++++-- 3 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr59038.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bd4715e2c42..171032f7a72 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2013-11-08 Richard Biener + + 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 * config/rs6000/t-xilinx: Remove duplicate contents. 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/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 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 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; -- cgit v1.2.3 From f93a1fa4d353af770f1c7a039e2124db1d5ba195 Mon Sep 17 00:00:00 2001 From: Bernhard Reutner-Fischer Date: Fri, 8 Nov 2013 10:18:27 +0000 Subject: libgcc: check for fenv.h in dfp configure check uClibc can be built without fenv support, extend the configure check for decimal floating point to probe the existance of fenv.h, too. libgcc/ChangeLog: 2013-03-24 Bernhard Reutner-Fischer * configure.ac (libgcc_cv_dfp): Extend check to probe fenv.h availability. * configure: Regenerate git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@204562 138bc75d-0d04-0410-961f-82ee72b054a4 --- libgcc/ChangeLog | 6 ++++++ libgcc/configure | 13 +++++++++++++ libgcc/configure.ac | 9 ++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 1b2a20b75bf..0bfba640e21 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,9 @@ +2013-11-08 Bernhard Reutner-Fischer + + * configure.ac (libgcc_cv_dfp): Extend check to probe fenv.h + availability. + * configure: Regenerate + 2013-11-07 Uros Bizjak * config/i386/sfp-exceptions.c (__sfp_handle_exceptions): Handle 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 + +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 +]], [[ +_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) -- cgit v1.2.3 From 9daa7b7bfc48f18315468a321e30b5300c83ebfa Mon Sep 17 00:00:00 2001 From: Ilya Enkovich Date: Fri, 8 Nov 2013 10:57:54 +0000 Subject: * 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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@204563 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 9 +++++++++ gcc/c-family/c.opt | 5 +++++ gcc/common.opt | 5 ----- gcc/langhooks-def.h | 4 +--- gcc/langhooks.h | 3 --- gcc/toplev.c | 3 --- 6 files changed, 15 insertions(+), 14 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 171032f7a72..81e5b4fdee4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2013-11-08 Ilya Enkovich + + * 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 PR tree-optimization/59038 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/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/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. */ -- cgit v1.2.3 From 911e958591caa3d7108f8e2946516339aa41ee43 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 8 Nov 2013 12:49:10 +0000 Subject: 2013-11-08 Richard Biener PR tree-optimization/59047 * tree-predcom.c (ref_at_iteration): Handle bitfield accesses properly. * gcc.dg/torture/pr59047.c: New testcase. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@204566 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 6 ++++++ gcc/testsuite/ChangeLog | 11 ++++++++++ gcc/testsuite/gcc.dg/torture/pr59047.c | 39 ++++++++++++++++++++++++++++++++++ gcc/tree-predcom.c | 22 +++++++++++++++---- 4 files changed, 74 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr59047.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 81e5b4fdee4..19049bf3f52 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2013-11-08 Richard Biener + + PR tree-optimization/59047 + * tree-predcom.c (ref_at_iteration): Handle bitfield accesses + properly. + 2013-11-08 Ilya Enkovich * common.opt (fcheck-pointer-bounds): Move to ... diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e83d64e4dbd..4fc3066b528 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2013-11-08 Richard Biener + + PR tree-optimization/59047 + * gcc.dg/torture/pr59047.c: New testcase. + +2013-11-08 Richard Biener + + PR tree-optimization/59038 + PR tree-optimization/58955 + * gcc.dg/torture/pr59038.c: New testcase. + 2013-11-07 Janus Weil PR fortran/58471 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/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 -- cgit v1.2.3 From 4de5fb668d4957e915163ed69454abdbe1b21e28 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 8 Nov 2013 14:30:22 +0000 Subject: * 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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@204571 138bc75d-0d04-0410-961f-82ee72b054a4 --- libstdc++-v3/ChangeLog | 14 ++ libstdc++-v3/include/bits/regex_automaton.h | 179 +++++++++++++---------- libstdc++-v3/include/bits/regex_automaton.tcc | 202 +++++++++++++------------- libstdc++-v3/include/bits/regex_compiler.h | 4 +- libstdc++-v3/include/bits/regex_compiler.tcc | 15 +- libstdc++-v3/include/bits/regex_executor.h | 6 +- 6 files changed, 228 insertions(+), 192 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index e2bf7ff0433..68e4f6b4910 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,17 @@ +2013-11-08 Jonathan Wakely + + * 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. + 2013-11-06 Jonathan Wakely * include/bits/regex_automaton.h (_S_opcode_word_boundry): Rename to diff --git a/libstdc++-v3/include/bits/regex_automaton.h b/libstdc++-v3/include/bits/regex_automaton.h index e6305123703..ded3716771c 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 - 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 - class _NFA - : public std::vector<_State<_CharT, _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<_CharT> _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 _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 + struct _NFA + : _NFA_base, std::vector<_State<_CharT, _TraitsT>> + { + typedef _State<_CharT, _TraitsT> _StateT; + typedef _Matcher<_CharT> _MatcherT; + + using _NFA_base::_NFA_base; - _SizeT - _M_sub_count() const - { return _M_subexpr_count; } + // 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,14 +263,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::ostream& _M_dot(std::ostream& __ostr) const; #endif - - std::vector _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 @@ -251,7 +276,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION 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..0c25c634e77 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 - 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 - 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=\"\"];\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=\"\", 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=\"\"];\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=\"\"];\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=\"\", 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=\"\"];\n"; + break; + case _S_opcode_accept: + __ostr << __id << " [label=\"" << __id << "\\nACC\"];\n" ; + break; + default: + _GLIBCXX_DEBUG_ASSERT(false); + break; } + return __ostr; + } template - std::ostream& _NFA<_CharT, _TraitsT>:: - _M_dot(std::ostream& __ostr) const + std::ostream& + _NFA<_CharT, _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 - _StateIdT _NFA<_CharT, _TraitsT>:: - _M_insert_backref(size_t __index) + _StateIdT + _NFA<_CharT, _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 - void _NFA<_CharT, _TraitsT>:: - _M_eliminate_dummy() + void + _NFA<_CharT, _TraitsT>::_M_eliminate_dummy() { for (auto& __it : *this) { @@ -185,8 +183,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Just apply DFS on the sequence and re-link their links. template - _StateSeq<_CharT, _TraitsT> _StateSeq<_CharT, _TraitsT>:: - _M_clone() + _StateSeq<_CharT, _TraitsT> + _StateSeq<_CharT, _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..98141a722fb 100644 --- a/libstdc++-v3/include/bits/regex_compiler.h +++ b/libstdc++-v3/include/bits/regex_compiler.h @@ -55,8 +55,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION 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; diff --git a/libstdc++-v3/include/bits/regex_compiler.tcc b/libstdc++-v3/include/bits/regex_compiler.tcc index e3764b8d82a..58ef0f0cbe5 100644 --- a/libstdc++-v3/include/bits/regex_compiler.tcc +++ b/libstdc++-v3/include/bits/regex_compiler.tcc @@ -147,11 +147,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _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. @@ -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)) { @@ -343,7 +341,8 @@ _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; } @@ -432,8 +431,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template - bool _BracketMatcher<_CharT, _TraitsT>:: - operator()(_CharT __ch) const + bool + _BracketMatcher<_CharT, _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..f08f292886e 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 + bool __dfs_mode> class _Executor { public: @@ -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 -- cgit v1.2.3 From 774f07b723d83c93d56a42a09bf8b89df350edf3 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 8 Nov 2013 14:30:29 +0000 Subject: * 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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@204572 138bc75d-0d04-0410-961f-82ee72b054a4 --- libstdc++-v3/ChangeLog | 11 ++++++ libstdc++-v3/include/bits/regex.h | 17 ++++----- libstdc++-v3/include/bits/regex_automaton.h | 16 ++++----- libstdc++-v3/include/bits/regex_automaton.tcc | 18 +++++----- libstdc++-v3/include/bits/regex_compiler.h | 16 +++++++-- libstdc++-v3/include/bits/regex_compiler.tcc | 50 +++++++++++++-------------- libstdc++-v3/include/bits/regex_executor.h | 6 ++-- libstdc++-v3/include/bits/regex_executor.tcc | 5 ++- 8 files changed, 80 insertions(+), 59 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 68e4f6b4910..c8cd18545a6 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -12,6 +12,17 @@ * 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. + 2013-11-06 Jonathan Wakely * 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 > + template> 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 - (__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 diff --git a/libstdc++-v3/include/bits/regex_automaton.h b/libstdc++-v3/include/bits/regex_automaton.h index ded3716771c..1be51221ecd 100644 --- a/libstdc++-v3/include/bits/regex_automaton.h +++ b/libstdc++-v3/include/bits/regex_automaton.h @@ -103,10 +103,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif }; - template + template struct _State : _State_base { - typedef _Matcher<_CharT> _MatcherT; + typedef _Matcher _MatcherT; _MatcherT _M_matches; // for _S_opcode_match @@ -155,12 +155,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION bool _M_has_backref; }; - template + template struct _NFA - : _NFA_base, std::vector<_State<_CharT, _TraitsT>> + : _NFA_base, std::vector<_State<_TraitsT>> { - typedef _State<_CharT, _TraitsT> _StateT; - typedef _Matcher<_CharT> _MatcherT; + typedef _State<_TraitsT> _StateT; + typedef _Matcher _MatcherT; using _NFA_base::_NFA_base; @@ -268,11 +268,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// Describes a sequence of one or more %_State, its current start /// and end(s). This structure contains fragments of an NFA during /// construction. - template + template class _StateSeq { public: - typedef _NFA<_CharT, _TraitsT> _RegexT; + typedef _NFA<_TraitsT> _RegexT; public: _StateSeq(_RegexT& __nfa, _StateIdT __s) diff --git a/libstdc++-v3/include/bits/regex_automaton.tcc b/libstdc++-v3/include/bits/regex_automaton.tcc index 0c25c634e77..b0734cf2988 100644 --- a/libstdc++-v3/include/bits/regex_automaton.tcc +++ b/libstdc++-v3/include/bits/regex_automaton.tcc @@ -129,9 +129,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __ostr; } - template + template std::ostream& - _NFA<_CharT, _TraitsT>::_M_dot(std::ostream& __ostr) const + _NFA<_TraitsT>::_M_dot(std::ostream& __ostr) const { __ostr << "digraph _Nfa {\n" " rankdir=LR;\n"; @@ -142,9 +142,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } #endif - template + template _StateIdT - _NFA<_CharT, _TraitsT>::_M_insert_backref(size_t __index) + _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 @@ -164,9 +164,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return _M_insert_state(std::move(__tmp)); } - template + template void - _NFA<_CharT, _TraitsT>::_M_eliminate_dummy() + _NFA<_TraitsT>::_M_eliminate_dummy() { for (auto& __it : *this) { @@ -182,9 +182,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } // Just apply DFS on the sequence and re-link their links. - template - _StateSeq<_CharT, _TraitsT> - _StateSeq<_CharT, _TraitsT>::_M_clone() + template + _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 98141a722fb..fef88624872 100644 --- a/libstdc++-v3/include/bits/regex_compiler.h +++ b/libstdc++-v3/include/bits/regex_compiler.h @@ -43,12 +43,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct _BracketMatcher; /// Builds an NFA from an input iterator interval. - template + template 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, @@ -59,9 +59,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return make_shared<_RegexT>(std::move(_M_nfa)); } private: + typedef typename _TraitsT::char_type _CharT; 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; @@ -129,6 +130,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _StackT _M_stack; }; + template + inline std::shared_ptr<_NFA<_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 struct _AnyMatcher { diff --git a/libstdc++-v3/include/bits/regex_compiler.tcc b/libstdc++-v3/include/bits/regex_compiler.tcc index 58ef0f0cbe5..49c32b8a0ed 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 - _Compiler<_FwdIter, _CharT, _TraitsT>:: + template + _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>(_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 + template void - _Compiler<_FwdIter, _CharT, _TraitsT>:: + _Compiler<_FwdIter, _TraitsT>:: _M_disjunction() { this->_M_alternative(); @@ -110,9 +110,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } - template + template 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 + template bool - _Compiler<_FwdIter, _CharT, _TraitsT>:: + _Compiler<_FwdIter, _TraitsT>:: _M_term() { if (this->_M_assertion()) @@ -141,9 +141,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return false; } - template + template bool - _Compiler<_FwdIter, _CharT, _TraitsT>:: + _Compiler<_FwdIter, _TraitsT>:: _M_assertion() { if (_M_match_token(_ScannerT::_S_token_line_begin)) @@ -172,9 +172,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return true; } - template + template void - _Compiler<_FwdIter, _CharT, _TraitsT>:: + _Compiler<_FwdIter, _TraitsT>:: _M_quantifier() { bool __neg = (_M_flags & regex_constants::ECMAScript); @@ -278,9 +278,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } - template + template bool - _Compiler<_FwdIter, _CharT, _TraitsT>:: + _Compiler<_FwdIter, _TraitsT>:: _M_atom() { if (_M_match_token(_ScannerT::_S_token_anychar)) @@ -329,9 +329,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return true; } - template + template bool - _Compiler<_FwdIter, _CharT, _TraitsT>:: + _Compiler<_FwdIter, _TraitsT>:: _M_bracket_expression() { bool __neg = @@ -346,9 +346,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return true; } - template + template void - _Compiler<_FwdIter, _CharT, _TraitsT>:: + _Compiler<_FwdIter, _TraitsT>:: _M_expression_term(_BMatcherT& __matcher) { if (_M_match_token(_ScannerT::_S_token_collsymbol)) @@ -383,9 +383,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __throw_regex_error(regex_constants::error_brack); } - template + template bool - _Compiler<_FwdIter, _CharT, _TraitsT>:: + _Compiler<_FwdIter, _TraitsT>:: _M_try_char() { bool __is_char = false; @@ -404,9 +404,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __is_char; } - template + template bool - _Compiler<_FwdIter, _CharT, _TraitsT>:: + _Compiler<_FwdIter, _TraitsT>:: _M_match_token(_TokenT token) { if (token == _M_scanner._M_get_token()) @@ -418,9 +418,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return false; } - template + template int - _Compiler<_FwdIter, _CharT, _TraitsT>:: + _Compiler<_FwdIter, _TraitsT>:: _M_cur_int_value(int __radix) { long __v = 0; diff --git a/libstdc++-v3/include/bits/regex_executor.h b/libstdc++-v3/include/bits/regex_executor.h index f08f292886e..ded77475f6f 100644 --- a/libstdc++-v3/include/bits/regex_executor.h +++ b/libstdc++-v3/include/bits/regex_executor.h @@ -62,7 +62,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef std::vector, _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, @@ -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 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 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; -- cgit v1.2.3 From 61dc52412acdd85108cb3fec0e36964f2236b064 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 8 Nov 2013 14:30:34 +0000 Subject: * include/bits/regex_compiler.h (__detail::_AnyMatcher, __detail::_CharMatcher, __detail::_BracketMatcher): Remove redundant _CharT template parameters. * include/bits/regex_compiler.tcc: Likewise. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@204573 138bc75d-0d04-0410-961f-82ee72b054a4 --- libstdc++-v3/ChangeLog | 5 +++++ libstdc++-v3/include/bits/regex_compiler.h | 17 ++++++++++------- libstdc++-v3/include/bits/regex_compiler.tcc | 8 ++++---- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index c8cd18545a6..93203c243e0 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -23,6 +23,11 @@ * 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. + 2013-11-06 Jonathan Wakely * include/bits/regex_automaton.h (_S_opcode_word_boundry): Rename to diff --git a/libstdc++-v3/include/bits/regex_compiler.h b/libstdc++-v3/include/bits/regex_compiler.h index fef88624872..406d9a9fd6b 100644 --- a/libstdc++-v3/include/bits/regex_compiler.h +++ b/libstdc++-v3/include/bits/regex_compiler.h @@ -39,7 +39,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @{ */ - template + template struct _BracketMatcher; /// Builds an NFA from an input iterator interval. @@ -59,13 +59,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return make_shared<_RegexT>(std::move(_M_nfa)); } private: - typedef typename _TraitsT::char_type _CharT; typedef _Scanner<_FwdIter> _ScannerT; typedef typename _ScannerT::_TokenT _TokenT; 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 _CtypeT; // accepts a specific token or returns false. bool @@ -139,9 +138,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return _Cmplr(__first, __last, __traits, __flags)._M_get_nfa(); } - template + template struct _AnyMatcher { + typedef typename _TraitsT::char_type _CharT; + explicit _AnyMatcher(const _TraitsT& __traits) : _M_traits(__traits) @@ -159,9 +160,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const _TraitsT& _M_traits; }; - template + template struct _CharMatcher { + typedef typename _TraitsT::char_type _CharT; typedef regex_constants::syntax_option_type _FlagT; explicit @@ -188,9 +190,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION }; /// Matches a character range (bracket expression) - template + template 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 49c32b8a0ed..f89498f35ed 100644 --- a/libstdc++-v3/include/bits/regex_compiler.tcc +++ b/libstdc++-v3/include/bits/regex_compiler.tcc @@ -286,11 +286,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION 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)) @@ -430,9 +430,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __v; } - template + template bool - _BracketMatcher<_CharT, _TraitsT>::operator()(_CharT __ch) const + _BracketMatcher<_TraitsT>::operator()(_CharT __ch) const { bool __ret = false; if (_M_traits.isctype(__ch, _M_class_set) -- cgit v1.2.3 From 070402670510a6ecfd594dfbe5c4b51f4f837043 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 8 Nov 2013 14:30:40 +0000 Subject: * include/bits/regex_compiler.h (__detail::__compile_nfa): Overload so that std::basic_string and std::vector iterators dispatch to the const C* compiler. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@204574 138bc75d-0d04-0410-961f-82ee72b054a4 --- libstdc++-v3/ChangeLog | 4 +++ libstdc++-v3/include/bits/regex_compiler.h | 44 +++++++++++++++++++++++++++++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 93203c243e0..ea2e6c7eee9 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -28,6 +28,10 @@ _CharT template parameters. * include/bits/regex_compiler.tcc: Likewise. + * include/bits/regex_compiler.h (__detail::__compile_nfa): Overload + so that std::basic_string and std::vector iterators dispatch to + the const C* compiler. + 2013-11-06 Jonathan Wakely * include/bits/regex_automaton.h (_S_opcode_word_boundry): Rename to diff --git a/libstdc++-v3/include/bits/regex_compiler.h b/libstdc++-v3/include/bits/regex_compiler.h index 406d9a9fd6b..741098f8c64 100644 --- a/libstdc++-v3/include/bits/regex_compiler.h +++ b/libstdc++-v3/include/bits/regex_compiler.h @@ -129,8 +129,40 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _StackT _M_stack; }; + template + struct __has_contiguous_iter : std::false_type { }; + + template + struct __has_contiguous_iter> + : std::true_type + { }; + + template + struct __has_contiguous_iter> + : std::true_type + { }; + + template + struct __is_contiguous_normal_iter : std::false_type { }; + + template + struct + __is_contiguous_normal_iter<__gnu_cxx::__normal_iterator<_Tp, _Cont>> + : __has_contiguous_iter<_Cont>::type + { }; + + template + using __enable_if_contiguous_normal_iter + = typename enable_if< __is_contiguous_normal_iter<_Iter>::value, + std::shared_ptr<_NFA<_TraitsT>> >::type; + + template + using __disable_if_contiguous_normal_iter + = typename enable_if< !__is_contiguous_normal_iter<_Iter>::value, + std::shared_ptr<_NFA<_TraitsT>> >::type; + template - inline std::shared_ptr<_NFA<_TraitsT>> + inline __disable_if_contiguous_normal_iter<_FwdIter, _TraitsT> __compile_nfa(_FwdIter __first, _FwdIter __last, const _TraitsT& __traits, regex_constants::syntax_option_type __flags) { @@ -138,6 +170,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return _Cmplr(__first, __last, __traits, __flags)._M_get_nfa(); } + template + 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 struct _AnyMatcher { -- cgit v1.2.3 From f5f43ef0cb98c55172700b921a860b3450a9797a Mon Sep 17 00:00:00 2001 From: James Greenhalgh Date: Fri, 8 Nov 2013 15:09:50 +0000 Subject: [ARM, AArch64] Make aarch-common.c files more robust. gcc/ * 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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@204575 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 14 +++ gcc/config/arm/aarch-common.c | 257 +++++++++++++++++++++++++++--------------- 2 files changed, 180 insertions(+), 91 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 19049bf3f52..5a854b0165c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2013-11-08 James Greenhalgh + + * 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 PR tree-optimization/59047 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); } -- cgit v1.2.3 From 4a60a6a5128db6ff0b10f8389e85adf0ac9b2fb5 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Fri, 8 Nov 2013 16:24:06 +0000 Subject: * 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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@204579 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 9 ++++++++ gcc/tree-ssa-threadedge.c | 4 +--- gcc/tree-ssa-threadupdate.c | 51 +++++++++++++++++++-------------------------- gcc/tree-ssa-threadupdate.h | 1 + 4 files changed, 32 insertions(+), 33 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5a854b0165c..9ba77dbcbe5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2013-11-08 Jeff Law + + * 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 * config/arm/aarch-common.c 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 *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 *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 *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 *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 *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 *); +extern void delete_jump_thread_path (vec *); #endif -- cgit v1.2.3 From 5b1ea11f5fbaa1d51529a4efa58e0d652930eb81 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 8 Nov 2013 17:33:31 +0000 Subject: * include/bits/regex_compiler.h (__detail::__has_contiguous_iter): vector storage is not contiguous. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@204582 138bc75d-0d04-0410-961f-82ee72b054a4 --- libstdc++-v3/ChangeLog | 3 +++ libstdc++-v3/include/bits/regex_compiler.h | 9 +++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index ea2e6c7eee9..3ecd3ba6500 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -32,6 +32,9 @@ so that std::basic_string and std::vector iterators dispatch to the const C* compiler. + * include/bits/regex_compiler.h (__detail::__has_contiguous_iter): + vector storage is not contiguous. + 2013-11-06 Jonathan Wakely * include/bits/regex_automaton.h (_S_opcode_word_boundry): Rename to diff --git a/libstdc++-v3/include/bits/regex_compiler.h b/libstdc++-v3/include/bits/regex_compiler.h index 741098f8c64..b9f81272bb9 100644 --- a/libstdc++-v3/include/bits/regex_compiler.h +++ b/libstdc++-v3/include/bits/regex_compiler.h @@ -134,12 +134,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template struct __has_contiguous_iter> - : std::true_type + : std::true_type // string storage is contiguous { }; template struct __has_contiguous_iter> - : std::true_type + : std::true_type // vector storage is contiguous + { }; + + template + struct __has_contiguous_iter> + : std::false_type // vector storage is not contiguous { }; template -- cgit v1.2.3 From ba75c1770f408b5704931877efec9208fe3b1a47 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 8 Nov 2013 17:35:24 +0000 Subject: compiler: Fix bogus init loop error with struct composite literal. This should eventually be bug482.go in the master testsuite. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@204583 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/go/gofrontend/expressions.cc | 48 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 7269f5849f5..aefb51cec5e 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -13488,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 -- cgit v1.2.3 From 64085907e8a7d3e2d9322481a99c14e5e94ca24b Mon Sep 17 00:00:00 2001 From: Kyrylo Tkachov Date: Fri, 8 Nov 2013 17:36:21 +0000 Subject: * config/arm/arm.c (arm_new_rtx_costs): Break after handling comparisons. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@204584 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 5 +++++ gcc/config/arm/arm.c | 1 + 2 files changed, 6 insertions(+) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9ba77dbcbe5..0b5a94d03df 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2013-11-08 Kyrylo Tkachov + + * config/arm/arm.c (arm_new_rtx_costs): Break after handling + comparisons. + 2013-11-08 Jeff Law * tree-ssa-threadupdate.h (delete_thread_path): Declare. 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 -- cgit v1.2.3 From db8ac29b2cb6d37c0a7e347ddacc3a07aba8a0bc Mon Sep 17 00:00:00 2001 From: Cong Hou Date: Fri, 8 Nov 2013 18:44:46 +0000 Subject: 2013-11-08 Cong Hou PR tree-optimization/58508 * gcc.dg/vect/pr58508.c: Update. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@204590 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/gcc.dg/vect/pr58508.c | 1 + 2 files changed, 7 insertions(+) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4fc3066b528..b4b4988043b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-11-08 Cong Hou + + PR tree-optimization/58508 + * gcc.dg/vect/pr58508.c: Update. + 2013-11-08 Richard Biener PR tree-optimization/59047 @@ -52,6 +57,7 @@ gcc.dg/c11-atomic-2.c, gcc.dg/c11-atomic-3.c, gcc.dg/c90-atomic-1.c, gcc.dg/c99-atomic-1.c: New tests. +>>>>>>> .r204589 2013-11-07 Cong Hou * gcc.dg/vect/vect-alias-check.c: New. 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 } */ -- cgit v1.2.3 From a4323e3c8806841b134d4faef3f7104a3743af80 Mon Sep 17 00:00:00 2001 From: "Balaji V. Iyer" Date: Fri, 8 Nov 2013 19:52:27 +0000 Subject: +2013-11-08 Balaji V. Iyer + + PR c/59039 + * runtime/cilk_fiber-unix.cpp: Fixed a crash in run() function + when optimization is turned on. + git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@204592 138bc75d-0d04-0410-961f-82ee72b054a4 --- libcilkrts/ChangeLog | 6 +++++ libcilkrts/runtime/cilk_fiber-unix.cpp | 41 ++++++++++++++++++++++------------ 2 files changed, 33 insertions(+), 14 deletions(-) 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 + + 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 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 #include +#include +#include +#include + +// 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 +# include #elif defined __GNUC__ -# define alloca __builtin_alloca +# define alloca __builtin_alloca #elif defined _AIX -# define alloca __alloca +# define alloca __alloca #else -# include -# ifdef __cplusplus +# include +# ifdef __cplusplus extern "C" -# endif +# endif void *alloca (size_t); #endif -#include -#include -#include - // 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) { -- cgit v1.2.3 From 4b24b467dbe6f2fa18341b3ad8ff368fdb67ca71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Dumont?= Date: Fri, 8 Nov 2013 21:03:58 +0000 Subject: =?UTF-8?q?2013-11-08=20=20Fran=C3=A7ois=20Dumont=20=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 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>): Adapt. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@204598 138bc75d-0d04-0410-961f-82ee72b054a4 --- libstdc++-v3/ChangeLog | 20 ++++++ libstdc++-v3/include/debug/forward_list | 21 +++--- libstdc++-v3/include/debug/safe_iterator.h | 79 +++++++++++----------- libstdc++-v3/include/debug/safe_iterator.tcc | 72 +++++++++----------- libstdc++-v3/include/debug/safe_local_iterator.h | 19 +++--- libstdc++-v3/include/debug/safe_local_iterator.tcc | 49 +++++++------- 6 files changed, 139 insertions(+), 121 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 3ecd3ba6500..31bffa55022 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,23 @@ +2013-11-08 François Dumont + + * 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>): Adapt. + 2013-11-08 Jonathan Wakely * include/bits/regex_automaton.h (__detail::_State): Split 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 > { 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 + 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 + static bool + _S_Is_Beginnest(const _Safe_iterator<_Iterator, _Sequence>& __it) + { return _S_Is(__it); } }; #ifndef _GLIBCXX_DEBUG_PEDANTIC template 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 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 + static bool + _S_Is(const _Safe_iterator<_Iterator, _Sequence>&) + { return false; } + + template + 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 - inline std::pair::difference_type, + template + inline std::pair::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 - inline std::pair::difference_type, + template + inline std::pair::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 - inline std::pair::difference_type, + template + inline std::pair::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::__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 - 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::__value, + const _Sequence*, + _Sequence*>::__type _M_get_sequence() const - { return static_cast(_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 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 __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 __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 - template - 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 __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 __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::__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 - 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::__value, + const _Sequence*, + _Sequence*>::__type _M_get_sequence() const - { return static_cast(_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 - template - 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 __dist = - __get_distance(base(), __rhs.base()); - switch (__dist.second) + /* Determine if we can order the iterators without the help of + the container */ + std::pair __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 -- cgit v1.2.3 From 026c24c4ca1e50fea5c38fcbf8d1992ed6ddd427 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Fri, 8 Nov 2013 22:15:09 +0000 Subject: 2013-11-08 Andrew MacLeod Joseph Myers * ginclude/stdatomic.h: New file. * Makefile.in (USER_H): Add stdatomic.h. testsuite: 2013-11-08 Joseph Myers * gcc.dg/atomic/stdatomic-compare-exchange-1.c, gcc.dg/atomic/stdatomic-compare-exchange-2.c, gcc.dg/atomic/stdatomic-compare-exchange-3.c, gcc.dg/atomic/stdatomic-compare-exchange-4.c, gcc.dg/atomic/stdatomic-exchange-1.c, gcc.dg/atomic/stdatomic-exchange-2.c, gcc.dg/atomic/stdatomic-exchange-3.c, gcc.dg/atomic/stdatomic-exchange-4.c, gcc.dg/atomic/stdatomic-fence.c, gcc.dg/atomic/stdatomic-flag.c, gcc.dg/atomic/stdatomic-generic.c, gcc.dg/atomic/stdatomic-kill-dep.c, gcc.dg/atomic/stdatomic-load-1.c, gcc.dg/atomic/stdatomic-load-2.c, gcc.dg/atomic/stdatomic-load-3.c, gcc.dg/atomic/stdatomic-load-4.c, gcc.dg/atomic/stdatomic-lockfree.c, gcc.dg/atomic/stdatomic-op-1.c, gcc.dg/atomic/stdatomic-op-2.c, gcc.dg/atomic/stdatomic-op-3.c, gcc.dg/atomic/stdatomic-op-4.c, gcc.dg/atomic/stdatomic-store-1.c, gcc.dg/atomic/stdatomic-store-2.c, gcc.dg/atomic/stdatomic-store-3.c, gcc.dg/atomic/stdatomic-store-4.c, gcc.dg/c11-stdatomic-1.c: New tests. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@204603 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 6 + gcc/Makefile.in | 1 + gcc/ginclude/stdatomic.h | 244 +++++++++++++++ gcc/testsuite/ChangeLog | 26 ++ .../gcc.dg/atomic/stdatomic-compare-exchange-1.c | 81 +++++ .../gcc.dg/atomic/stdatomic-compare-exchange-2.c | 81 +++++ .../gcc.dg/atomic/stdatomic-compare-exchange-3.c | 81 +++++ .../gcc.dg/atomic/stdatomic-compare-exchange-4.c | 81 +++++ gcc/testsuite/gcc.dg/atomic/stdatomic-exchange-1.c | 46 +++ gcc/testsuite/gcc.dg/atomic/stdatomic-exchange-2.c | 46 +++ gcc/testsuite/gcc.dg/atomic/stdatomic-exchange-3.c | 46 +++ gcc/testsuite/gcc.dg/atomic/stdatomic-exchange-4.c | 46 +++ gcc/testsuite/gcc.dg/atomic/stdatomic-fence.c | 26 ++ gcc/testsuite/gcc.dg/atomic/stdatomic-flag.c | 38 +++ gcc/testsuite/gcc.dg/atomic/stdatomic-generic.c | 52 ++++ gcc/testsuite/gcc.dg/atomic/stdatomic-kill-dep.c | 19 ++ gcc/testsuite/gcc.dg/atomic/stdatomic-load-1.c | 44 +++ gcc/testsuite/gcc.dg/atomic/stdatomic-load-2.c | 44 +++ gcc/testsuite/gcc.dg/atomic/stdatomic-load-3.c | 44 +++ gcc/testsuite/gcc.dg/atomic/stdatomic-load-4.c | 44 +++ gcc/testsuite/gcc.dg/atomic/stdatomic-lockfree.c | 68 ++++ gcc/testsuite/gcc.dg/atomic/stdatomic-op-1.c | 341 +++++++++++++++++++++ gcc/testsuite/gcc.dg/atomic/stdatomic-op-2.c | 341 +++++++++++++++++++++ gcc/testsuite/gcc.dg/atomic/stdatomic-op-3.c | 341 +++++++++++++++++++++ gcc/testsuite/gcc.dg/atomic/stdatomic-op-4.c | 341 +++++++++++++++++++++ gcc/testsuite/gcc.dg/atomic/stdatomic-store-1.c | 43 +++ gcc/testsuite/gcc.dg/atomic/stdatomic-store-2.c | 43 +++ gcc/testsuite/gcc.dg/atomic/stdatomic-store-3.c | 43 +++ gcc/testsuite/gcc.dg/atomic/stdatomic-store-4.c | 43 +++ gcc/testsuite/gcc.dg/c11-stdatomic-1.c | 119 +++++++ 30 files changed, 2819 insertions(+) create mode 100644 gcc/ginclude/stdatomic.h create mode 100644 gcc/testsuite/gcc.dg/atomic/stdatomic-compare-exchange-1.c create mode 100644 gcc/testsuite/gcc.dg/atomic/stdatomic-compare-exchange-2.c create mode 100644 gcc/testsuite/gcc.dg/atomic/stdatomic-compare-exchange-3.c create mode 100644 gcc/testsuite/gcc.dg/atomic/stdatomic-compare-exchange-4.c create mode 100644 gcc/testsuite/gcc.dg/atomic/stdatomic-exchange-1.c create mode 100644 gcc/testsuite/gcc.dg/atomic/stdatomic-exchange-2.c create mode 100644 gcc/testsuite/gcc.dg/atomic/stdatomic-exchange-3.c create mode 100644 gcc/testsuite/gcc.dg/atomic/stdatomic-exchange-4.c create mode 100644 gcc/testsuite/gcc.dg/atomic/stdatomic-fence.c create mode 100644 gcc/testsuite/gcc.dg/atomic/stdatomic-flag.c create mode 100644 gcc/testsuite/gcc.dg/atomic/stdatomic-generic.c create mode 100644 gcc/testsuite/gcc.dg/atomic/stdatomic-kill-dep.c create mode 100644 gcc/testsuite/gcc.dg/atomic/stdatomic-load-1.c create mode 100644 gcc/testsuite/gcc.dg/atomic/stdatomic-load-2.c create mode 100644 gcc/testsuite/gcc.dg/atomic/stdatomic-load-3.c create mode 100644 gcc/testsuite/gcc.dg/atomic/stdatomic-load-4.c create mode 100644 gcc/testsuite/gcc.dg/atomic/stdatomic-lockfree.c create mode 100644 gcc/testsuite/gcc.dg/atomic/stdatomic-op-1.c create mode 100644 gcc/testsuite/gcc.dg/atomic/stdatomic-op-2.c create mode 100644 gcc/testsuite/gcc.dg/atomic/stdatomic-op-3.c create mode 100644 gcc/testsuite/gcc.dg/atomic/stdatomic-op-4.c create mode 100644 gcc/testsuite/gcc.dg/atomic/stdatomic-store-1.c create mode 100644 gcc/testsuite/gcc.dg/atomic/stdatomic-store-2.c create mode 100644 gcc/testsuite/gcc.dg/atomic/stdatomic-store-3.c create mode 100644 gcc/testsuite/gcc.dg/atomic/stdatomic-store-4.c create mode 100644 gcc/testsuite/gcc.dg/c11-stdatomic-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0b5a94d03df..8c52a6cc03f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2013-11-08 Andrew MacLeod + Joseph Myers + + * ginclude/stdatomic.h: New file. + * Makefile.in (USER_H): Add stdatomic.h. + 2013-11-08 Kyrylo Tkachov * config/arm/arm.c (arm_new_rtx_costs): Break after handling diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 4a4ab4c1111..49285e5f732 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -381,6 +381,7 @@ USER_H = $(srcdir)/ginclude/float.h \ $(srcdir)/ginclude/stdfix.h \ $(srcdir)/ginclude/stdnoreturn.h \ $(srcdir)/ginclude/stdalign.h \ + $(srcdir)/ginclude/stdatomic.h \ $(EXTRA_HEADERS) USER_H_INC_NEXT_PRE = @user_headers_inc_next_pre@ diff --git a/gcc/ginclude/stdatomic.h b/gcc/ginclude/stdatomic.h new file mode 100644 index 00000000000..622577f0877 --- /dev/null +++ b/gcc/ginclude/stdatomic.h @@ -0,0 +1,244 @@ +/* Copyright (C) 2013 Free Software Foundation, Inc. + +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. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +/* ISO C11 Standard: 7.17 Atomics . */ + +#ifndef _STDATOMIC_H +#define _STDATOMIC_H + +typedef enum + { + memory_order_relaxed = __ATOMIC_RELAXED, + memory_order_consume = __ATOMIC_CONSUME, + memory_order_acquire = __ATOMIC_ACQUIRE, + memory_order_release = __ATOMIC_RELEASE, + memory_order_acq_rel = __ATOMIC_ACQ_REL, + memory_order_seq_cst = __ATOMIC_SEQ_CST + } memory_order; + + +typedef _Atomic _Bool atomic_bool; +typedef _Atomic char atomic_char; +typedef _Atomic signed char atomic_schar; +typedef _Atomic unsigned char atomic_uchar; +typedef _Atomic short atomic_short; +typedef _Atomic unsigned short atomic_ushort; +typedef _Atomic int atomic_int; +typedef _Atomic unsigned int atomic_uint; +typedef _Atomic long atomic_long; +typedef _Atomic unsigned long atomic_ulong; +typedef _Atomic long long atomic_llong; +typedef _Atomic unsigned long long atomic_ullong; +typedef _Atomic __CHAR16_TYPE__ atomic_char16_t; +typedef _Atomic __CHAR32_TYPE__ atomic_char32_t; +typedef _Atomic __WCHAR_TYPE__ atomic_wchar_t; +typedef _Atomic __INT_LEAST8_TYPE__ atomic_int_least8_t; +typedef _Atomic __UINT_LEAST8_TYPE__ atomic_uint_least8_t; +typedef _Atomic __INT_LEAST16_TYPE__ atomic_int_least16_t; +typedef _Atomic __UINT_LEAST16_TYPE__ atomic_uint_least16_t; +typedef _Atomic __INT_LEAST32_TYPE__ atomic_int_least32_t; +typedef _Atomic __UINT_LEAST32_TYPE__ atomic_uint_least32_t; +typedef _Atomic __INT_LEAST64_TYPE__ atomic_int_least64_t; +typedef _Atomic __UINT_LEAST64_TYPE__ atomic_uint_least64_t; +typedef _Atomic __INT_FAST8_TYPE__ atomic_int_fast8_t; +typedef _Atomic __UINT_FAST8_TYPE__ atomic_uint_fast8_t; +typedef _Atomic __INT_FAST16_TYPE__ atomic_int_fast16_t; +typedef _Atomic __UINT_FAST16_TYPE__ atomic_uint_fast16_t; +typedef _Atomic __INT_FAST32_TYPE__ atomic_int_fast32_t; +typedef _Atomic __UINT_FAST32_TYPE__ atomic_uint_fast32_t; +typedef _Atomic __INT_FAST64_TYPE__ atomic_int_fast64_t; +typedef _Atomic __UINT_FAST64_TYPE__ atomic_uint_fast64_t; +typedef _Atomic __INTPTR_TYPE__ atomic_intptr_t; +typedef _Atomic __UINTPTR_TYPE__ atomic_uintptr_t; +typedef _Atomic __SIZE_TYPE__ atomic_size_t; +typedef _Atomic __PTRDIFF_TYPE__ atomic_ptrdiff_t; +typedef _Atomic __INTMAX_TYPE__ atomic_intmax_t; +typedef _Atomic __UINTMAX_TYPE__ atomic_uintmax_t; + + +#define ATOMIC_VAR_INIT(VALUE) (VALUE) +#define atomic_init(PTR, VAL) \ + do \ + { \ + *(PTR) = (VAL); \ + } \ + while (0) + +#define kill_dependency(Y) \ + __extension__ \ + ({ \ + __typeof__ (Y) __kill_dependency_tmp = (Y); \ + __kill_dependency_tmp; \ + }) + +#define atomic_thread_fence(MO) __atomic_thread_fence (MO) +#define atomic_signal_fence(MO) __atomic_signal_fence (MO) +#define atomic_is_lock_free(OBJ) __atomic_is_lock_free (sizeof (*(OBJ)), (OBJ)) + +#define __atomic_type_lock_free(T) \ + (__atomic_always_lock_free (sizeof (T), (void *) 0) \ + ? 2 \ + : (__atomic_is_lock_free (sizeof (T), (void *) 0) ? 1 : 0)) +#define ATOMIC_BOOL_LOCK_FREE \ + __atomic_type_lock_free (atomic_bool) +#define ATOMIC_CHAR_LOCK_FREE \ + __atomic_type_lock_free (atomic_char) +#define ATOMIC_CHAR16_T_LOCK_FREE \ + __atomic_type_lock_free (atomic_char16_t) +#define ATOMIC_CHAR32_T_LOCK_FREE \ + __atomic_type_lock_free (atomic_char32_t) +#define ATOMIC_WCHAR_T_LOCK_FREE \ + __atomic_type_lock_free (atomic_wchar_t) +#define ATOMIC_SHORT_LOCK_FREE \ + __atomic_type_lock_free (atomic_short) +#define ATOMIC_INT_LOCK_FREE \ + __atomic_type_lock_free (atomic_int) +#define ATOMIC_LONG_LOCK_FREE \ + __atomic_type_lock_free (atomic_long) +#define ATOMIC_LLONG_LOCK_FREE \ + __atomic_type_lock_free (atomic_llong) +#define ATOMIC_POINTER_LOCK_FREE \ + __atomic_type_lock_free (void * _Atomic) + + +/* Note that these macros require __typeof__ to remove _Atomic + qualifiers (and const qualifiers, if those are valid on macro + operands). + + Also note that the header file uses the generic form of __atomic + builtins, which requires the address to be taken of the value + parameter, and then we pass that value on. This allows the macros + to work for any type, and the compiler is smart enough to convert + these to lock-free _N variants if possible, and throw away the + temps. */ + +#define atomic_store_explicit(PTR, VAL, MO) \ + __extension__ \ + ({ \ + __typeof__ (*(PTR)) __atomic_store_tmp = (VAL); \ + __atomic_store ((PTR), &__atomic_store_tmp, (MO)); \ + }) + +#define atomic_store(PTR, VAL) \ + atomic_store_explicit (PTR, VAL, __ATOMIC_SEQ_CST) + + +#define atomic_load_explicit(PTR, MO) \ + __extension__ \ + ({ \ + __typeof__ (*(PTR)) __atomic_load_tmp; \ + __atomic_load ((PTR), &__atomic_load_tmp, (MO)); \ + __atomic_load_tmp; \ + }) + +#define atomic_load(PTR) atomic_load_explicit (PTR, __ATOMIC_SEQ_CST) + + +#define atomic_exchange_explicit(PTR, VAL, MO) \ + __extension__ \ + ({ \ + __typeof__ (*(PTR)) __atomic_exchange_val = (VAL), __atomic_exchange_tmp; \ + __atomic_exchange ((PTR), &__atomic_exchange_val, \ + &__atomic_exchange_tmp, (MO)); \ + __atomic_exchange_tmp; \ + }) + +#define atomic_exchange(PTR, VAL) \ + atomic_exchange_explicit (PTR, VAL, __ATOMIC_SEQ_CST) + + +#define atomic_compare_exchange_strong_explicit(PTR, VAL, DES, SUC, FAIL) \ + __extension__ \ + ({ \ + __typeof__ (*(PTR)) __atomic_compare_exchange_tmp = (DES); \ + __atomic_compare_exchange ((PTR), (VAL), \ + &__atomic_compare_exchange_tmp, 0, \ + (SUC), (FAIL)); \ + }) + +#define atomic_compare_exchange_strong(PTR, VAL, DES) \ + atomic_compare_exchange_strong_explicit (PTR, VAL, DES, __ATOMIC_SEQ_CST, \ + __ATOMIC_SEQ_CST) + +#define atomic_compare_exchange_weak_explicit(PTR, VAL, DES, SUC, FAIL) \ + __extension__ \ + ({ \ + __typeof__ (*(PTR)) __atomic_compare_exchange_tmp = (DES); \ + __atomic_compare_exchange ((PTR), (VAL), \ + &__atomic_compare_exchange_tmp, 1, \ + (SUC), (FAIL)); \ + }) + +#define atomic_compare_exchange_weak(PTR, VAL, DES) \ + atomic_compare_exchange_weak_explicit (PTR, VAL, DES, __ATOMIC_SEQ_CST, \ + __ATOMIC_SEQ_CST) + + + +#define atomic_fetch_add(PTR, VAL) __atomic_fetch_add ((PTR), (VAL), \ + __ATOMIC_SEQ_CST) +#define atomic_fetch_add_explicit(PTR, VAL, MO) \ + __atomic_fetch_add ((PTR), (VAL), (MO)) + +#define atomic_fetch_sub(PTR, VAL) __atomic_fetch_sub ((PTR), (VAL), \ + __ATOMIC_SEQ_CST) +#define atomic_fetch_sub_explicit(PTR, VAL, MO) \ + __atomic_fetch_sub ((PTR), (VAL), (MO)) + +#define atomic_fetch_or(PTR, VAL) __atomic_fetch_or ((PTR), (VAL), \ + __ATOMIC_SEQ_CST) +#define atomic_fetch_or_explicit(PTR, VAL, MO) \ + __atomic_fetch_or ((PTR), (VAL), (MO)) + +#define atomic_fetch_xor(PTR, VAL) __atomic_fetch_xor ((PTR), (VAL), \ + __ATOMIC_SEQ_CST) +#define atomic_fetch_xor_explicit(PTR, VAL, MO) \ + __atomic_fetch_xor ((PTR), (VAL), (MO)) + +#define atomic_fetch_and(PTR, VAL) __atomic_fetch_and ((PTR), (VAL), \ + __ATOMIC_SEQ_CST) +#define atomic_fetch_and_explicit(PTR, VAL, MO) \ + __atomic_fetch_and ((PTR), (VAL), (MO)) + + +typedef _Atomic struct +{ +#if __GCC_ATOMIC_TEST_AND_SET_TRUEVAL == 1 + _Bool __val; +#else + unsigned char __val; +#endif +} atomic_flag; + +#define ATOMIC_FLAG_INIT { 0 } + + +#define atomic_flag_test_and_set(PTR) \ + __atomic_test_and_set ((PTR), __ATOMIC_SEQ_CST) +#define atomic_flag_test_and_set_explicit(PTR, MO) \ + __atomic_test_and_set ((PTR), (MO)) + +#define atomic_flag_clear(PTR) __atomic_clear ((PTR), __ATOMIC_SEQ_CST) +#define atomic_flag_clear_explicit(PTR, MO) __atomic_clear ((PTR), (MO)) + +#endif /* _STDATOMIC_H */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b4b4988043b..7ceba705781 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,29 @@ +2013-11-08 Joseph Myers + + * gcc.dg/atomic/stdatomic-compare-exchange-1.c, + gcc.dg/atomic/stdatomic-compare-exchange-2.c, + gcc.dg/atomic/stdatomic-compare-exchange-3.c, + gcc.dg/atomic/stdatomic-compare-exchange-4.c, + gcc.dg/atomic/stdatomic-exchange-1.c, + gcc.dg/atomic/stdatomic-exchange-2.c, + gcc.dg/atomic/stdatomic-exchange-3.c, + gcc.dg/atomic/stdatomic-exchange-4.c, + gcc.dg/atomic/stdatomic-fence.c, gcc.dg/atomic/stdatomic-flag.c, + gcc.dg/atomic/stdatomic-generic.c, + gcc.dg/atomic/stdatomic-kill-dep.c, + gcc.dg/atomic/stdatomic-load-1.c, + gcc.dg/atomic/stdatomic-load-2.c, + gcc.dg/atomic/stdatomic-load-3.c, + gcc.dg/atomic/stdatomic-load-4.c, + gcc.dg/atomic/stdatomic-lockfree.c, + gcc.dg/atomic/stdatomic-op-1.c, gcc.dg/atomic/stdatomic-op-2.c, + gcc.dg/atomic/stdatomic-op-3.c, gcc.dg/atomic/stdatomic-op-4.c, + gcc.dg/atomic/stdatomic-store-1.c, + gcc.dg/atomic/stdatomic-store-2.c, + gcc.dg/atomic/stdatomic-store-3.c, + gcc.dg/atomic/stdatomic-store-4.c, gcc.dg/c11-stdatomic-1.c: New + tests. + 2013-11-08 Cong Hou PR tree-optimization/58508 diff --git a/gcc/testsuite/gcc.dg/atomic/stdatomic-compare-exchange-1.c b/gcc/testsuite/gcc.dg/atomic/stdatomic-compare-exchange-1.c new file mode 100644 index 00000000000..d44c17dd60f --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic/stdatomic-compare-exchange-1.c @@ -0,0 +1,81 @@ +/* Test atomic_compare_exchange routines for existence and proper + execution on 1-byte values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +#include + +extern void abort (void); + +_Atomic char v = ATOMIC_VAR_INIT (0); +char expected = 0; +char max = ~0; +char desired = ~0; +char zero = 0; + +int +main () +{ + + if (!atomic_compare_exchange_strong_explicit (&v, &expected, max, memory_order_relaxed, memory_order_relaxed)) + abort (); + if (expected != 0) + abort (); + + if (atomic_compare_exchange_strong_explicit (&v, &expected, 0, memory_order_acquire, memory_order_relaxed)) + abort (); + if (expected != max) + abort (); + + if (!atomic_compare_exchange_strong_explicit (&v, &expected, 0, memory_order_release, memory_order_acquire)) + abort (); + if (expected != max) + abort (); + if (v != 0) + abort (); + + if (atomic_compare_exchange_weak_explicit (&v, &expected, desired, memory_order_acq_rel, memory_order_acquire)) + abort (); + if (expected != 0) + abort (); + + if (!atomic_compare_exchange_strong_explicit (&v, &expected, desired, memory_order_seq_cst, memory_order_seq_cst)) + abort (); + if (expected != 0) + abort (); + if (v != max) + abort (); + + v = 0; + + if (!atomic_compare_exchange_strong (&v, &expected, max)) + abort (); + if (expected != 0) + abort (); + + if (atomic_compare_exchange_strong (&v, &expected, zero)) + abort (); + if (expected != max) + abort (); + + if (!atomic_compare_exchange_strong (&v, &expected, zero)) + abort (); + if (expected != max) + abort (); + if (v != 0) + abort (); + + if (atomic_compare_exchange_weak (&v, &expected, desired)) + abort (); + if (expected != 0) + abort (); + + if (!atomic_compare_exchange_strong (&v, &expected, desired)) + abort (); + if (expected != 0) + abort (); + if (v != max) + abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/atomic/stdatomic-compare-exchange-2.c b/gcc/testsuite/gcc.dg/atomic/stdatomic-compare-exchange-2.c new file mode 100644 index 00000000000..5647ee66335 --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic/stdatomic-compare-exchange-2.c @@ -0,0 +1,81 @@ +/* Test atomic_compare_exchange routines for existence and proper + execution on 2-byte values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +#include + +extern void abort (void); + +_Atomic short v = ATOMIC_VAR_INIT (0); +short expected = 0; +short max = ~0; +short desired = ~0; +short zero = 0; + +int +main () +{ + + if (!atomic_compare_exchange_strong_explicit (&v, &expected, max, memory_order_relaxed, memory_order_relaxed)) + abort (); + if (expected != 0) + abort (); + + if (atomic_compare_exchange_strong_explicit (&v, &expected, 0, memory_order_acquire, memory_order_relaxed)) + abort (); + if (expected != max) + abort (); + + if (!atomic_compare_exchange_strong_explicit (&v, &expected, 0, memory_order_release, memory_order_acquire)) + abort (); + if (expected != max) + abort (); + if (v != 0) + abort (); + + if (atomic_compare_exchange_weak_explicit (&v, &expected, desired, memory_order_acq_rel, memory_order_acquire)) + abort (); + if (expected != 0) + abort (); + + if (!atomic_compare_exchange_strong_explicit (&v, &expected, desired, memory_order_seq_cst, memory_order_seq_cst)) + abort (); + if (expected != 0) + abort (); + if (v != max) + abort (); + + v = 0; + + if (!atomic_compare_exchange_strong (&v, &expected, max)) + abort (); + if (expected != 0) + abort (); + + if (atomic_compare_exchange_strong (&v, &expected, zero)) + abort (); + if (expected != max) + abort (); + + if (!atomic_compare_exchange_strong (&v, &expected, zero)) + abort (); + if (expected != max) + abort (); + if (v != 0) + abort (); + + if (atomic_compare_exchange_weak (&v, &expected, desired)) + abort (); + if (expected != 0) + abort (); + + if (!atomic_compare_exchange_strong (&v, &expected, desired)) + abort (); + if (expected != 0) + abort (); + if (v != max) + abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/atomic/stdatomic-compare-exchange-3.c b/gcc/testsuite/gcc.dg/atomic/stdatomic-compare-exchange-3.c new file mode 100644 index 00000000000..e29784e5b21 --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic/stdatomic-compare-exchange-3.c @@ -0,0 +1,81 @@ +/* Test atomic_compare_exchange routines for existence and proper + execution on 2-byte values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +#include + +extern void abort (void); + +_Atomic int v = ATOMIC_VAR_INIT (0); +int expected = 0; +int max = ~0; +int desired = ~0; +int zero = 0; + +int +main () +{ + + if (!atomic_compare_exchange_strong_explicit (&v, &expected, max, memory_order_relaxed, memory_order_relaxed)) + abort (); + if (expected != 0) + abort (); + + if (atomic_compare_exchange_strong_explicit (&v, &expected, 0, memory_order_acquire, memory_order_relaxed)) + abort (); + if (expected != max) + abort (); + + if (!atomic_compare_exchange_strong_explicit (&v, &expected, 0, memory_order_release, memory_order_acquire)) + abort (); + if (expected != max) + abort (); + if (v != 0) + abort (); + + if (atomic_compare_exchange_weak_explicit (&v, &expected, desired, memory_order_acq_rel, memory_order_acquire)) + abort (); + if (expected != 0) + abort (); + + if (!atomic_compare_exchange_strong_explicit (&v, &expected, desired, memory_order_seq_cst, memory_order_seq_cst)) + abort (); + if (expected != 0) + abort (); + if (v != max) + abort (); + + v = 0; + + if (!atomic_compare_exchange_strong (&v, &expected, max)) + abort (); + if (expected != 0) + abort (); + + if (atomic_compare_exchange_strong (&v, &expected, zero)) + abort (); + if (expected != max) + abort (); + + if (!atomic_compare_exchange_strong (&v, &expected, zero)) + abort (); + if (expected != max) + abort (); + if (v != 0) + abort (); + + if (atomic_compare_exchange_weak (&v, &expected, desired)) + abort (); + if (expected != 0) + abort (); + + if (!atomic_compare_exchange_strong (&v, &expected, desired)) + abort (); + if (expected != 0) + abort (); + if (v != max) + abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/atomic/stdatomic-compare-exchange-4.c b/gcc/testsuite/gcc.dg/atomic/stdatomic-compare-exchange-4.c new file mode 100644 index 00000000000..e052dca0c94 --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic/stdatomic-compare-exchange-4.c @@ -0,0 +1,81 @@ +/* Test atomic_compare_exchange routines for existence and proper + execution on 2-byte values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +#include + +extern void abort (void); + +_Atomic long long v = ATOMIC_VAR_INIT (0); +long long expected = 0; +long long max = ~0LL; +long long desired = ~0LL; +long long zero = 0; + +int +main () +{ + + if (!atomic_compare_exchange_strong_explicit (&v, &expected, max, memory_order_relaxed, memory_order_relaxed)) + abort (); + if (expected != 0) + abort (); + + if (atomic_compare_exchange_strong_explicit (&v, &expected, 0, memory_order_acquire, memory_order_relaxed)) + abort (); + if (expected != max) + abort (); + + if (!atomic_compare_exchange_strong_explicit (&v, &expected, 0, memory_order_release, memory_order_acquire)) + abort (); + if (expected != max) + abort (); + if (v != 0) + abort (); + + if (atomic_compare_exchange_weak_explicit (&v, &expected, desired, memory_order_acq_rel, memory_order_acquire)) + abort (); + if (expected != 0) + abort (); + + if (!atomic_compare_exchange_strong_explicit (&v, &expected, desired, memory_order_seq_cst, memory_order_seq_cst)) + abort (); + if (expected != 0) + abort (); + if (v != max) + abort (); + + v = 0; + + if (!atomic_compare_exchange_strong (&v, &expected, max)) + abort (); + if (expected != 0) + abort (); + + if (atomic_compare_exchange_strong (&v, &expected, zero)) + abort (); + if (expected != max) + abort (); + + if (!atomic_compare_exchange_strong (&v, &expected, zero)) + abort (); + if (expected != max) + abort (); + if (v != 0) + abort (); + + if (atomic_compare_exchange_weak (&v, &expected, desired)) + abort (); + if (expected != 0) + abort (); + + if (!atomic_compare_exchange_strong (&v, &expected, desired)) + abort (); + if (expected != 0) + abort (); + if (v != max) + abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/atomic/stdatomic-exchange-1.c b/gcc/testsuite/gcc.dg/atomic/stdatomic-exchange-1.c new file mode 100644 index 00000000000..d7c751a34fe --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic/stdatomic-exchange-1.c @@ -0,0 +1,46 @@ +/* Test atomic_exchange routines for existence and proper execution on + 1-byte values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +#include + +extern void abort (void); + +_Atomic char v; +char count, ret; + +int +main () +{ + v = 0; + count = 0; + + if (atomic_exchange_explicit (&v, count + 1, memory_order_relaxed) != count) + abort (); + count++; + + if (atomic_exchange_explicit (&v, count + 1, memory_order_acquire) != count) + abort (); + count++; + + if (atomic_exchange_explicit (&v, count + 1, memory_order_release) != count) + abort (); + count++; + + if (atomic_exchange_explicit (&v, count + 1, memory_order_acq_rel) != count) + abort (); + count++; + + if (atomic_exchange_explicit (&v, count + 1, memory_order_seq_cst) != count) + abort (); + count++; + + count++; + + ret = atomic_exchange (&v, count); + if (ret != count - 1 || v != count) + abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/atomic/stdatomic-exchange-2.c b/gcc/testsuite/gcc.dg/atomic/stdatomic-exchange-2.c new file mode 100644 index 00000000000..2f1f7e2359d --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic/stdatomic-exchange-2.c @@ -0,0 +1,46 @@ +/* Test atomic_exchange routines for existence and proper execution on + 2-byte values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +#include + +extern void abort (void); + +_Atomic short v; +short count, ret; + +int +main () +{ + v = 0; + count = 0; + + if (atomic_exchange_explicit (&v, count + 1, memory_order_relaxed) != count) + abort (); + count++; + + if (atomic_exchange_explicit (&v, count + 1, memory_order_acquire) != count) + abort (); + count++; + + if (atomic_exchange_explicit (&v, count + 1, memory_order_release) != count) + abort (); + count++; + + if (atomic_exchange_explicit (&v, count + 1, memory_order_acq_rel) != count) + abort (); + count++; + + if (atomic_exchange_explicit (&v, count + 1, memory_order_seq_cst) != count) + abort (); + count++; + + count++; + + ret = atomic_exchange (&v, count); + if (ret != count - 1 || v != count) + abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/atomic/stdatomic-exchange-3.c b/gcc/testsuite/gcc.dg/atomic/stdatomic-exchange-3.c new file mode 100644 index 00000000000..a62c5718785 --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic/stdatomic-exchange-3.c @@ -0,0 +1,46 @@ +/* Test atomic_exchange routines for existence and proper execution on + 4-byte values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +#include + +extern void abort (void); + +_Atomic int v; +int count, ret; + +int +main () +{ + v = 0; + count = 0; + + if (atomic_exchange_explicit (&v, count + 1, memory_order_relaxed) != count) + abort (); + count++; + + if (atomic_exchange_explicit (&v, count + 1, memory_order_acquire) != count) + abort (); + count++; + + if (atomic_exchange_explicit (&v, count + 1, memory_order_release) != count) + abort (); + count++; + + if (atomic_exchange_explicit (&v, count + 1, memory_order_acq_rel) != count) + abort (); + count++; + + if (atomic_exchange_explicit (&v, count + 1, memory_order_seq_cst) != count) + abort (); + count++; + + count++; + + ret = atomic_exchange (&v, count); + if (ret != count - 1 || v != count) + abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/atomic/stdatomic-exchange-4.c b/gcc/testsuite/gcc.dg/atomic/stdatomic-exchange-4.c new file mode 100644 index 00000000000..1be9b299948 --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic/stdatomic-exchange-4.c @@ -0,0 +1,46 @@ +/* Test atomic_exchange routines for existence and proper execution on + 8-byte values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +#include + +extern void abort (void); + +_Atomic long long v; +long long count, ret; + +int +main () +{ + v = 0; + count = 0; + + if (atomic_exchange_explicit (&v, count + 1, memory_order_relaxed) != count) + abort (); + count++; + + if (atomic_exchange_explicit (&v, count + 1, memory_order_acquire) != count) + abort (); + count++; + + if (atomic_exchange_explicit (&v, count + 1, memory_order_release) != count) + abort (); + count++; + + if (atomic_exchange_explicit (&v, count + 1, memory_order_acq_rel) != count) + abort (); + count++; + + if (atomic_exchange_explicit (&v, count + 1, memory_order_seq_cst) != count) + abort (); + count++; + + count++; + + ret = atomic_exchange (&v, count); + if (ret != count - 1 || v != count) + abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/atomic/stdatomic-fence.c b/gcc/testsuite/gcc.dg/atomic/stdatomic-fence.c new file mode 100644 index 00000000000..5f6c4e0f9d7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic/stdatomic-fence.c @@ -0,0 +1,26 @@ +/* Test atomic_*_fence routines for existence and execution with each + valid memory model. */ +/* { dg-do run } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +#include + +int +main () +{ + atomic_thread_fence (memory_order_relaxed); + atomic_thread_fence (memory_order_consume); + atomic_thread_fence (memory_order_acquire); + atomic_thread_fence (memory_order_release); + atomic_thread_fence (memory_order_acq_rel); + atomic_thread_fence (memory_order_seq_cst); + + atomic_signal_fence (memory_order_relaxed); + atomic_signal_fence (memory_order_consume); + atomic_signal_fence (memory_order_acquire); + atomic_signal_fence (memory_order_release); + atomic_signal_fence (memory_order_acq_rel); + atomic_signal_fence (memory_order_seq_cst); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/atomic/stdatomic-flag.c b/gcc/testsuite/gcc.dg/atomic/stdatomic-flag.c new file mode 100644 index 00000000000..32f9e9bb631 --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic/stdatomic-flag.c @@ -0,0 +1,38 @@ +/* Test atomic_flag routines for existence and execution. */ +/* { dg-do run } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +#include + +extern void abort (void); +atomic_flag a = ATOMIC_FLAG_INIT; + +int +main () +{ + int b; + + if (!atomic_is_lock_free (&a)) + abort (); + + if (atomic_flag_test_and_set (&a)) + abort (); + atomic_flag_clear_explicit (&a, memory_order_relaxed); + if (atomic_flag_test_and_set (&a)) + abort (); + atomic_flag_clear (&a); + + b = atomic_flag_test_and_set_explicit (&a, memory_order_seq_cst); + if (!atomic_flag_test_and_set (&a) || b != 0) + abort (); + + b = atomic_flag_test_and_set_explicit (&a, memory_order_acq_rel); + if (!atomic_flag_test_and_set (&a) || b != 1) + abort (); + + atomic_flag_clear_explicit (&a, memory_order_seq_cst); + if (atomic_flag_test_and_set (&a)) + abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/atomic/stdatomic-generic.c b/gcc/testsuite/gcc.dg/atomic/stdatomic-generic.c new file mode 100644 index 00000000000..8033c53739d --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic/stdatomic-generic.c @@ -0,0 +1,52 @@ +/* Test generic atomic routines for proper function calling. */ +/* { dg-do run } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +#include + +extern void abort (); +extern int memcmp (const void *, const void *, __SIZE_TYPE__); + +typedef struct test { + int array[10]; +} test_struct; + +test_struct zero = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +test_struct ones = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; +_Atomic test_struct a; +test_struct b; + +int size = sizeof (test_struct); +/* Test for consistency on sizes 1, 2, 4, 8, 16 and 32. */ +int +main () +{ + test_struct c; + + atomic_store_explicit (&a, zero, memory_order_relaxed); + if (memcmp (&a, &zero, size)) + abort (); + + c = atomic_exchange_explicit (&a, ones, memory_order_seq_cst); + if (memcmp (&c, &zero, size)) + abort (); + if (memcmp (&a, &ones, size)) + abort (); + + b = atomic_load_explicit (&a, memory_order_relaxed); + if (memcmp (&b, &ones, size)) + abort (); + + if (!atomic_compare_exchange_strong_explicit (&a, &b, zero, memory_order_seq_cst, memory_order_acquire)) + abort (); + if (memcmp (&a, &zero, size)) + abort (); + + if (atomic_compare_exchange_weak_explicit (&a, &b, ones, memory_order_seq_cst, memory_order_acquire)) + abort (); + if (memcmp (&b, &zero, size)) + abort (); + + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/atomic/stdatomic-kill-dep.c b/gcc/testsuite/gcc.dg/atomic/stdatomic-kill-dep.c new file mode 100644 index 00000000000..fda7fe7d1f0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic/stdatomic-kill-dep.c @@ -0,0 +1,19 @@ +/* Test atomic_kill_dependency. */ +/* { dg-do run } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +#include + +extern void abort (void); + +_Atomic int a = ATOMIC_VAR_INIT (1), b; + +int +main () +{ + b = kill_dependency (a); + if (b != 1) + abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/atomic/stdatomic-load-1.c b/gcc/testsuite/gcc.dg/atomic/stdatomic-load-1.c new file mode 100644 index 00000000000..16bea684cb3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic/stdatomic-load-1.c @@ -0,0 +1,44 @@ +/* Test atomic_load routines for existence and proper execution on + 1-byte values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +#include + +extern void abort (void); + +_Atomic char v; +char count; + +int +main () +{ + v = 0; + count = 0; + + if (atomic_load_explicit (&v, memory_order_relaxed) != count++) + abort (); + else + v++; + + if (atomic_load_explicit (&v, memory_order_acquire) != count++) + abort (); + else + v++; + + if (atomic_load_explicit (&v, memory_order_consume) != count++) + abort (); + else + v++; + + if (atomic_load_explicit (&v, memory_order_seq_cst) != count++) + abort (); + else + v++; + + if (atomic_load (&v) != count) + abort (); + + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/atomic/stdatomic-load-2.c b/gcc/testsuite/gcc.dg/atomic/stdatomic-load-2.c new file mode 100644 index 00000000000..6b492d8c2ce --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic/stdatomic-load-2.c @@ -0,0 +1,44 @@ +/* Test atomic_load routines for existence and proper execution on + 2-byte values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +#include + +extern void abort (void); + +_Atomic short v; +short count; + +int +main () +{ + v = 0; + count = 0; + + if (atomic_load_explicit (&v, memory_order_relaxed) != count++) + abort (); + else + v++; + + if (atomic_load_explicit (&v, memory_order_acquire) != count++) + abort (); + else + v++; + + if (atomic_load_explicit (&v, memory_order_consume) != count++) + abort (); + else + v++; + + if (atomic_load_explicit (&v, memory_order_seq_cst) != count++) + abort (); + else + v++; + + if (atomic_load (&v) != count) + abort (); + + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/atomic/stdatomic-load-3.c b/gcc/testsuite/gcc.dg/atomic/stdatomic-load-3.c new file mode 100644 index 00000000000..c6f2e4b09ec --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic/stdatomic-load-3.c @@ -0,0 +1,44 @@ +/* Test atomic_load routines for existence and proper execution on + 4-byte values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +#include + +extern void abort (void); + +_Atomic int v; +int count; + +int +main () +{ + v = 0; + count = 0; + + if (atomic_load_explicit (&v, memory_order_relaxed) != count++) + abort (); + else + v++; + + if (atomic_load_explicit (&v, memory_order_acquire) != count++) + abort (); + else + v++; + + if (atomic_load_explicit (&v, memory_order_consume) != count++) + abort (); + else + v++; + + if (atomic_load_explicit (&v, memory_order_seq_cst) != count++) + abort (); + else + v++; + + if (atomic_load (&v) != count) + abort (); + + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/atomic/stdatomic-load-4.c b/gcc/testsuite/gcc.dg/atomic/stdatomic-load-4.c new file mode 100644 index 00000000000..bc26a5238df --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic/stdatomic-load-4.c @@ -0,0 +1,44 @@ +/* Test atomic_load routines for existence and proper execution on + 8-byte values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +#include + +extern void abort (void); + +_Atomic long long v; +long long count; + +int +main () +{ + v = 0; + count = 0; + + if (atomic_load_explicit (&v, memory_order_relaxed) != count++) + abort (); + else + v++; + + if (atomic_load_explicit (&v, memory_order_acquire) != count++) + abort (); + else + v++; + + if (atomic_load_explicit (&v, memory_order_consume) != count++) + abort (); + else + v++; + + if (atomic_load_explicit (&v, memory_order_seq_cst) != count++) + abort (); + else + v++; + + if (atomic_load (&v) != count) + abort (); + + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/atomic/stdatomic-lockfree.c b/gcc/testsuite/gcc.dg/atomic/stdatomic-lockfree.c new file mode 100644 index 00000000000..29310e9ce2a --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic/stdatomic-lockfree.c @@ -0,0 +1,68 @@ +/* Test atomic_is_lock_free. */ +/* { dg-do run } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +#include +#include + +extern void abort (); + +_Atomic _Bool aba; +atomic_bool abt; +_Atomic char aca; +atomic_char act; +_Atomic __CHAR16_TYPE__ ac16a; +atomic_char16_t ac16t; +_Atomic __CHAR32_TYPE__ ac32a; +atomic_char32_t ac32t; +_Atomic __WCHAR_TYPE__ awca; +atomic_wchar_t awct; +_Atomic short asa; +atomic_short ast; +_Atomic int aia; +atomic_int ait; +_Atomic long ala; +atomic_long alt; +_Atomic long long alla; +atomic_llong allt; +void *_Atomic apa; + +#define CHECK_TYPE(MACRO, V1, V2) \ + do \ + { \ + int r1 = MACRO; \ + int r2 = atomic_is_lock_free (&V1); \ + int r3 = atomic_is_lock_free (&V2); \ + if (r1 != 0 && r1 != 1 && r1 != 2) \ + abort (); \ + if (r2 != 0 && r2 != 1) \ + abort (); \ + if (r3 != 0 && r3 != 1) \ + abort (); \ + if (r1 == 2 && r2 != 1) \ + abort (); \ + if (r1 == 2 && r3 != 1) \ + abort (); \ + if (r1 == 0 && r2 != 0) \ + abort (); \ + if (r1 == 0 && r3 != 0) \ + abort (); \ + } \ + while (0) + +int +main () +{ + CHECK_TYPE (ATOMIC_BOOL_LOCK_FREE, aba, abt); + CHECK_TYPE (ATOMIC_CHAR_LOCK_FREE, aca, act); + CHECK_TYPE (ATOMIC_CHAR16_T_LOCK_FREE, ac16a, ac16t); + CHECK_TYPE (ATOMIC_CHAR32_T_LOCK_FREE, ac32a, ac32t); + CHECK_TYPE (ATOMIC_WCHAR_T_LOCK_FREE, awca, awct); + CHECK_TYPE (ATOMIC_SHORT_LOCK_FREE, asa, ast); + CHECK_TYPE (ATOMIC_INT_LOCK_FREE, aia, ait); + CHECK_TYPE (ATOMIC_LONG_LOCK_FREE, ala, alt); + CHECK_TYPE (ATOMIC_LLONG_LOCK_FREE, alla, allt); + CHECK_TYPE (ATOMIC_POINTER_LOCK_FREE, apa, apa); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/atomic/stdatomic-op-1.c b/gcc/testsuite/gcc.dg/atomic/stdatomic-op-1.c new file mode 100644 index 00000000000..6513a53402e --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic/stdatomic-op-1.c @@ -0,0 +1,341 @@ +/* Test atomic_fetch routines for existence and proper execution on + 1-byte values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +#include + +extern void abort (void); + +_Atomic char v; +char count, res; +const char init = ~0; + +void +test_fetch_add () +{ + v = 0; + count = 1; + + if (atomic_fetch_add_explicit (&v, count, memory_order_relaxed) != 0) + abort (); + + if (atomic_fetch_add_explicit (&v, 1, memory_order_consume) != 1) + abort (); + + if (atomic_fetch_add_explicit (&v, count, memory_order_acquire) != 2) + abort (); + + if (atomic_fetch_add_explicit (&v, 1, memory_order_release) != 3) + abort (); + + if (atomic_fetch_add_explicit (&v, count, memory_order_acq_rel) != 4) + abort (); + + if (atomic_fetch_add_explicit (&v, 1, memory_order_seq_cst) != 5) + abort (); + + if (atomic_fetch_add (&v, 1) != 6) + abort (); +} + +void +test_fetch_sub () +{ + v = res = 20; + count = 0; + + if (atomic_fetch_sub_explicit (&v, count + 1, memory_order_relaxed) != res--) + abort (); + + if (atomic_fetch_sub_explicit (&v, 1, memory_order_consume) != res--) + abort (); + + if (atomic_fetch_sub_explicit (&v, count + 1, memory_order_acquire) != res--) + abort (); + + if (atomic_fetch_sub_explicit (&v, 1, memory_order_release) != res--) + abort (); + + if (atomic_fetch_sub_explicit (&v, count + 1, memory_order_acq_rel) != res--) + abort (); + + if (atomic_fetch_sub_explicit (&v, 1, memory_order_seq_cst) != res--) + abort (); + + if (atomic_fetch_sub (&v, 1) != res--) + abort (); +} + +void +test_fetch_and () +{ + v = init; + + if (atomic_fetch_and_explicit (&v, 0, memory_order_relaxed) != init) + abort (); + + if (atomic_fetch_and_explicit (&v, init, memory_order_consume) != 0) + abort (); + + if (atomic_fetch_and_explicit (&v, 0, memory_order_acquire) != 0) + abort (); + + v = ~v; + if (atomic_fetch_and_explicit (&v, init, memory_order_release) != init) + abort (); + + if (atomic_fetch_and_explicit (&v, 0, memory_order_acq_rel) != init) + abort (); + + if (atomic_fetch_and_explicit (&v, 0, memory_order_seq_cst) != 0) + abort (); + + if (atomic_fetch_and (&v, 0) != 0) + abort (); +} + +void +test_fetch_xor () +{ + v = init; + count = 0; + + if (atomic_fetch_xor_explicit (&v, count, memory_order_relaxed) != init) + abort (); + + if (atomic_fetch_xor_explicit (&v, ~count, memory_order_consume) != init) + abort (); + + if (atomic_fetch_xor_explicit (&v, 0, memory_order_acquire) != 0) + abort (); + + if (atomic_fetch_xor_explicit (&v, ~count, memory_order_release) != 0) + abort (); + + if (atomic_fetch_xor_explicit (&v, 0, memory_order_acq_rel) != init) + abort (); + + if (atomic_fetch_xor_explicit (&v, ~count, memory_order_seq_cst) != init) + abort (); + + if (atomic_fetch_xor (&v, ~count) != 0) + abort (); +} + +void +test_fetch_or () +{ + v = 0; + count = 1; + + if (atomic_fetch_or_explicit (&v, count, memory_order_relaxed) != 0) + abort (); + + count *= 2; + if (atomic_fetch_or_explicit (&v, 2, memory_order_consume) != 1) + abort (); + + count *= 2; + if (atomic_fetch_or_explicit (&v, count, memory_order_acquire) != 3) + abort (); + + count *= 2; + if (atomic_fetch_or_explicit (&v, 8, memory_order_release) != 7) + abort (); + + count *= 2; + if (atomic_fetch_or_explicit (&v, count, memory_order_acq_rel) != 15) + abort (); + + count *= 2; + if (atomic_fetch_or_explicit (&v, count, memory_order_seq_cst) != 31) + abort (); + + count *= 2; + if (atomic_fetch_or (&v, count) != 63) + abort (); +} + + +/* Test the OP routines with a result which isn't used. */ + +void +test_add () +{ + v = 0; + count = 1; + + atomic_fetch_add (&v, count); + if (v != 1) + abort (); + + atomic_fetch_add_explicit (&v, count, memory_order_consume); + if (v != 2) + abort (); + + atomic_fetch_add (&v, 1); + if (v != 3) + abort (); + + atomic_fetch_add_explicit (&v, 1, memory_order_release); + if (v != 4) + abort (); + + atomic_fetch_add (&v, 1); + if (v != 5) + abort (); + + atomic_fetch_add_explicit (&v, count, memory_order_seq_cst); + if (v != 6) + abort (); +} + +void +test_sub () +{ + v = res = 20; + count = 0; + + atomic_fetch_sub (&v, count + 1); + if (v != --res) + abort (); + + atomic_fetch_sub_explicit (&v, count + 1, memory_order_consume); + if (v != --res) + abort (); + + atomic_fetch_sub (&v, 1); + if (v != --res) + abort (); + + atomic_fetch_sub_explicit (&v, 1, memory_order_release); + if (v != --res) + abort (); + + atomic_fetch_sub (&v, count + 1); + if (v != --res) + abort (); + + atomic_fetch_sub_explicit (&v, count + 1, memory_order_seq_cst); + if (v != --res) + abort (); +} + +void +test_and () +{ + v = init; + + atomic_fetch_and (&v, 0); + if (v != 0) + abort (); + + v = init; + atomic_fetch_and_explicit (&v, init, memory_order_consume); + if (v != init) + abort (); + + atomic_fetch_and (&v, 0); + if (v != 0) + abort (); + + v = ~v; + atomic_fetch_and_explicit (&v, init, memory_order_release); + if (v != init) + abort (); + + atomic_fetch_and (&v, 0); + if (v != 0) + abort (); + + v = ~v; + atomic_fetch_and_explicit (&v, 0, memory_order_seq_cst); + if (v != 0) + abort (); +} + +void +test_xor () +{ + v = init; + count = 0; + + atomic_fetch_xor (&v, count); + if (v != init) + abort (); + + atomic_fetch_xor_explicit (&v, ~count, memory_order_consume); + if (v != 0) + abort (); + + atomic_fetch_xor (&v, 0); + if (v != 0) + abort (); + + atomic_fetch_xor_explicit (&v, ~count, memory_order_release); + if (v != init) + abort (); + + atomic_fetch_xor_explicit (&v, 0, memory_order_acq_rel); + if (v != init) + abort (); + + atomic_fetch_xor (&v, ~count); + if (v != 0) + abort (); +} + +void +test_or () +{ + v = 0; + count = 1; + + atomic_fetch_or (&v, count); + if (v != 1) + abort (); + + count *= 2; + atomic_fetch_or_explicit (&v, count, memory_order_consume); + if (v != 3) + abort (); + + count *= 2; + atomic_fetch_or (&v, 4); + if (v != 7) + abort (); + + count *= 2; + atomic_fetch_or_explicit (&v, 8, memory_order_release); + if (v != 15) + abort (); + + count *= 2; + atomic_fetch_or (&v, count); + if (v != 31) + abort (); + + count *= 2; + atomic_fetch_or_explicit (&v, count, memory_order_seq_cst); + if (v != 63) + abort (); +} + +int +main () +{ + test_fetch_add (); + test_fetch_sub (); + test_fetch_and (); + test_fetch_xor (); + test_fetch_or (); + + test_add (); + test_sub (); + test_and (); + test_xor (); + test_or (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/atomic/stdatomic-op-2.c b/gcc/testsuite/gcc.dg/atomic/stdatomic-op-2.c new file mode 100644 index 00000000000..05edafff0bd --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic/stdatomic-op-2.c @@ -0,0 +1,341 @@ +/* Test atomic_fetch routines for existence and proper execution on + 2-byte values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +#include + +extern void abort (void); + +_Atomic short v; +short count, res; +const short init = ~0; + +void +test_fetch_add () +{ + v = 0; + count = 1; + + if (atomic_fetch_add_explicit (&v, count, memory_order_relaxed) != 0) + abort (); + + if (atomic_fetch_add_explicit (&v, 1, memory_order_consume) != 1) + abort (); + + if (atomic_fetch_add_explicit (&v, count, memory_order_acquire) != 2) + abort (); + + if (atomic_fetch_add_explicit (&v, 1, memory_order_release) != 3) + abort (); + + if (atomic_fetch_add_explicit (&v, count, memory_order_acq_rel) != 4) + abort (); + + if (atomic_fetch_add_explicit (&v, 1, memory_order_seq_cst) != 5) + abort (); + + if (atomic_fetch_add (&v, 1) != 6) + abort (); +} + +void +test_fetch_sub () +{ + v = res = 20; + count = 0; + + if (atomic_fetch_sub_explicit (&v, count + 1, memory_order_relaxed) != res--) + abort (); + + if (atomic_fetch_sub_explicit (&v, 1, memory_order_consume) != res--) + abort (); + + if (atomic_fetch_sub_explicit (&v, count + 1, memory_order_acquire) != res--) + abort (); + + if (atomic_fetch_sub_explicit (&v, 1, memory_order_release) != res--) + abort (); + + if (atomic_fetch_sub_explicit (&v, count + 1, memory_order_acq_rel) != res--) + abort (); + + if (atomic_fetch_sub_explicit (&v, 1, memory_order_seq_cst) != res--) + abort (); + + if (atomic_fetch_sub (&v, 1) != res--) + abort (); +} + +void +test_fetch_and () +{ + v = init; + + if (atomic_fetch_and_explicit (&v, 0, memory_order_relaxed) != init) + abort (); + + if (atomic_fetch_and_explicit (&v, init, memory_order_consume) != 0) + abort (); + + if (atomic_fetch_and_explicit (&v, 0, memory_order_acquire) != 0) + abort (); + + v = ~v; + if (atomic_fetch_and_explicit (&v, init, memory_order_release) != init) + abort (); + + if (atomic_fetch_and_explicit (&v, 0, memory_order_acq_rel) != init) + abort (); + + if (atomic_fetch_and_explicit (&v, 0, memory_order_seq_cst) != 0) + abort (); + + if (atomic_fetch_and (&v, 0) != 0) + abort (); +} + +void +test_fetch_xor () +{ + v = init; + count = 0; + + if (atomic_fetch_xor_explicit (&v, count, memory_order_relaxed) != init) + abort (); + + if (atomic_fetch_xor_explicit (&v, ~count, memory_order_consume) != init) + abort (); + + if (atomic_fetch_xor_explicit (&v, 0, memory_order_acquire) != 0) + abort (); + + if (atomic_fetch_xor_explicit (&v, ~count, memory_order_release) != 0) + abort (); + + if (atomic_fetch_xor_explicit (&v, 0, memory_order_acq_rel) != init) + abort (); + + if (atomic_fetch_xor_explicit (&v, ~count, memory_order_seq_cst) != init) + abort (); + + if (atomic_fetch_xor (&v, ~count) != 0) + abort (); +} + +void +test_fetch_or () +{ + v = 0; + count = 1; + + if (atomic_fetch_or_explicit (&v, count, memory_order_relaxed) != 0) + abort (); + + count *= 2; + if (atomic_fetch_or_explicit (&v, 2, memory_order_consume) != 1) + abort (); + + count *= 2; + if (atomic_fetch_or_explicit (&v, count, memory_order_acquire) != 3) + abort (); + + count *= 2; + if (atomic_fetch_or_explicit (&v, 8, memory_order_release) != 7) + abort (); + + count *= 2; + if (atomic_fetch_or_explicit (&v, count, memory_order_acq_rel) != 15) + abort (); + + count *= 2; + if (atomic_fetch_or_explicit (&v, count, memory_order_seq_cst) != 31) + abort (); + + count *= 2; + if (atomic_fetch_or (&v, count) != 63) + abort (); +} + + +/* Test the OP routines with a result which isn't used. */ + +void +test_add () +{ + v = 0; + count = 1; + + atomic_fetch_add (&v, count); + if (v != 1) + abort (); + + atomic_fetch_add_explicit (&v, count, memory_order_consume); + if (v != 2) + abort (); + + atomic_fetch_add (&v, 1); + if (v != 3) + abort (); + + atomic_fetch_add_explicit (&v, 1, memory_order_release); + if (v != 4) + abort (); + + atomic_fetch_add (&v, 1); + if (v != 5) + abort (); + + atomic_fetch_add_explicit (&v, count, memory_order_seq_cst); + if (v != 6) + abort (); +} + +void +test_sub () +{ + v = res = 20; + count = 0; + + atomic_fetch_sub (&v, count + 1); + if (v != --res) + abort (); + + atomic_fetch_sub_explicit (&v, count + 1, memory_order_consume); + if (v != --res) + abort (); + + atomic_fetch_sub (&v, 1); + if (v != --res) + abort (); + + atomic_fetch_sub_explicit (&v, 1, memory_order_release); + if (v != --res) + abort (); + + atomic_fetch_sub (&v, count + 1); + if (v != --res) + abort (); + + atomic_fetch_sub_explicit (&v, count + 1, memory_order_seq_cst); + if (v != --res) + abort (); +} + +void +test_and () +{ + v = init; + + atomic_fetch_and (&v, 0); + if (v != 0) + abort (); + + v = init; + atomic_fetch_and_explicit (&v, init, memory_order_consume); + if (v != init) + abort (); + + atomic_fetch_and (&v, 0); + if (v != 0) + abort (); + + v = ~v; + atomic_fetch_and_explicit (&v, init, memory_order_release); + if (v != init) + abort (); + + atomic_fetch_and (&v, 0); + if (v != 0) + abort (); + + v = ~v; + atomic_fetch_and_explicit (&v, 0, memory_order_seq_cst); + if (v != 0) + abort (); +} + +void +test_xor () +{ + v = init; + count = 0; + + atomic_fetch_xor (&v, count); + if (v != init) + abort (); + + atomic_fetch_xor_explicit (&v, ~count, memory_order_consume); + if (v != 0) + abort (); + + atomic_fetch_xor (&v, 0); + if (v != 0) + abort (); + + atomic_fetch_xor_explicit (&v, ~count, memory_order_release); + if (v != init) + abort (); + + atomic_fetch_xor_explicit (&v, 0, memory_order_acq_rel); + if (v != init) + abort (); + + atomic_fetch_xor (&v, ~count); + if (v != 0) + abort (); +} + +void +test_or () +{ + v = 0; + count = 1; + + atomic_fetch_or (&v, count); + if (v != 1) + abort (); + + count *= 2; + atomic_fetch_or_explicit (&v, count, memory_order_consume); + if (v != 3) + abort (); + + count *= 2; + atomic_fetch_or (&v, 4); + if (v != 7) + abort (); + + count *= 2; + atomic_fetch_or_explicit (&v, 8, memory_order_release); + if (v != 15) + abort (); + + count *= 2; + atomic_fetch_or (&v, count); + if (v != 31) + abort (); + + count *= 2; + atomic_fetch_or_explicit (&v, count, memory_order_seq_cst); + if (v != 63) + abort (); +} + +int +main () +{ + test_fetch_add (); + test_fetch_sub (); + test_fetch_and (); + test_fetch_xor (); + test_fetch_or (); + + test_add (); + test_sub (); + test_and (); + test_xor (); + test_or (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/atomic/stdatomic-op-3.c b/gcc/testsuite/gcc.dg/atomic/stdatomic-op-3.c new file mode 100644 index 00000000000..dc745d40591 --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic/stdatomic-op-3.c @@ -0,0 +1,341 @@ +/* Test atomic_fetch routines for existence and proper execution on + 4-byte values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +#include + +extern void abort (void); + +_Atomic int v; +int count, res; +const int init = ~0; + +void +test_fetch_add () +{ + v = 0; + count = 1; + + if (atomic_fetch_add_explicit (&v, count, memory_order_relaxed) != 0) + abort (); + + if (atomic_fetch_add_explicit (&v, 1, memory_order_consume) != 1) + abort (); + + if (atomic_fetch_add_explicit (&v, count, memory_order_acquire) != 2) + abort (); + + if (atomic_fetch_add_explicit (&v, 1, memory_order_release) != 3) + abort (); + + if (atomic_fetch_add_explicit (&v, count, memory_order_acq_rel) != 4) + abort (); + + if (atomic_fetch_add_explicit (&v, 1, memory_order_seq_cst) != 5) + abort (); + + if (atomic_fetch_add (&v, 1) != 6) + abort (); +} + +void +test_fetch_sub () +{ + v = res = 20; + count = 0; + + if (atomic_fetch_sub_explicit (&v, count + 1, memory_order_relaxed) != res--) + abort (); + + if (atomic_fetch_sub_explicit (&v, 1, memory_order_consume) != res--) + abort (); + + if (atomic_fetch_sub_explicit (&v, count + 1, memory_order_acquire) != res--) + abort (); + + if (atomic_fetch_sub_explicit (&v, 1, memory_order_release) != res--) + abort (); + + if (atomic_fetch_sub_explicit (&v, count + 1, memory_order_acq_rel) != res--) + abort (); + + if (atomic_fetch_sub_explicit (&v, 1, memory_order_seq_cst) != res--) + abort (); + + if (atomic_fetch_sub (&v, 1) != res--) + abort (); +} + +void +test_fetch_and () +{ + v = init; + + if (atomic_fetch_and_explicit (&v, 0, memory_order_relaxed) != init) + abort (); + + if (atomic_fetch_and_explicit (&v, init, memory_order_consume) != 0) + abort (); + + if (atomic_fetch_and_explicit (&v, 0, memory_order_acquire) != 0) + abort (); + + v = ~v; + if (atomic_fetch_and_explicit (&v, init, memory_order_release) != init) + abort (); + + if (atomic_fetch_and_explicit (&v, 0, memory_order_acq_rel) != init) + abort (); + + if (atomic_fetch_and_explicit (&v, 0, memory_order_seq_cst) != 0) + abort (); + + if (atomic_fetch_and (&v, 0) != 0) + abort (); +} + +void +test_fetch_xor () +{ + v = init; + count = 0; + + if (atomic_fetch_xor_explicit (&v, count, memory_order_relaxed) != init) + abort (); + + if (atomic_fetch_xor_explicit (&v, ~count, memory_order_consume) != init) + abort (); + + if (atomic_fetch_xor_explicit (&v, 0, memory_order_acquire) != 0) + abort (); + + if (atomic_fetch_xor_explicit (&v, ~count, memory_order_release) != 0) + abort (); + + if (atomic_fetch_xor_explicit (&v, 0, memory_order_acq_rel) != init) + abort (); + + if (atomic_fetch_xor_explicit (&v, ~count, memory_order_seq_cst) != init) + abort (); + + if (atomic_fetch_xor (&v, ~count) != 0) + abort (); +} + +void +test_fetch_or () +{ + v = 0; + count = 1; + + if (atomic_fetch_or_explicit (&v, count, memory_order_relaxed) != 0) + abort (); + + count *= 2; + if (atomic_fetch_or_explicit (&v, 2, memory_order_consume) != 1) + abort (); + + count *= 2; + if (atomic_fetch_or_explicit (&v, count, memory_order_acquire) != 3) + abort (); + + count *= 2; + if (atomic_fetch_or_explicit (&v, 8, memory_order_release) != 7) + abort (); + + count *= 2; + if (atomic_fetch_or_explicit (&v, count, memory_order_acq_rel) != 15) + abort (); + + count *= 2; + if (atomic_fetch_or_explicit (&v, count, memory_order_seq_cst) != 31) + abort (); + + count *= 2; + if (atomic_fetch_or (&v, count) != 63) + abort (); +} + + +/* Test the OP routines with a result which isn't used. */ + +void +test_add () +{ + v = 0; + count = 1; + + atomic_fetch_add (&v, count); + if (v != 1) + abort (); + + atomic_fetch_add_explicit (&v, count, memory_order_consume); + if (v != 2) + abort (); + + atomic_fetch_add (&v, 1); + if (v != 3) + abort (); + + atomic_fetch_add_explicit (&v, 1, memory_order_release); + if (v != 4) + abort (); + + atomic_fetch_add (&v, 1); + if (v != 5) + abort (); + + atomic_fetch_add_explicit (&v, count, memory_order_seq_cst); + if (v != 6) + abort (); +} + +void +test_sub () +{ + v = res = 20; + count = 0; + + atomic_fetch_sub (&v, count + 1); + if (v != --res) + abort (); + + atomic_fetch_sub_explicit (&v, count + 1, memory_order_consume); + if (v != --res) + abort (); + + atomic_fetch_sub (&v, 1); + if (v != --res) + abort (); + + atomic_fetch_sub_explicit (&v, 1, memory_order_release); + if (v != --res) + abort (); + + atomic_fetch_sub (&v, count + 1); + if (v != --res) + abort (); + + atomic_fetch_sub_explicit (&v, count + 1, memory_order_seq_cst); + if (v != --res) + abort (); +} + +void +test_and () +{ + v = init; + + atomic_fetch_and (&v, 0); + if (v != 0) + abort (); + + v = init; + atomic_fetch_and_explicit (&v, init, memory_order_consume); + if (v != init) + abort (); + + atomic_fetch_and (&v, 0); + if (v != 0) + abort (); + + v = ~v; + atomic_fetch_and_explicit (&v, init, memory_order_release); + if (v != init) + abort (); + + atomic_fetch_and (&v, 0); + if (v != 0) + abort (); + + v = ~v; + atomic_fetch_and_explicit (&v, 0, memory_order_seq_cst); + if (v != 0) + abort (); +} + +void +test_xor () +{ + v = init; + count = 0; + + atomic_fetch_xor (&v, count); + if (v != init) + abort (); + + atomic_fetch_xor_explicit (&v, ~count, memory_order_consume); + if (v != 0) + abort (); + + atomic_fetch_xor (&v, 0); + if (v != 0) + abort (); + + atomic_fetch_xor_explicit (&v, ~count, memory_order_release); + if (v != init) + abort (); + + atomic_fetch_xor_explicit (&v, 0, memory_order_acq_rel); + if (v != init) + abort (); + + atomic_fetch_xor (&v, ~count); + if (v != 0) + abort (); +} + +void +test_or () +{ + v = 0; + count = 1; + + atomic_fetch_or (&v, count); + if (v != 1) + abort (); + + count *= 2; + atomic_fetch_or_explicit (&v, count, memory_order_consume); + if (v != 3) + abort (); + + count *= 2; + atomic_fetch_or (&v, 4); + if (v != 7) + abort (); + + count *= 2; + atomic_fetch_or_explicit (&v, 8, memory_order_release); + if (v != 15) + abort (); + + count *= 2; + atomic_fetch_or (&v, count); + if (v != 31) + abort (); + + count *= 2; + atomic_fetch_or_explicit (&v, count, memory_order_seq_cst); + if (v != 63) + abort (); +} + +int +main () +{ + test_fetch_add (); + test_fetch_sub (); + test_fetch_and (); + test_fetch_xor (); + test_fetch_or (); + + test_add (); + test_sub (); + test_and (); + test_xor (); + test_or (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/atomic/stdatomic-op-4.c b/gcc/testsuite/gcc.dg/atomic/stdatomic-op-4.c new file mode 100644 index 00000000000..84b83e44f8e --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic/stdatomic-op-4.c @@ -0,0 +1,341 @@ +/* Test atomic_fetch routines for existence and proper execution on + 8-byte values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +#include + +extern void abort (void); + +_Atomic long long v; +long long count, res; +const long long init = ~0; + +void +test_fetch_add () +{ + v = 0; + count = 1; + + if (atomic_fetch_add_explicit (&v, count, memory_order_relaxed) != 0) + abort (); + + if (atomic_fetch_add_explicit (&v, 1, memory_order_consume) != 1) + abort (); + + if (atomic_fetch_add_explicit (&v, count, memory_order_acquire) != 2) + abort (); + + if (atomic_fetch_add_explicit (&v, 1, memory_order_release) != 3) + abort (); + + if (atomic_fetch_add_explicit (&v, count, memory_order_acq_rel) != 4) + abort (); + + if (atomic_fetch_add_explicit (&v, 1, memory_order_seq_cst) != 5) + abort (); + + if (atomic_fetch_add (&v, 1) != 6) + abort (); +} + +void +test_fetch_sub () +{ + v = res = 20; + count = 0; + + if (atomic_fetch_sub_explicit (&v, count + 1, memory_order_relaxed) != res--) + abort (); + + if (atomic_fetch_sub_explicit (&v, 1, memory_order_consume) != res--) + abort (); + + if (atomic_fetch_sub_explicit (&v, count + 1, memory_order_acquire) != res--) + abort (); + + if (atomic_fetch_sub_explicit (&v, 1, memory_order_release) != res--) + abort (); + + if (atomic_fetch_sub_explicit (&v, count + 1, memory_order_acq_rel) != res--) + abort (); + + if (atomic_fetch_sub_explicit (&v, 1, memory_order_seq_cst) != res--) + abort (); + + if (atomic_fetch_sub (&v, 1) != res--) + abort (); +} + +void +test_fetch_and () +{ + v = init; + + if (atomic_fetch_and_explicit (&v, 0, memory_order_relaxed) != init) + abort (); + + if (atomic_fetch_and_explicit (&v, init, memory_order_consume) != 0) + abort (); + + if (atomic_fetch_and_explicit (&v, 0, memory_order_acquire) != 0) + abort (); + + v = ~v; + if (atomic_fetch_and_explicit (&v, init, memory_order_release) != init) + abort (); + + if (atomic_fetch_and_explicit (&v, 0, memory_order_acq_rel) != init) + abort (); + + if (atomic_fetch_and_explicit (&v, 0, memory_order_seq_cst) != 0) + abort (); + + if (atomic_fetch_and (&v, 0) != 0) + abort (); +} + +void +test_fetch_xor () +{ + v = init; + count = 0; + + if (atomic_fetch_xor_explicit (&v, count, memory_order_relaxed) != init) + abort (); + + if (atomic_fetch_xor_explicit (&v, ~count, memory_order_consume) != init) + abort (); + + if (atomic_fetch_xor_explicit (&v, 0, memory_order_acquire) != 0) + abort (); + + if (atomic_fetch_xor_explicit (&v, ~count, memory_order_release) != 0) + abort (); + + if (atomic_fetch_xor_explicit (&v, 0, memory_order_acq_rel) != init) + abort (); + + if (atomic_fetch_xor_explicit (&v, ~count, memory_order_seq_cst) != init) + abort (); + + if (atomic_fetch_xor (&v, ~count) != 0) + abort (); +} + +void +test_fetch_or () +{ + v = 0; + count = 1; + + if (atomic_fetch_or_explicit (&v, count, memory_order_relaxed) != 0) + abort (); + + count *= 2; + if (atomic_fetch_or_explicit (&v, 2, memory_order_consume) != 1) + abort (); + + count *= 2; + if (atomic_fetch_or_explicit (&v, count, memory_order_acquire) != 3) + abort (); + + count *= 2; + if (atomic_fetch_or_explicit (&v, 8, memory_order_release) != 7) + abort (); + + count *= 2; + if (atomic_fetch_or_explicit (&v, count, memory_order_acq_rel) != 15) + abort (); + + count *= 2; + if (atomic_fetch_or_explicit (&v, count, memory_order_seq_cst) != 31) + abort (); + + count *= 2; + if (atomic_fetch_or (&v, count) != 63) + abort (); +} + + +/* Test the OP routines with a result which isn't used. */ + +void +test_add () +{ + v = 0; + count = 1; + + atomic_fetch_add (&v, count); + if (v != 1) + abort (); + + atomic_fetch_add_explicit (&v, count, memory_order_consume); + if (v != 2) + abort (); + + atomic_fetch_add (&v, 1); + if (v != 3) + abort (); + + atomic_fetch_add_explicit (&v, 1, memory_order_release); + if (v != 4) + abort (); + + atomic_fetch_add (&v, 1); + if (v != 5) + abort (); + + atomic_fetch_add_explicit (&v, count, memory_order_seq_cst); + if (v != 6) + abort (); +} + +void +test_sub () +{ + v = res = 20; + count = 0; + + atomic_fetch_sub (&v, count + 1); + if (v != --res) + abort (); + + atomic_fetch_sub_explicit (&v, count + 1, memory_order_consume); + if (v != --res) + abort (); + + atomic_fetch_sub (&v, 1); + if (v != --res) + abort (); + + atomic_fetch_sub_explicit (&v, 1, memory_order_release); + if (v != --res) + abort (); + + atomic_fetch_sub (&v, count + 1); + if (v != --res) + abort (); + + atomic_fetch_sub_explicit (&v, count + 1, memory_order_seq_cst); + if (v != --res) + abort (); +} + +void +test_and () +{ + v = init; + + atomic_fetch_and (&v, 0); + if (v != 0) + abort (); + + v = init; + atomic_fetch_and_explicit (&v, init, memory_order_consume); + if (v != init) + abort (); + + atomic_fetch_and (&v, 0); + if (v != 0) + abort (); + + v = ~v; + atomic_fetch_and_explicit (&v, init, memory_order_release); + if (v != init) + abort (); + + atomic_fetch_and (&v, 0); + if (v != 0) + abort (); + + v = ~v; + atomic_fetch_and_explicit (&v, 0, memory_order_seq_cst); + if (v != 0) + abort (); +} + +void +test_xor () +{ + v = init; + count = 0; + + atomic_fetch_xor (&v, count); + if (v != init) + abort (); + + atomic_fetch_xor_explicit (&v, ~count, memory_order_consume); + if (v != 0) + abort (); + + atomic_fetch_xor (&v, 0); + if (v != 0) + abort (); + + atomic_fetch_xor_explicit (&v, ~count, memory_order_release); + if (v != init) + abort (); + + atomic_fetch_xor_explicit (&v, 0, memory_order_acq_rel); + if (v != init) + abort (); + + atomic_fetch_xor (&v, ~count); + if (v != 0) + abort (); +} + +void +test_or () +{ + v = 0; + count = 1; + + atomic_fetch_or (&v, count); + if (v != 1) + abort (); + + count *= 2; + atomic_fetch_or_explicit (&v, count, memory_order_consume); + if (v != 3) + abort (); + + count *= 2; + atomic_fetch_or (&v, 4); + if (v != 7) + abort (); + + count *= 2; + atomic_fetch_or_explicit (&v, 8, memory_order_release); + if (v != 15) + abort (); + + count *= 2; + atomic_fetch_or (&v, count); + if (v != 31) + abort (); + + count *= 2; + atomic_fetch_or_explicit (&v, count, memory_order_seq_cst); + if (v != 63) + abort (); +} + +int +main () +{ + test_fetch_add (); + test_fetch_sub (); + test_fetch_and (); + test_fetch_xor (); + test_fetch_or (); + + test_add (); + test_sub (); + test_and (); + test_xor (); + test_or (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/atomic/stdatomic-store-1.c b/gcc/testsuite/gcc.dg/atomic/stdatomic-store-1.c new file mode 100644 index 00000000000..f7936dabc1e --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic/stdatomic-store-1.c @@ -0,0 +1,43 @@ +/* Test atomic_store routines for existence and proper execution on + 1-byte values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +#include + +extern void abort (void); + +_Atomic char v; +char count; + +int +main () +{ + v = 0; + count = 0; + + atomic_init (&v, count + 1); + if (v != ++count) + abort (); + + atomic_store_explicit (&v, count + 1, memory_order_relaxed); + if (v != ++count) + abort (); + + atomic_store_explicit (&v, count + 1, memory_order_release); + if (v != ++count) + abort (); + + atomic_store_explicit (&v, count + 1, memory_order_seq_cst); + if (v != ++count) + abort (); + + count++; + + atomic_store (&v, count); + if (v != count) + abort (); + + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/atomic/stdatomic-store-2.c b/gcc/testsuite/gcc.dg/atomic/stdatomic-store-2.c new file mode 100644 index 00000000000..0bbba1cef89 --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic/stdatomic-store-2.c @@ -0,0 +1,43 @@ +/* Test atomic_store routines for existence and proper execution on + 2-byte values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +#include + +extern void abort (void); + +_Atomic short v; +short count; + +int +main () +{ + v = 0; + count = 0; + + atomic_init (&v, count + 1); + if (v != ++count) + abort (); + + atomic_store_explicit (&v, count + 1, memory_order_relaxed); + if (v != ++count) + abort (); + + atomic_store_explicit (&v, count + 1, memory_order_release); + if (v != ++count) + abort (); + + atomic_store_explicit (&v, count + 1, memory_order_seq_cst); + if (v != ++count) + abort (); + + count++; + + atomic_store (&v, count); + if (v != count) + abort (); + + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/atomic/stdatomic-store-3.c b/gcc/testsuite/gcc.dg/atomic/stdatomic-store-3.c new file mode 100644 index 00000000000..86c1b2aa886 --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic/stdatomic-store-3.c @@ -0,0 +1,43 @@ +/* Test atomic_store routines for existence and proper execution on + 4-byte values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +#include + +extern void abort (void); + +_Atomic int v; +int count; + +int +main () +{ + v = 0; + count = 0; + + atomic_init (&v, count + 1); + if (v != ++count) + abort (); + + atomic_store_explicit (&v, count + 1, memory_order_relaxed); + if (v != ++count) + abort (); + + atomic_store_explicit (&v, count + 1, memory_order_release); + if (v != ++count) + abort (); + + atomic_store_explicit (&v, count + 1, memory_order_seq_cst); + if (v != ++count) + abort (); + + count++; + + atomic_store (&v, count); + if (v != count) + abort (); + + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/atomic/stdatomic-store-4.c b/gcc/testsuite/gcc.dg/atomic/stdatomic-store-4.c new file mode 100644 index 00000000000..fe96469a9be --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic/stdatomic-store-4.c @@ -0,0 +1,43 @@ +/* Test atomic_store routines for existence and proper execution on + 8-byte values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +#include + +extern void abort (void); + +_Atomic long long v; +long long count; + +int +main () +{ + v = 0; + count = 0; + + atomic_init (&v, count + 1); + if (v != ++count) + abort (); + + atomic_store_explicit (&v, count + 1, memory_order_relaxed); + if (v != ++count) + abort (); + + atomic_store_explicit (&v, count + 1, memory_order_release); + if (v != ++count) + abort (); + + atomic_store_explicit (&v, count + 1, memory_order_seq_cst); + if (v != ++count) + abort (); + + count++; + + atomic_store (&v, count); + if (v != count) + abort (); + + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/c11-stdatomic-1.c b/gcc/testsuite/gcc.dg/c11-stdatomic-1.c new file mode 100644 index 00000000000..79909c055a7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c11-stdatomic-1.c @@ -0,0 +1,119 @@ +/* Test stdatomic.h header contents. */ +/* { dg-do compile } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +#include + +#ifndef ATOMIC_BOOL_LOCK_FREE +# error ATOMIC_BOOL_LOCK_FREE not defined +#endif + +#ifndef ATOMIC_CHAR_LOCK_FREE +# error ATOMIC_CHAR_LOCK_FREE not defined +#endif + +#ifndef ATOMIC_CHAR16_T_LOCK_FREE +# error ATOMIC_CHAR16_T_LOCK_FREE not defined +#endif + +#ifndef ATOMIC_CHAR32_T_LOCK_FREE +# error ATOMIC_CHAR32_T_LOCK_FREE not defined +#endif + +#ifndef ATOMIC_WCHAR_T_LOCK_FREE +# error ATOMIC_WCHAR_T_LOCK_FREE not defined +#endif + +#ifndef ATOMIC_SHORT_LOCK_FREE +# error ATOMIC_SHORT_LOCK_FREE not defined +#endif + +#ifndef ATOMIC_INT_LOCK_FREE +# error ATOMIC_INT_LOCK_FREE not defined +#endif + +#ifndef ATOMIC_LONG_LOCK_FREE +# error ATOMIC_LONG_LOCK_FREE not defined +#endif + +#ifndef ATOMIC_LLONG_LOCK_FREE +# error ATOMIC_LLONG_LOCK_FREE not defined +#endif + +#ifndef ATOMIC_POINTER_LOCK_FREE +# error ATOMIC_POINTER_LOCK_FREE not defined +#endif + +memory_order m0 = memory_order_relaxed; +memory_order m1 = memory_order_consume; +memory_order m2 = memory_order_acquire; +memory_order m3 = memory_order_release; +memory_order m4 = memory_order_acq_rel; +memory_order m5 = memory_order_seq_cst; + +atomic_flag af = ATOMIC_FLAG_INIT; + +struct s { int i[100]; } sv; +void +f (void) +{ + _Atomic struct s sva = ATOMIC_VAR_INIT (sv); +} + +#ifndef kill_dependency +# error kill_dependency not defined +#endif + +#define CHECK_ATOMIC_TYPEDEF(A, B) \ + do \ + { \ + A v; \ + char array1[sizeof (A) == sizeof (B) ? 1 : -1]; \ + char array2[_Alignof (A) == _Alignof (B) ? 1 : -1]; \ + } \ + while (0) + +#include +#include + +void +check_typedefs (void) +{ + CHECK_ATOMIC_TYPEDEF (atomic_bool, _Atomic _Bool); + CHECK_ATOMIC_TYPEDEF (atomic_char, _Atomic char); + CHECK_ATOMIC_TYPEDEF (atomic_schar, _Atomic signed char); + CHECK_ATOMIC_TYPEDEF (atomic_uchar, _Atomic unsigned char); + CHECK_ATOMIC_TYPEDEF (atomic_short, _Atomic short); + CHECK_ATOMIC_TYPEDEF (atomic_ushort, _Atomic unsigned short); + CHECK_ATOMIC_TYPEDEF (atomic_int, _Atomic int); + CHECK_ATOMIC_TYPEDEF (atomic_uint, _Atomic unsigned int); + CHECK_ATOMIC_TYPEDEF (atomic_long, _Atomic long); + CHECK_ATOMIC_TYPEDEF (atomic_ulong, _Atomic unsigned long); + CHECK_ATOMIC_TYPEDEF (atomic_llong, _Atomic long long); + CHECK_ATOMIC_TYPEDEF (atomic_ullong, _Atomic unsigned long long); + CHECK_ATOMIC_TYPEDEF (atomic_char16_t, _Atomic __CHAR16_TYPE__); + CHECK_ATOMIC_TYPEDEF (atomic_char32_t, _Atomic __CHAR32_TYPE__); + CHECK_ATOMIC_TYPEDEF (atomic_wchar_t, _Atomic wchar_t); + CHECK_ATOMIC_TYPEDEF (atomic_int_least8_t, _Atomic int_least8_t); + CHECK_ATOMIC_TYPEDEF (atomic_uint_least8_t, _Atomic uint_least8_t); + CHECK_ATOMIC_TYPEDEF (atomic_int_least16_t, _Atomic int_least16_t); + CHECK_ATOMIC_TYPEDEF (atomic_uint_least16_t, _Atomic uint_least16_t); + CHECK_ATOMIC_TYPEDEF (atomic_int_least32_t, _Atomic int_least32_t); + CHECK_ATOMIC_TYPEDEF (atomic_uint_least32_t, _Atomic uint_least32_t); + CHECK_ATOMIC_TYPEDEF (atomic_int_least64_t, _Atomic int_least64_t); + CHECK_ATOMIC_TYPEDEF (atomic_uint_least64_t, _Atomic uint_least64_t); + CHECK_ATOMIC_TYPEDEF (atomic_int_fast8_t, _Atomic int_fast8_t); + CHECK_ATOMIC_TYPEDEF (atomic_uint_fast8_t, _Atomic uint_fast8_t); + CHECK_ATOMIC_TYPEDEF (atomic_int_fast16_t, _Atomic int_fast16_t); + CHECK_ATOMIC_TYPEDEF (atomic_uint_fast16_t, _Atomic uint_fast16_t); + CHECK_ATOMIC_TYPEDEF (atomic_int_fast32_t, _Atomic int_fast32_t); + CHECK_ATOMIC_TYPEDEF (atomic_uint_fast32_t, _Atomic uint_fast32_t); + CHECK_ATOMIC_TYPEDEF (atomic_int_fast64_t, _Atomic int_fast64_t); + CHECK_ATOMIC_TYPEDEF (atomic_uint_fast64_t, _Atomic uint_fast64_t); + CHECK_ATOMIC_TYPEDEF (atomic_intptr_t, _Atomic intptr_t); + CHECK_ATOMIC_TYPEDEF (atomic_uintptr_t, _Atomic uintptr_t); + CHECK_ATOMIC_TYPEDEF (atomic_size_t, _Atomic size_t); + CHECK_ATOMIC_TYPEDEF (atomic_ptrdiff_t, _Atomic ptrdiff_t); + CHECK_ATOMIC_TYPEDEF (atomic_intmax_t, _Atomic intmax_t); + CHECK_ATOMIC_TYPEDEF (atomic_uintmax_t, _Atomic uintmax_t); +} -- cgit v1.2.3 From ec1c555d37fcda7b7bcd00051fc6c0bdb84ad1b2 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Fri, 8 Nov 2013 22:16:59 +0000 Subject: Move Cilk Plus Builtins node before Other Builtins node PR other/59055 * doc/extend.texi: Move Cilk Plus Builtins node before Other Builtins node. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@204604 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 6 ++++++ gcc/doc/extend.texi | 52 ++++++++++++++++++++++++++-------------------------- 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8c52a6cc03f..2f224a42da2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2013-11-08 H.J. Lu + + PR other/59055 + * doc/extend.texi: Move Cilk Plus Builtins node before Other + Builtins node. + 2013-11-08 Andrew MacLeod Joseph Myers 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 -- cgit v1.2.3