summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog.melt3
-rw-r--r--gcc/ChangeLog120
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/Makefile.in2
-rw-r--r--gcc/ada/ChangeLog8
-rw-r--r--gcc/ada/gcc-interface/trans.c87
-rw-r--r--gcc/c-parser.c2
-rw-r--r--gcc/c-typeck.c2
-rw-r--r--gcc/config/mn10300/constraints.md3
-rw-r--r--gcc/config/mn10300/mn10300.c3
-rw-r--r--gcc/config/mn10300/mn10300.h8
-rw-r--r--gcc/config/mn10300/mn10300.md16
-rw-r--r--gcc/config/rs6000/rs6000.c5
-rw-r--r--gcc/config/rs6000/x-aix3
-rw-r--r--gcc/config/rs6000/xcoff.h2
-rw-r--r--gcc/coverage.c1
-rw-r--r--gcc/doc/rtl.texi104
-rw-r--r--gcc/fold-const.c1
-rw-r--r--gcc/fortran/ChangeLog5
-rw-r--r--gcc/fortran/resolve.c12
-rw-r--r--gcc/ira-build.c41
-rw-r--r--gcc/ira-costs.c4
-rw-r--r--gcc/ira-emit.c6
-rw-r--r--gcc/ira-lives.c201
-rw-r--r--gcc/java/ChangeLog8
-rw-r--r--gcc/java/Make-lang.in4
-rw-r--r--gcc/java/class.c1
-rw-r--r--gcc/java/expr.c1
-rw-r--r--gcc/sched-deps.c5
-rw-r--r--gcc/testsuite/ChangeLog33
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr37381.c97
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr37418-1.c6
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr37418-2.c6
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr37418-3.c6
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr37418-4.c6
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr37664.c14
-rw-r--r--gcc/testsuite/gcc.dg/dll-2.c4
-rw-r--r--gcc/testsuite/gcc.dg/dll-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/imag-1.c18
-rw-r--r--gcc/testsuite/gfortran.dg/elemental_intrinsic_1.f0311
-rw-r--r--gcc/tree-ssa-pre.c5
-rw-r--r--gcc/tree-ssa.c11
-rw-r--r--gcc/tree.c105
-rw-r--r--libgfortran/ChangeLog25
-rw-r--r--libgfortran/generated/spread_r4.c3
-rw-r--r--libgfortran/io/file_pos.c2
-rw-r--r--libgfortran/io/io.h2
-rw-r--r--libgfortran/io/transfer.c85
-rw-r--r--libgfortran/io/write_float.def2
-rw-r--r--libstdc++-v3/ChangeLog64
-rw-r--r--libstdc++-v3/include/bits/forward_list.h267
-rw-r--r--libstdc++-v3/include/bits/forward_list.tcc220
-rw-r--r--libstdc++-v3/testsuite/23_containers/forward_list/capacity/1.cc3
-rw-r--r--libstdc++-v3/testsuite/23_containers/forward_list/modifiers/2.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/forward_list/requirements/explicit_instantiation/1.cc36
-rw-r--r--libstdc++-v3/testsuite/23_containers/forward_list/requirements/explicit_instantiation/3.cc37
56 files changed, 1176 insertions, 556 deletions
diff --git a/ChangeLog.melt b/ChangeLog.melt
index 54bb20389e2..3eb2d615e84 100644
--- a/ChangeLog.melt
+++ b/ChangeLog.melt
@@ -1,3 +1,6 @@
+2008-10-18 Basile Starynkevitch <basile@starynkevitch.net>
+ MELT branch merged with trunk r141209
+
2008-10-15 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk r141146
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7983e984915..80b318f288a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,106 @@
+2008-10-17 Andreas Krebbel <krebbel1@de.ibm.com>
+
+ * c-parser.c (c_parser_binary_expression): Silence the
+ uninitialized variable warning emitted for binary_loc.
+
+2008-10-16 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (phi_translate_set): Add constants to phi
+ translation cache.
+
+2008-10-16 Joseph Myers <joseph@codesourcery.com>
+
+ PR c/33192
+ * c-typeck.c (build_unary_op): Use omit_one_operand for
+ IMAGPART_EXPR of real argument.
+
+2008-10-16 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/37664
+ * fold-const.c (fold_binary): When optimizing comparison with
+ highest or lowest type's value, don't consider TREE_OVERFLOW.
+
+2008-10-16 David Edelsohn <edelsohn@gnu.org>
+
+ PR target/35483
+ * Makefile.in (coverage.o): Depend on $(TM_P_H).
+ * coverage.c: Include tm_p.h.
+ * config/rs6000/x-aix (jc1): Override LDFLAGS.
+ * config/rs6000/xcoff.h (ASM_GENERATE_INTERNAL_LABEL): Strip
+ dollar signs from PREFIX.
+ * config/rs6000/rs6000.c (output_toc): Use RS6000_OUTPUT_BASENAME
+ instead of manual strip_name_encoding.
+
+2008-10-16 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/37418
+ * tree-ssa.c (useless_type_conversion_p_1): Do not treat
+ volatile qualified functions or methods as relevant.
+
+2008-10-16 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/37525
+ * tree.c (int_fits_type_p): Rewrite using double_int. Zero extend
+ sizetype unsigned constants, both in the case of C and bounds.
+
+2008-10-15 Jan Hubicka <jh@suse.cz>
+
+ * ira-emit.c (change_regs): Return false when replacing reg by
+ itself.
+
+2008-10-14 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR target/37633
+ * ira-costs.c (ira_tune_allocno_costs_and_cover_classes): Check
+ HARD_REGNO_CALL_PART_CLOBBERED.
+
+2008-10-15 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR middle-end/37535
+ * ira-lives.c (mark_early_clobbers): Remove.
+ (make_pseudo_conflict, check_and_make_def_use_conflicts,
+ check_and_make_def_conflicts,
+ make_early_clobber_and_input_conflicts,
+ mark_hard_reg_early_clobbers): New functions.
+ (process_bb_node_lives): Call
+ make_early_clobber_and_input_conflicts and
+ mark_hard_reg_early_clobbers. Make hard register inputs live
+ again.
+
+ * doc/rtl.texi (clobber): Change descriotion of RA behaviour for
+ early clobbers of pseudo-registers.
+
+2008-10-15 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR middle-end/37674
+ * ira-build.c (ira_flattening): Recalculate
+ ALLOCNO_TOTAL_NO_STACK_REG_P and ALLOCNO_TOTAL_CONFLICT_HARD_REGS
+ from the scratch instead of the propagation.
+
+2008-10-15 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * doc/rtl.texi (const_double): Remove the "addr" operand.
+ Describe CONST_DOUBLE_* macros under const_double rather
+ than const_vector.
+ (const_fixed): Fix the operand description.
+ (const): Add an @findex directive.
+ (CONST0_RTX, CONST1_RTX, CONST2_RTX): Move description
+ after the constant rtl table.
+ (fix): Combine floating-point and fixed-point descriptions.
+ Fix hyphenation.
+ * sched-deps.c (sched_analyze_2): Remove reference to
+ CONST_DOUBLE_CHAIN.
+
+2008-10-15 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * config/mn10300/mn10300.h (OUTPUT_ADDR_CONST_EXTRA): Handle
+ UNSPEC_GOTSYM_OFFs.
+ * config/mn10300/mn10300.c (legitimate_pic_operand_p): Return true
+ for UNSPEC_GOTSYM_OFFs.
+ * config/mn10300/mn10300.md (UNSPEC_GOTSYM_OFF): New unspec.
+ (add_GOT_to_pic_reg): Use it.
+ * config/mn10300/constraints.md (S): Allow UNSPEC_GOTSYM_OFF.
+
2008-10-15 Jan Sjodin <jan.sjodin@amd.com>
Harsha Jagasia <harsha.jagasia@amd.com>
@@ -64,6 +167,23 @@
already implies hard float. Also fix several insn condition
with TARGET_DFP which shall require TARGET_HARD_DFP instead.
+2008-10-15 David Edelsohn <edelsohn@gnu.org>
+
+ PR target/35483
+ Based on patches by Laurent Vivier.
+ * xcoffout.h (DBX_FINISH_STABS): Translate dollar sign to underscore.
+ * config/rs6000/rs6000-protos.h (rs6000_xcoff_strip_dollar): Declare.
+ * config/rs6000/xcoff.h (ASM_DECLARE_FUNCTION_NAME): Translate
+ dollar sign to underscore.
+ (ASM_OUTPUT_EXTERNAL): Same.
+ (ASM_OUTPUT_LABELREF): New.
+ * config/rs6000/rs6000.c (rs6000_xcoff_strip_dollar): New.
+
+ * config/rs6000/aix51.h (TARGET_USE_JCR_SECTION): Define.
+ * config/rs6000/aix52.h (TARGET_USE_JCR_SECTION): Define.
+ * config/rs6000/aix53.h (TARGET_USE_JCR_SECTION): Define.
+ * config/rs6000/aix61.h (TARGET_USE_JCR_SECTION): Define.
+
2008-10-15 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/36881
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 8f9cc3472a0..081aad70ac4 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20081015
+20081018
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 594f4b98ff9..167f1f5d253 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -2717,7 +2717,7 @@ ipa-struct-reorg.o: ipa-struct-reorg.c ipa-struct-reorg.h $(CONFIG_H) $(SYSTEM_H
coverage.o : coverage.c $(GCOV_IO_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(RTL_H) $(TREE_H) $(FLAGS_H) output.h $(REGS_H) $(EXPR_H) \
$(FUNCTION_H) $(TOPLEV_H) $(GGC_H) langhooks.h $(COVERAGE_H) gt-coverage.h \
- $(HASHTAB_H) tree-iterator.h $(CGRAPH_H) tree-pass.h gcov-io.c
+ $(HASHTAB_H) tree-iterator.h $(CGRAPH_H) tree-pass.h gcov-io.c $(TM_P_H)
cselib.o : cselib.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(REGS_H) hard-reg-set.h $(FLAGS_H) $(REAL_H) insn-config.h $(RECOG_H) \
$(EMIT_RTL_H) $(TOPLEV_H) output.h $(FUNCTION_H) cselib.h $(GGC_H) $(TM_P_H) \
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 7cbfc1b6d99..caee7260244 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,11 @@
+2008-10-17 Geert Bosch <bosch@adacore.com>
+
+ * gcc-interface/trans.c (gnat_to_gnu) <N_Slice>: Simplify expansion
+ to use only a single check instead of three, and avoid unnecessary
+ COMPOUND_EXPR.
+ (emit_check): Avoid useless COMPOUND_EXPRs and SAVE_EXPRs, sometimes
+ creating more opportunities for optimizations.
+
2008-10-13 Jakub Jelinek <jakub@redhat.com>
PR middle-end/37601
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index e4c86225fac..6ade56869d9 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -3563,32 +3563,40 @@ gnat_to_gnu (Node_Id gnat_node)
/* Get the permitted bounds. */
tree gnu_base_index_type
= TYPE_INDEX_TYPE (TYPE_DOMAIN (gnu_type));
- tree gnu_base_min_expr = TYPE_MIN_VALUE (gnu_base_index_type);
- tree gnu_base_max_expr = TYPE_MAX_VALUE (gnu_base_index_type);
+ tree gnu_base_min_expr = SUBSTITUTE_PLACEHOLDER_IN_EXPR
+ (TYPE_MIN_VALUE (gnu_base_index_type), gnu_result);
+ tree gnu_base_max_expr = SUBSTITUTE_PLACEHOLDER_IN_EXPR
+ (TYPE_MAX_VALUE (gnu_base_index_type), gnu_result);
tree gnu_expr_l, gnu_expr_h, gnu_expr_type;
- /* Check to see that the minimum slice value is in range. */
- gnu_expr_l = emit_index_check (gnu_result,
- gnu_min_expr,
- gnu_base_min_expr,
- gnu_base_max_expr);
-
- /* Check to see that the maximum slice value is in range. */
- gnu_expr_h = emit_index_check (gnu_result,
- gnu_max_expr,
- gnu_base_min_expr,
- gnu_base_max_expr);
+ gnu_min_expr = protect_multiple_eval (gnu_min_expr);
+ gnu_max_expr = protect_multiple_eval (gnu_max_expr);
/* Derive a good type to convert everything to. */
- gnu_expr_type = get_base_type (TREE_TYPE (gnu_expr_l));
-
- /* Build a compound expression that does the range checks and
- returns the low bound. */
- gnu_expr = build_binary_op (COMPOUND_EXPR, gnu_expr_type,
- convert (gnu_expr_type, gnu_expr_h),
- convert (gnu_expr_type, gnu_expr_l));
-
- /* Build a conditional expression that does the range check and
+ gnu_expr_type = get_base_type (TREE_TYPE (gnu_index_type));
+
+ /* Test whether the minimum slice value is too small. */
+ gnu_expr_l = build_binary_op (LT_EXPR, integer_type_node,
+ convert (gnu_expr_type,
+ gnu_min_expr),
+ convert (gnu_expr_type,
+ gnu_base_min_expr));
+
+ /* Test whether the maximum slice value is too large. */
+ gnu_expr_h = build_binary_op (GT_EXPR, integer_type_node,
+ convert (gnu_expr_type,
+ gnu_max_expr),
+ convert (gnu_expr_type,
+ gnu_base_max_expr));
+
+ /* Build a slice index check that returns the low bound,
+ assuming the slice is not empty. */
+ gnu_expr = emit_check
+ (build_binary_op (TRUTH_ORIF_EXPR, integer_type_node,
+ gnu_expr_l, gnu_expr_h),
+ gnu_min_expr, CE_Index_Check_Failed);
+
+ /* Build a conditional expression that does the index checks and
returns the low bound if the slice is not empty (max >= min),
and returns the naked low bound otherwise (max < min), unless
it is non-constant and the high bound is; this prevents VRP
@@ -6186,33 +6194,18 @@ emit_index_check (tree gnu_array_object,
static tree
emit_check (tree gnu_cond, tree gnu_expr, int reason)
{
- tree gnu_call;
- tree gnu_result;
+ tree gnu_call = build_call_raise (reason, Empty, N_Raise_Constraint_Error);
+ tree gnu_result
+ = fold_build3 (COND_EXPR, TREE_TYPE (gnu_expr), gnu_cond,
+ build2 (COMPOUND_EXPR, TREE_TYPE (gnu_expr), gnu_call,
+ convert (TREE_TYPE (gnu_expr), integer_zero_node)),
+ gnu_expr);
- gnu_call = build_call_raise (reason, Empty, N_Raise_Constraint_Error);
-
- /* Use an outer COMPOUND_EXPR to make sure that GNU_EXPR will get evaluated
- in front of the comparison in case it ends up being a SAVE_EXPR. Put the
- whole thing inside its own SAVE_EXPR so the inner SAVE_EXPR doesn't leak
- out. */
- gnu_result = fold_build3 (COND_EXPR, TREE_TYPE (gnu_expr), gnu_cond,
- build2 (COMPOUND_EXPR, TREE_TYPE (gnu_expr),
- gnu_call, gnu_expr),
- gnu_expr);
-
- /* If GNU_EXPR has side effects, make the outer COMPOUND_EXPR and
- protect it. Otherwise, show GNU_RESULT has no side effects: we
- don't need to evaluate it just for the check. */
- if (TREE_SIDE_EFFECTS (gnu_expr))
- gnu_result
- = build2 (COMPOUND_EXPR, TREE_TYPE (gnu_expr), gnu_expr, gnu_result);
- else
- TREE_SIDE_EFFECTS (gnu_result) = 0;
+ /* GNU_RESULT has side effects if and only if GNU_EXPR has:
+ we don't need to evaluate it just for the check. */
+ TREE_SIDE_EFFECTS (gnu_result) = TREE_SIDE_EFFECTS (gnu_expr);
- /* ??? Unfortunately, if we don't put a SAVE_EXPR around this whole thing,
- we will repeatedly do the test. It would be nice if GCC was able
- to optimize this and only do it once. */
- return save_expr (gnu_result);
+ return gnu_result;
}
/* Return an expression that converts GNU_EXPR to GNAT_TYPE, doing
diff --git a/gcc/c-parser.c b/gcc/c-parser.c
index f08b2813010..0fc579b3e98 100644
--- a/gcc/c-parser.c
+++ b/gcc/c-parser.c
@@ -4583,7 +4583,7 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after)
} stack[NUM_PRECS];
int sp;
/* Location of the binary operator. */
- location_t binary_loc;
+ location_t binary_loc = UNKNOWN_LOCATION; /* Quiet warning. */
#define POP \
do { \
switch (stack[sp].op) \
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index ab8df375448..da98c43c4bf 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -3038,7 +3038,7 @@ build_unary_op (location_t location,
else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
ret = fold_build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
else
- ret = convert (TREE_TYPE (arg), integer_zero_node);
+ ret = omit_one_operand (TREE_TYPE (arg), integer_zero_node, arg);
goto return_build_unary_op;
case PREINCREMENT_EXPR:
diff --git a/gcc/config/mn10300/constraints.md b/gcc/config/mn10300/constraints.md
index 53f128750c7..8dbf63a75ba 100644
--- a/gcc/config/mn10300/constraints.md
+++ b/gcc/config/mn10300/constraints.md
@@ -68,7 +68,8 @@
(if_then_else (match_test "flag_pic")
(and (match_test "GET_CODE (op) == UNSPEC")
(ior (match_test "XINT (op, 1) == UNSPEC_PLT")
- (match_test "XINT (op, 1) == UNSPEC_PIC")))
+ (match_test "XINT (op, 1) == UNSPEC_PIC")
+ (match_test "XINT (op, 1) == UNSPEC_GOTSYM_OFF")))
(match_test "GET_CODE (op) == SYMBOL_REF")))
;; Integer constraints
diff --git a/gcc/config/mn10300/mn10300.c b/gcc/config/mn10300/mn10300.c
index f89e0751c4c..eed82997244 100644
--- a/gcc/config/mn10300/mn10300.c
+++ b/gcc/config/mn10300/mn10300.c
@@ -1869,7 +1869,8 @@ legitimate_pic_operand_p (rtx x)
&& (XINT (x, 1) == UNSPEC_PIC
|| XINT (x, 1) == UNSPEC_GOT
|| XINT (x, 1) == UNSPEC_GOTOFF
- || XINT (x, 1) == UNSPEC_PLT))
+ || XINT (x, 1) == UNSPEC_PLT
+ || XINT (x, 1) == UNSPEC_GOTSYM_OFF))
return 1;
fmt = GET_RTX_FORMAT (GET_CODE (x));
diff --git a/gcc/config/mn10300/mn10300.h b/gcc/config/mn10300/mn10300.h
index c1c80579427..d83eedfb08a 100644
--- a/gcc/config/mn10300/mn10300.h
+++ b/gcc/config/mn10300/mn10300.h
@@ -738,7 +738,7 @@ while (0)
constants. Used for PIC-specific UNSPECs. */
#define OUTPUT_ADDR_CONST_EXTRA(STREAM, X, FAIL) \
do \
- if (GET_CODE (X) == UNSPEC && XVECLEN ((X), 0) == 1) \
+ if (GET_CODE (X) == UNSPEC) \
{ \
switch (XINT ((X), 1)) \
{ \
@@ -762,6 +762,12 @@ while (0)
output_addr_const ((STREAM), XVECEXP ((X), 0, 0)); \
fputs ("@PLT", (STREAM)); \
break; \
+ case UNSPEC_GOTSYM_OFF: \
+ assemble_name (STREAM, GOT_SYMBOL_NAME); \
+ fputs ("-(", STREAM); \
+ output_addr_const (STREAM, XVECEXP (X, 0, 0)); \
+ fputs ("-.)", STREAM); \
+ break; \
default: \
goto FAIL; \
} \
diff --git a/gcc/config/mn10300/mn10300.md b/gcc/config/mn10300/mn10300.md
index 8fbbdc87df5..38aa37645ac 100644
--- a/gcc/config/mn10300/mn10300.md
+++ b/gcc/config/mn10300/mn10300.md
@@ -45,6 +45,7 @@
(UNSPEC_GOT 2)
(UNSPEC_GOTOFF 3)
(UNSPEC_PLT 4)
+ (UNSPEC_GOTSYM_OFF 5)
])
(include "predicates.md")
@@ -2619,18 +2620,9 @@
[(set (reg:SI PIC_REG)
(plus:SI
(reg:SI PIC_REG)
- (const
- (unspec [(minus:SI
- (match_dup 1)
- (const (minus:SI
- (const (match_operand:SI 0 "" ""))
- (pc))))
- ] UNSPEC_PIC))))]
- ""
- "
-{
- operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
-}")
+ (const:SI
+ (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_GOTSYM_OFF))))]
+ "")
(define_expand "symGOT2reg"
[(match_operand:SI 0 "" "")
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 612c7d45d67..6df7aa79732 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -18097,7 +18097,6 @@ output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
{
char buf[256];
const char *name = buf;
- const char *real_name;
rtx base = x;
HOST_WIDE_INT offset = 0;
@@ -18371,12 +18370,12 @@ output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
gcc_unreachable ();
}
- real_name = (*targetm.strip_name_encoding) (name);
if (TARGET_MINIMAL_TOC)
fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
else
{
- fprintf (file, "\t.tc %s", real_name);
+ fputs ("\t.tc ", file);
+ RS6000_OUTPUT_BASENAME (file, name);
if (offset < 0)
fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
diff --git a/gcc/config/rs6000/x-aix b/gcc/config/rs6000/x-aix
index 32e7357f329..11ccb932d4b 100644
--- a/gcc/config/rs6000/x-aix
+++ b/gcc/config/rs6000/x-aix
@@ -1,3 +1,6 @@
# genautomata requires more than 256MB of data
build/genautomata : override LDFLAGS += -Wl,-bmaxdata:0x20000000
+# jc1 requires more than 256MB of data
+jc1 : override LDFLAGS += -Wl,-bmaxdata:0x20000000
+
diff --git a/gcc/config/rs6000/xcoff.h b/gcc/config/rs6000/xcoff.h
index 08e06b4a757..c8193908a97 100644
--- a/gcc/config/rs6000/xcoff.h
+++ b/gcc/config/rs6000/xcoff.h
@@ -257,7 +257,7 @@
This is suitable for output with `assemble_name'. */
#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \
- sprintf (LABEL, "*%s..%u", (PREFIX), (unsigned) (NUM))
+ sprintf (LABEL, "*%s..%u", rs6000_xcoff_strip_dollar (PREFIX), (unsigned) (NUM))
/* This is how to output an assembler line to define N characters starting
at P to FILE. */
diff --git a/gcc/coverage.c b/gcc/coverage.c
index 2d4f791bc58..b2ac87651d3 100644
--- a/gcc/coverage.c
+++ b/gcc/coverage.c
@@ -38,6 +38,7 @@ along with GCC; see the file COPYING3. If not see
#include "expr.h"
#include "function.h"
#include "toplev.h"
+#include "tm_p.h"
#include "ggc.h"
#include "coverage.h"
#include "langhooks.h"
diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi
index a12de2152bb..1411f24e5d9 100644
--- a/gcc/doc/rtl.texi
+++ b/gcc/doc/rtl.texi
@@ -1507,21 +1507,33 @@ Similarly, there is only one object for the integer whose value is
@code{constm1_rtx} will point to the same object.
@findex const_double
-@item (const_double:@var{m} @var{addr} @var{i0} @var{i1} @dots{})
+@item (const_double:@var{m} @var{i0} @var{i1} @dots{})
Represents either a floating-point constant of mode @var{m} or an
integer constant too large to fit into @code{HOST_BITS_PER_WIDE_INT}
bits but small enough to fit within twice that number of bits (GCC
does not provide a mechanism to represent even larger constants). In
the latter case, @var{m} will be @code{VOIDmode}.
+@findex CONST_DOUBLE_LOW
+If @var{m} is @code{VOIDmode}, the bits of the value are stored in
+@var{i0} and @var{i1}. @var{i0} is customarily accessed with the macro
+@code{CONST_DOUBLE_LOW} and @var{i1} with @code{CONST_DOUBLE_HIGH}.
+
+If the constant is floating point (regardless of its precision), then
+the number of integers used to store the value depends on the size of
+@code{REAL_VALUE_TYPE} (@pxref{Floating Point}). The integers
+represent a floating point number, but not precisely in the target
+machine's or host machine's floating point format. To convert them to
+the precise bit pattern used by the target machine, use the macro
+@code{REAL_VALUE_TO_TARGET_DOUBLE} and friends (@pxref{Data Output}).
+
@findex const_fixed
-@item (const_fixed:@var{m} @var{addr})
+@item (const_fixed:@var{m} @dots{})
Represents a fixed-point constant of mode @var{m}.
-The data structure, which contains data with the size of two
-@code{HOST_BITS_PER_WIDE_INT} and the associated fixed-point mode,
-is access with the macro @code{CONST_FIXED_VALUE}. The high part of data
-is accessed with @code{CONST_FIXED_VALUE_HIGH}; the low part is accessed
-with @code{CONST_FIXED_VALUE_LOW}.
+The operand is a data structure of type @code{struct fixed_value} and
+is accessed with the macro @code{CONST_FIXED_VALUE}. The high part of
+data is accessed with @code{CONST_FIXED_VALUE_HIGH}; the low part is
+accessed with @code{CONST_FIXED_VALUE_LOW}.
@findex const_vector
@item (const_vector:@var{m} [@var{x0} @var{x1} @dots{}])
@@ -1537,44 +1549,6 @@ Individual elements in a vector constant are accessed with the macro
where @var{v} is the vector constant and @var{n} is the element
desired.
-@findex CONST_DOUBLE_MEM
-@findex CONST_DOUBLE_CHAIN
-@var{addr} is used to contain the @code{mem} expression that corresponds
-to the location in memory that at which the constant can be found. If
-it has not been allocated a memory location, but is on the chain of all
-@code{const_double} expressions in this compilation (maintained using an
-undisplayed field), @var{addr} contains @code{const0_rtx}. If it is not
-on the chain, @var{addr} contains @code{cc0_rtx}. @var{addr} is
-customarily accessed with the macro @code{CONST_DOUBLE_MEM} and the
-chain field via @code{CONST_DOUBLE_CHAIN}.
-
-@findex CONST_DOUBLE_LOW
-If @var{m} is @code{VOIDmode}, the bits of the value are stored in
-@var{i0} and @var{i1}. @var{i0} is customarily accessed with the macro
-@code{CONST_DOUBLE_LOW} and @var{i1} with @code{CONST_DOUBLE_HIGH}.
-
-If the constant is floating point (regardless of its precision), then
-the number of integers used to store the value depends on the size of
-@code{REAL_VALUE_TYPE} (@pxref{Floating Point}). The integers
-represent a floating point number, but not precisely in the target
-machine's or host machine's floating point format. To convert them to
-the precise bit pattern used by the target machine, use the macro
-@code{REAL_VALUE_TO_TARGET_DOUBLE} and friends (@pxref{Data Output}).
-
-@findex CONST0_RTX
-@findex CONST1_RTX
-@findex CONST2_RTX
-The macro @code{CONST0_RTX (@var{mode})} refers to an expression with
-value 0 in mode @var{mode}. If mode @var{mode} is of mode class
-@code{MODE_INT}, it returns @code{const0_rtx}. If mode @var{mode} is of
-mode class @code{MODE_FLOAT}, it returns a @code{CONST_DOUBLE}
-expression in mode @var{mode}. Otherwise, it returns a
-@code{CONST_VECTOR} expression in mode @var{mode}. Similarly, the macro
-@code{CONST1_RTX (@var{mode})} refers to an expression with value 1 in
-mode @var{mode} and similarly for @code{CONST2_RTX}. The
-@code{CONST1_RTX} and @code{CONST2_RTX} macros are undefined
-for vector modes.
-
@findex const_string
@item (const_string @var{str})
Represents a constant string with value @var{str}. Currently this is
@@ -1605,6 +1579,7 @@ references is so that jump optimization can distinguish them.
The @code{label_ref} contains a mode, which is usually @code{Pmode}.
Usually that is the only mode for which a label is directly valid.
+@findex const
@item (const:@var{m} @var{exp})
Represents a constant that is the result of an assembly-time
arithmetic computation. The operand, @var{exp}, is an expression that
@@ -1627,6 +1602,20 @@ reference a global memory location.
@var{m} should be @code{Pmode}.
@end table
+@findex CONST0_RTX
+@findex CONST1_RTX
+@findex CONST2_RTX
+The macro @code{CONST0_RTX (@var{mode})} refers to an expression with
+value 0 in mode @var{mode}. If mode @var{mode} is of mode class
+@code{MODE_INT}, it returns @code{const0_rtx}. If mode @var{mode} is of
+mode class @code{MODE_FLOAT}, it returns a @code{CONST_DOUBLE}
+expression in mode @var{mode}. Otherwise, it returns a
+@code{CONST_VECTOR} expression in mode @var{mode}. Similarly, the macro
+@code{CONST1_RTX (@var{mode})} refers to an expression with value 1 in
+mode @var{mode} and similarly for @code{CONST2_RTX}. The
+@code{CONST1_RTX} and @code{CONST2_RTX} macros are undefined
+for vector modes.
+
@node Regs and Memory
@section Registers and Memory
@cindex RTL register expressions
@@ -2707,7 +2696,12 @@ regarded as unsigned, to floating point mode @var{m}.
@findex fix
@item (fix:@var{m} @var{x})
-When @var{m} is a fixed point mode, represents the result of
+When @var{m} is a floating-point mode, represents the result of
+converting floating point value @var{x} (valid for mode @var{m}) to an
+integer, still represented in floating point mode @var{m}, by rounding
+towards zero.
+
+When @var{m} is a fixed-point mode, represents the result of
converting floating point value @var{x} to mode @var{m}, regarded as
signed. How rounding is done is not specified, so this operation may
be used validly in compiling C code only for integer-valued operands.
@@ -2718,13 +2712,6 @@ Represents the result of converting floating point value @var{x} to
fixed point mode @var{m}, regarded as unsigned. How rounding is done
is not specified.
-@findex fix
-@item (fix:@var{m} @var{x})
-When @var{m} is a floating point mode, represents the result of
-converting floating point value @var{x} (valid for mode @var{m}) to an
-integer, still represented in floating point mode @var{m}, by rounding
-towards zero.
-
@findex fract_convert
@item (fract_convert:@var{m} @var{x})
Represents the result of converting fixed-point value @var{x} to
@@ -2930,11 +2917,12 @@ constituent instructions might not.
When a @code{clobber} expression for a register appears inside a
@code{parallel} with other side effects, the register allocator
guarantees that the register is unoccupied both before and after that
-insn if it is a hard register clobber or the @samp{&} constraint
-is specified for at least one alternative (@pxref{Modifiers}) of the
-clobber. However, the reload phase may allocate a register used for
-one of the inputs unless the @samp{&} constraint is specified for the
-selected alternative. You can clobber either a specific hard
+insn if it is a hard register clobber. For pseudo-register clobber,
+the register allocator and the reload pass do not assign the same hard
+register to the clobber and the input operands if there is an insn
+alternative containing the @samp{&} constraint (@pxref{Modifiers}) for
+the clobber and the hard register is in register classes of the
+clobber in the alternative. You can clobber either a specific hard
register, a pseudo register, or a @code{scratch} expression; in the
latter two cases, GCC will allocate a hard register that is available
there for use as a temporary.
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 0ce122a1554..605caa812e0 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -12447,7 +12447,6 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
unsigned int width = TYPE_PRECISION (arg1_type);
if (TREE_CODE (arg1) == INTEGER_CST
- && !TREE_OVERFLOW (arg1)
&& width <= 2 * HOST_BITS_PER_WIDE_INT
&& (INTEGRAL_TYPE_P (arg1_type) || POINTER_TYPE_P (arg1_type)))
{
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 1d26c1f2c97..d4ff6b34c30 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,8 @@
+2008-10-16 Daniel Kraft <d@domob.eu>
+
+ * resolve.c (resolve_elemental_actual): Handle calls to intrinsic
+ subroutines correctly.
+
2008-10-13 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* simplify.c: Remove MPFR_VERSION_NUM(2,3,0) conditionals.
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 70d3ad5df99..1816907c3ec 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -1352,10 +1352,18 @@ resolve_elemental_actual (gfc_expr *expr, gfc_code *c)
else
return SUCCESS;
}
- else if (c && c->ext.actual != NULL && c->symtree->n.sym->attr.elemental)
+ else if (c && c->ext.actual != NULL)
{
arg0 = c->ext.actual;
- esym = c->symtree->n.sym;
+
+ if (c->resolved_sym)
+ esym = c->resolved_sym;
+ else
+ esym = c->symtree->n.sym;
+ gcc_assert (esym);
+
+ if (!esym->attr.elemental)
+ return SUCCESS;
}
else
return SUCCESS;
diff --git a/gcc/ira-build.c b/gcc/ira-build.c
index 55a3beb71bd..3d58e5521ad 100644
--- a/gcc/ira-build.c
+++ b/gcc/ira-build.c
@@ -2102,7 +2102,7 @@ void
ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit)
{
int i, j, num;
- bool propagate_p, stop_p, keep_p;
+ bool stop_p, keep_p;
int hard_regs_num;
bool new_pseudos_p, merged_p, mem_dest_p;
unsigned int n;
@@ -2114,20 +2114,29 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit)
ira_allocno_iterator ai;
ira_copy_iterator ci;
sparseset allocnos_live;
- bool *allocno_propagated_p;
regno_top_level_allocno_map
= (ira_allocno_t *) ira_allocate (max_reg_num () * sizeof (ira_allocno_t));
memset (regno_top_level_allocno_map, 0,
max_reg_num () * sizeof (ira_allocno_t));
- allocno_propagated_p
- = (bool *) ira_allocate (ira_allocnos_num * sizeof (bool));
- memset (allocno_propagated_p, 0, ira_allocnos_num * sizeof (bool));
new_pseudos_p = merged_p = false;
+ FOR_EACH_ALLOCNO (a, ai)
+ {
+ if (ALLOCNO_CAP_MEMBER (a) != NULL)
+ /* Caps are not in the regno allocno maps and they are never
+ will be transformed into allocnos existing after IR
+ flattening. */
+ continue;
+ COPY_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a),
+ ALLOCNO_CONFLICT_HARD_REGS (a));
+#ifdef STACK_REGS
+ ALLOCNO_TOTAL_NO_STACK_REG_P (a) = ALLOCNO_NO_STACK_REG_P (a);
+#endif
+ }
/* Fix final allocno attributes. */
for (i = max_regno_before_emit - 1; i >= FIRST_PSEUDO_REGISTER; i--)
{
- mem_dest_p = propagate_p = false;
+ mem_dest_p = false;
for (a = ira_regno_allocno_map[i];
a != NULL;
a = ALLOCNO_NEXT_REGNO_ALLOCNO (a))
@@ -2145,27 +2154,17 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit)
continue;
}
ira_assert (ALLOCNO_CAP_MEMBER (parent_a) == NULL);
+
if (ALLOCNO_MEM_OPTIMIZED_DEST (a) != NULL)
mem_dest_p = true;
- if (propagate_p)
+ if (REGNO (ALLOCNO_REG (a)) == REGNO (ALLOCNO_REG (parent_a)))
{
- if (!allocno_propagated_p [ALLOCNO_NUM (parent_a)])
- COPY_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (parent_a),
- ALLOCNO_CONFLICT_HARD_REGS (parent_a));
IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (parent_a),
ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a));
#ifdef STACK_REGS
- if (!allocno_propagated_p [ALLOCNO_NUM (parent_a)])
- ALLOCNO_TOTAL_NO_STACK_REG_P (parent_a)
- = ALLOCNO_NO_STACK_REG_P (parent_a);
- ALLOCNO_TOTAL_NO_STACK_REG_P (parent_a)
- = (ALLOCNO_TOTAL_NO_STACK_REG_P (parent_a)
- || ALLOCNO_TOTAL_NO_STACK_REG_P (a));
+ if (ALLOCNO_TOTAL_NO_STACK_REG_P (a))
+ ALLOCNO_TOTAL_NO_STACK_REG_P (parent_a) = true;
#endif
- allocno_propagated_p [ALLOCNO_NUM (parent_a)] = true;
- }
- if (REGNO (ALLOCNO_REG (a)) == REGNO (ALLOCNO_REG (parent_a)))
- {
if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL)
{
fprintf (ira_dump_file,
@@ -2188,7 +2187,6 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit)
continue;
}
new_pseudos_p = true;
- propagate_p = true;
first = ALLOCNO_MEM_OPTIMIZED_DEST (a) == NULL ? NULL : a;
stop_p = false;
for (;;)
@@ -2240,7 +2238,6 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit)
if (mem_dest_p && copy_live_ranges_to_removed_store_destinations (i))
merged_p = true;
}
- ira_free (allocno_propagated_p);
ira_assert (new_pseudos_p || ira_max_point_before_emit == ira_max_point);
if (merged_p || ira_max_point_before_emit != ira_max_point)
ira_rebuild_start_finish_chains ();
diff --git a/gcc/ira-costs.c b/gcc/ira-costs.c
index 774902035e1..64b2e7995d6 100644
--- a/gcc/ira-costs.c
+++ b/gcc/ira-costs.c
@@ -1572,8 +1572,8 @@ ira_tune_allocno_costs_and_cover_classes (void)
regno = ira_class_hard_regs[cover_class][j];
rclass = REGNO_REG_CLASS (regno);
cost = 0;
- /* ??? If only part is call clobbered. */
- if (! ira_hard_reg_not_in_set_p (regno, mode, call_used_reg_set))
+ if (! ira_hard_reg_not_in_set_p (regno, mode, call_used_reg_set)
+ || HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))
cost += (ALLOCNO_CALL_FREQ (a)
* (ira_memory_move_cost[mode][rclass][0]
+ ira_memory_move_cost[mode][rclass][1]));
diff --git a/gcc/ira-emit.c b/gcc/ira-emit.c
index 7fdaefb52e5..a6a7582f519 100644
--- a/gcc/ira-emit.c
+++ b/gcc/ira-emit.c
@@ -137,6 +137,7 @@ change_regs (rtx *loc)
int i, regno, result = false;
const char *fmt;
enum rtx_code code;
+ rtx reg;
if (*loc == NULL_RTX)
return false;
@@ -151,7 +152,10 @@ change_regs (rtx *loc)
return false;
if (ira_curr_regno_allocno_map[regno] == NULL)
return false;
- *loc = ALLOCNO_REG (ira_curr_regno_allocno_map[regno]);
+ reg = ALLOCNO_REG (ira_curr_regno_allocno_map[regno]);
+ if (reg == *loc)
+ return false;
+ *loc = reg;
return true;
}
diff --git a/gcc/ira-lives.c b/gcc/ira-lives.c
index 89343fe30f3..f4b2d6de42b 100644
--- a/gcc/ira-lives.c
+++ b/gcc/ira-lives.c
@@ -349,39 +349,169 @@ mark_ref_dead (df_ref def)
mark_reg_dead (reg);
}
-/* Mark early clobber registers of the current INSN as live (if
- LIVE_P) or dead. Return true if there are such registers. */
+/* Make pseudo REG conflicting with pseudo DREG, if the 1st pseudo
+ class is intersected with class CL. Advance the current program
+ point before making the conflict if ADVANCE_P. Return TRUE if we
+ will need to advance the current program point. */
static bool
-mark_early_clobbers (rtx insn, bool live_p)
+make_pseudo_conflict (rtx reg, enum reg_class cl, rtx dreg, bool advance_p)
{
- int alt;
- int def;
- df_ref *def_rec;
- bool set_p = false;
+ ira_allocno_t a;
- for (def = 0; def < recog_data.n_operands; def++)
- {
- rtx dreg = recog_data.operand[def];
-
- if (GET_CODE (dreg) == SUBREG)
- dreg = SUBREG_REG (dreg);
- if (! REG_P (dreg))
- continue;
+ if (GET_CODE (reg) == SUBREG)
+ reg = SUBREG_REG (reg);
+
+ if (! REG_P (reg) || REGNO (reg) < FIRST_PSEUDO_REGISTER)
+ return advance_p;
+
+ a = ira_curr_regno_allocno_map[REGNO (reg)];
+ if (! reg_classes_intersect_p (cl, ALLOCNO_COVER_CLASS (a)))
+ return advance_p;
- for (alt = 0; alt < recog_data.n_alternatives; alt++)
- if ((recog_op_alt[def][alt].earlyclobber)
- && (recog_op_alt[def][alt].cl != NO_REGS))
- break;
+ if (advance_p)
+ curr_point++;
- if (alt >= recog_data.n_alternatives)
- continue;
+ mark_reg_live (reg);
+ mark_reg_live (dreg);
+ mark_reg_dead (reg);
+ mark_reg_dead (dreg);
+
+ return false;
+}
- if (live_p)
- mark_reg_live (dreg);
+/* Check and make if necessary conflicts for pseudo DREG of class
+ DEF_CL of the current insn with input operand USE of class USE_CL.
+ Advance the current program point before making the conflict if
+ ADVANCE_P. Return TRUE if we will need to advance the current
+ program point. */
+static bool
+check_and_make_def_use_conflict (rtx dreg, enum reg_class def_cl,
+ int use, enum reg_class use_cl,
+ bool advance_p)
+{
+ if (! reg_classes_intersect_p (def_cl, use_cl))
+ return advance_p;
+
+ advance_p = make_pseudo_conflict (recog_data.operand[use],
+ use_cl, dreg, advance_p);
+ /* Reload may end up swapping commutative operands, so you
+ have to take both orderings into account. The
+ constraints for the two operands can be completely
+ different. (Indeed, if the constraints for the two
+ operands are the same for all alternatives, there's no
+ point marking them as commutative.) */
+ if (use < recog_data.n_operands + 1
+ && recog_data.constraints[use][0] == '%')
+ advance_p
+ = make_pseudo_conflict (recog_data.operand[use + 1],
+ use_cl, dreg, advance_p);
+ if (use >= 1
+ && recog_data.constraints[use - 1][0] == '%')
+ advance_p
+ = make_pseudo_conflict (recog_data.operand[use - 1],
+ use_cl, dreg, advance_p);
+ return advance_p;
+}
+
+/* Check and make if necessary conflicts for definition DEF of class
+ DEF_CL of the current insn with input operands. Process only
+ constraints of alternative ALT. */
+static void
+check_and_make_def_conflict (int alt, int def, enum reg_class def_cl)
+{
+ int use, use_match;
+ ira_allocno_t a;
+ enum reg_class use_cl, acl;
+ bool advance_p;
+ rtx dreg = recog_data.operand[def];
+
+ if (def_cl == NO_REGS)
+ return;
+
+ if (GET_CODE (dreg) == SUBREG)
+ dreg = SUBREG_REG (dreg);
+
+ if (! REG_P (dreg) || REGNO (dreg) < FIRST_PSEUDO_REGISTER)
+ return;
+
+ a = ira_curr_regno_allocno_map[REGNO (dreg)];
+ acl = ALLOCNO_COVER_CLASS (a);
+ if (! reg_classes_intersect_p (acl, def_cl))
+ return;
+
+ advance_p = true;
+
+ for (use = 0; use < recog_data.n_operands; use++)
+ {
+ if (use == def || recog_data.operand_type[use] == OP_OUT)
+ return;
+
+ if (recog_op_alt[use][alt].anything_ok)
+ use_cl = ALL_REGS;
else
- mark_reg_dead (dreg);
- set_p = true;
+ use_cl = recog_op_alt[use][alt].cl;
+
+ advance_p = check_and_make_def_use_conflict (dreg, def_cl, use,
+ use_cl, advance_p);
+
+ if ((use_match = recog_op_alt[use][alt].matches) >= 0)
+ {
+ if (use_match == def)
+ return;
+
+ if (recog_op_alt[use_match][alt].anything_ok)
+ use_cl = ALL_REGS;
+ else
+ use_cl = recog_op_alt[use_match][alt].cl;
+ advance_p = check_and_make_def_use_conflict (dreg, def_cl, use,
+ use_cl, advance_p);
+ }
}
+}
+
+/* Make conflicts of early clobber pseudo registers of the current
+ insn with its inputs. Avoid introducing unnecessary conflicts by
+ checking classes of the constraints and pseudos because otherwise
+ significant code degradation is possible for some targets. */
+static void
+make_early_clobber_and_input_conflicts (void)
+{
+ int alt;
+ int def, def_match;
+ enum reg_class def_cl;
+
+ for (alt = 0; alt < recog_data.n_alternatives; alt++)
+ for (def = 0; def < recog_data.n_operands; def++)
+ {
+ def_cl = NO_REGS;
+ if (recog_op_alt[def][alt].earlyclobber)
+ {
+ if (recog_op_alt[def][alt].anything_ok)
+ def_cl = ALL_REGS;
+ else
+ def_cl = recog_op_alt[def][alt].cl;
+ check_and_make_def_conflict (alt, def, def_cl);
+ }
+ if ((def_match = recog_op_alt[def][alt].matches) >= 0
+ && (recog_op_alt[def_match][alt].earlyclobber
+ || recog_op_alt[def][alt].earlyclobber))
+ {
+ if (recog_op_alt[def_match][alt].anything_ok)
+ def_cl = ALL_REGS;
+ else
+ def_cl = recog_op_alt[def_match][alt].cl;
+ check_and_make_def_conflict (alt, def, def_cl);
+ }
+ }
+}
+
+/* Mark early clobber hard registers of the current INSN as live (if
+ LIVE_P) or dead. Return true if there are such registers. */
+static bool
+mark_hard_reg_early_clobbers (rtx insn, bool live_p)
+{
+ df_ref *def_rec;
+ bool set_p = false;
for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++)
if (DF_REF_FLAGS_IS_SET (*def_rec, DF_REF_MUST_CLOBBER))
@@ -792,25 +922,36 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
}
}
+ make_early_clobber_and_input_conflicts ();
+
curr_point++;
/* Mark each used value as live. */
for (use_rec = DF_INSN_USES (insn); *use_rec; use_rec++)
mark_ref_live (*use_rec);
- set_p = mark_early_clobbers (insn, true);
-
process_single_reg_class_operands (true, freq);
+ set_p = mark_hard_reg_early_clobbers (insn, true);
+
if (set_p)
{
- mark_early_clobbers (insn, false);
+ mark_hard_reg_early_clobbers (insn, false);
- /* Mark each used value as live again. For example, a
+ /* Mark each hard reg as live again. For example, a
hard register can be in clobber and in an insn
input. */
for (use_rec = DF_INSN_USES (insn); *use_rec; use_rec++)
- mark_ref_live (*use_rec);
+ {
+ rtx ureg = DF_REF_REG (*use_rec);
+
+ if (GET_CODE (ureg) == SUBREG)
+ ureg = SUBREG_REG (ureg);
+ if (! REG_P (ureg) || REGNO (ureg) >= FIRST_PSEUDO_REGISTER)
+ continue;
+
+ mark_ref_live (*use_rec);
+ }
}
curr_point++;
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index d987bbe71b7..40454a0f5dd 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,11 @@
+2008-10-16 David Edelsohn <edelsohn@gnu.org>
+
+ PR target/35483
+ * Make-lang.in (class.o): Depend on $(TM_P_H).
+ (expr.o): Same.
+ * class.c: Include tm_p.h.
+ * expr.c: Include tm_p.h.
+
2008-10-14 Andrew Haley <aph@redhat.com>
* constants.c (build_constant_data_ref): Make sure we only build
diff --git a/gcc/java/Make-lang.in b/gcc/java/Make-lang.in
index f188c7d788d..2db3065f629 100644
--- a/gcc/java/Make-lang.in
+++ b/gcc/java/Make-lang.in
@@ -256,7 +256,7 @@ java/builtins.o: java/builtins.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
gt-java-builtins.h
java/class.o: java/class.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(JAVA_TREE_H) $(RTL_H) java/jcf.h java/parse.h toplev.h output.h $(GGC_H) \
- $(TARGET_H) $(FUNCTION_H) gt-java-class.h $(CGRAPH_H)
+ $(TARGET_H) $(FUNCTION_H) gt-java-class.h $(CGRAPH_H) $(TM_P_H)
java/constants.o: java/constants.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h \
toplev.h $(SYSTEM_H) coretypes.h $(TM_H) $(GGC_H) gt-java-constants.h
java/decl.o: java/decl.c $(CONFIG_H) $(JAVA_TREE_H) $(RTL_H) java/jcf.h \
@@ -270,7 +270,7 @@ java/expr.o: java/expr.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h $(REAL_H) \
$(RTL_H) $(EXPR_H) java/javaop.h java/java-opcodes.h except.h \
java/java-except.h java/java-except.h java/parse.h toplev.h \
$(SYSTEM_H) coretypes.h $(TM_H) $(GGC_H) gt-java-expr.h $(TARGET_H) \
- tree-iterator.h
+ tree-iterator.h $(TM_P_H)
java/jcf-depend.o: java/jcf-depend.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) java/jcf.h
java/jcf-parse.o: java/jcf-parse.c $(CONFIG_H) $(JAVA_TREE_H) $(FLAGS_H) \
diff --git a/gcc/java/class.c b/gcc/java/class.c
index 13cc54e024d..edd16f0ad61 100644
--- a/gcc/java/class.c
+++ b/gcc/java/class.c
@@ -38,6 +38,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "output.h"
#include "parse.h"
#include "function.h"
+#include "tm_p.h"
#include "ggc.h"
#include "stdio.h"
#include "target.h"
diff --git a/gcc/java/expr.c b/gcc/java/expr.c
index e1c00824248..858bc937d93 100644
--- a/gcc/java/expr.c
+++ b/gcc/java/expr.c
@@ -41,6 +41,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "parse.h"
#include "toplev.h"
#include "except.h"
+#include "tm_p.h"
#include "ggc.h"
#include "tree-iterator.h"
#include "gimple.h"
diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c
index 784f84ff63d..81fcb806228 100644
--- a/gcc/sched-deps.c
+++ b/gcc/sched-deps.c
@@ -2008,10 +2008,7 @@ sched_analyze_2 (struct deps *deps, rtx x, rtx insn)
case SYMBOL_REF:
case CONST:
case LABEL_REF:
- /* Ignore constants. Note that we must handle CONST_DOUBLE here
- because it may have a cc0_rtx in its CONST_DOUBLE_CHAIN field, but
- this does not mean that this insn is using cc0. */
-
+ /* Ignore constants. */
if (cslr_p && sched_deps_info->finish_rhs)
sched_deps_info->finish_rhs ();
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8cee6d05feb..5c14eceddbf 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,36 @@
+2008-10-18 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * gcc.dg/dll-2.c: Revert 2008-08-09 change (R138893): Change
+ "dg-message" back to "dg-warning".
+ * gcc.dg/dll-3.c: Likewise.
+
+2008-10-16 Alexander Monakov <amonakov@ispras.ru>
+
+ PR target/37381
+ * gcc.c-torture/compile/pr37381.c: New test.
+
+2008-10-16 Joseph Myers <joseph@codesourcery.com>
+
+ PR c/33192
+ * gcc.dg/imag-1.c: New test.
+
+2008-10-16 Daniel Kraft <d@domob.eu>
+
+ * gfortran.dg/elemental_intrinsic_1.f03: New test.
+
+2008-10-16 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/37664
+ * gcc.c-torture/compile/pr37664.c: New test.
+
+2008-10-16 Joseph Myers <joseph@codesourcery.com>
+
+ PR middle-end/37418
+ * gcc.c-torture/compile/pr37418-1.c,
+ gcc.c-torture/compile/pr37418-2.c,
+ gcc.c-torture/compile/pr37418-3.c,
+ gcc.c-torture/compile/pr37418-4.c: New tests.
+
2008-10-15 Thomas Koenig <tkoenig@gcc.gnu.org>
PR libfortran/34670
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr37381.c b/gcc/testsuite/gcc.c-torture/compile/pr37381.c
new file mode 100644
index 00000000000..a2fed66c4ee
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr37381.c
@@ -0,0 +1,97 @@
+extern unsigned int __invalid_size_argument_for_IOC;
+typedef unsigned int __u32;
+struct video_window
+{
+ __u32 x, y;
+ __u32 width, height;
+};
+typedef unsigned long XID;
+typedef XID Window;
+typedef struct _XExtData
+{
+ Window root;
+}
+Screen;
+typedef struct
+{
+ int border_width;
+}
+XWindowAttributes;
+typedef struct _XDisplay Display;
+typedef struct
+{
+ int default_screen;
+ Screen *screens;
+}
+ *_XPrivDisplay;
+typedef struct
+{
+ int x, y;
+}
+XSizeHints;
+typedef struct
+{
+ unsigned short hdisplay;
+ unsigned short vdisplay;
+}
+XF86VidModeModeInfo;
+Display *display;
+int tfd;
+int ccapt;
+int tml;
+int fswidth = 0;
+int fsheight = 0;
+Window fmwin;
+XF86VidModeModeInfo **modelines, *fullscreenmode = ((void *) 0);
+struct video_window vswin;
+DoFullScreen (void)
+{
+ int i;
+ int rx, ry;
+ Window junkwin;
+ XSizeHints fmsizehints;
+ XWindowAttributes fmwinattr;
+ if (ioctl
+ (tfd,
+ (((1U) << (((0 + 8) + 8) + 14)) | ((('v')) << (0 + 8)) | (((8)) << 0) |
+ (((((sizeof (int) == sizeof (int[1])
+ && sizeof (int) <
+ (1 << 14)) ? sizeof (int) : __invalid_size_argument_for_IOC))) <<
+ ((0 + 8) + 8))), &ccapt) < 0)
+ {
+ perror ("ioctl VIDIOCCAPTURE");
+ }
+ if (!XTranslateCoordinates
+ (display, fmwin,
+ ((&((_XPrivDisplay) display)->
+ screens[(((_XPrivDisplay) display)->default_screen)])->root),
+ -fmwinattr.border_width, -fmwinattr.border_width, &rx, &ry, &junkwin))
+ {
+ }
+ vswin.width = fswidth;
+ vswin.height = fsheight;
+ vswin.x = fmsizehints.x + rx;
+ vswin.y = fmsizehints.y + ry;
+ if (ioctl
+ (tfd,
+ (((1U) << (((0 + 8) + 8) + 14)) | ((('v')) << (0 + 8)) | (((8)) << 0) |
+ (((((sizeof (int) == sizeof (int[1])
+ && sizeof (int) <
+ (1 << 14)) ? sizeof (int) : __invalid_size_argument_for_IOC))) <<
+ ((0 + 8) + 8))), &ccapt) < 0)
+ {
+ XF86VidModeGetAllModeLines (display, XDefaultScreen (display), &tml,
+ &modelines);
+ {
+ if ((modelines[i]->hdisplay == fswidth)
+ && (modelines[i]->vdisplay == fsheight))
+ {
+ fullscreenmode = modelines[i];
+ }
+ }
+ {
+ XF86VidModeSetViewPort (display, XDefaultScreen (display), vswin.x,
+ vswin.y);
+ }
+ }
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr37418-1.c b/gcc/testsuite/gcc.c-torture/compile/pr37418-1.c
new file mode 100644
index 00000000000..dbb1a651ddb
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr37418-1.c
@@ -0,0 +1,6 @@
+typedef void ft(int);
+void f(int args)__attribute__((noreturn));
+void f2(ft *p __attribute__((noreturn)))
+{
+ p = f;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr37418-2.c b/gcc/testsuite/gcc.c-torture/compile/pr37418-2.c
new file mode 100644
index 00000000000..dcc003984ac
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr37418-2.c
@@ -0,0 +1,6 @@
+typedef void ft(int);
+volatile ft f;
+void f2(ft *p __attribute__((noreturn)))
+{
+ p = f;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr37418-3.c b/gcc/testsuite/gcc.c-torture/compile/pr37418-3.c
new file mode 100644
index 00000000000..5a2c2e81ead
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr37418-3.c
@@ -0,0 +1,6 @@
+typedef void ft(int);
+void f(int args)__attribute__((const));
+void f2(ft *p __attribute__((const)))
+{
+ p = f;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr37418-4.c b/gcc/testsuite/gcc.c-torture/compile/pr37418-4.c
new file mode 100644
index 00000000000..bc872789004
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr37418-4.c
@@ -0,0 +1,6 @@
+typedef void ft(int);
+const ft f;
+void f2(ft *p __attribute__((const)))
+{
+ p = f;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr37664.c b/gcc/testsuite/gcc.c-torture/compile/pr37664.c
new file mode 100644
index 00000000000..cf5c83d7b2d
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr37664.c
@@ -0,0 +1,14 @@
+/* PR tree-optimization/37664 */
+
+int v;
+
+int
+foo ()
+{
+ int a = 0x8899A862;
+ int b = 0x8E * a;
+ int c = (b % b);
+ if (v > (4294967295U >> c))
+ return v;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/dll-2.c b/gcc/testsuite/gcc.dg/dll-2.c
index 334299f3a27..3b8b60eee41 100644
--- a/gcc/testsuite/gcc.dg/dll-2.c
+++ b/gcc/testsuite/gcc.dg/dll-2.c
@@ -11,12 +11,12 @@
/* { dg-require-dll "" } */
__declspec (dllimport) int foo1 ();
-__declspec (dllexport) int foo1 (); /* { dg-message "note: previous dllimport ignored" } */
+__declspec (dllexport) int foo1 (); /* { dg-warning "previous dllimport ignored" } */
__declspec (dllexport) int foo2 ();
__declspec (dllimport) int foo2 (); /* { dg-warning "dllimport ignored" } */
__declspec (dllimport) int bar1;
-__declspec (dllexport) int bar1; /* { dg-message "note: previous dllimport ignored" } */
+__declspec (dllexport) int bar1; /* { dg-warning "previous dllimport ignored" } */
__declspec (dllexport) int bar2;
__declspec (dllimport) int bar2; /* { dg-warning "dllimport ignored" } */
diff --git a/gcc/testsuite/gcc.dg/dll-3.c b/gcc/testsuite/gcc.dg/dll-3.c
index 4272891a848..0a3f7df0988 100644
--- a/gcc/testsuite/gcc.dg/dll-3.c
+++ b/gcc/testsuite/gcc.dg/dll-3.c
@@ -5,7 +5,7 @@
/* { dg-do compile { target i?86-pc-mingw* } } */
__declspec (dllimport) int foo1 ();
-__declspec (dllexport) int foo1 (); /* { dg-message "note: previous dllimport ignored" } */
+__declspec (dllexport) int foo1 (); /* { dg-warning "previous dllimport ignored" } */
__declspec (dllexport) int foo2 ();
__declspec (dllimport) int foo2 (); /* { dg-warning "dllimport ignored" } */
diff --git a/gcc/testsuite/gcc.dg/imag-1.c b/gcc/testsuite/gcc.dg/imag-1.c
new file mode 100644
index 00000000000..e07ef72e43c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/imag-1.c
@@ -0,0 +1,18 @@
+/* Test for __imag__ side effects; see PR 33192. */
+/* Origin: Joseph Myers <joseph@codesourcery.com> */
+/* { dg-do run } */
+/* { dg-options "-std=gnu99" } */
+
+extern void abort (void);
+extern void exit (int);
+
+int
+main (void)
+{
+ int i, j;
+ i = 1;
+ j = __imag__ ++i;
+ if (i != 2 || j != 0)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gfortran.dg/elemental_intrinsic_1.f03 b/gcc/testsuite/gfortran.dg/elemental_intrinsic_1.f03
new file mode 100644
index 00000000000..8fdaa0fe9e5
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/elemental_intrinsic_1.f03
@@ -0,0 +1,11 @@
+! { dg-do compile }
+
+! Conformance-checking of arguments was not done for intrinsic elemental
+! subroutines, check this works now.
+
+! This is the test from PR fortran/35681, comment #1 (second program).
+
+ integer, dimension(10) :: ILA1 = (/1,2,3,4,5,6,7,8,9,10/)
+ call mvbits ((ILA1((/9/))), 2, 4, ILA1, 3) ! { dg-error "Different shape" }
+ write (*,'(10(I3))') ila1
+ end
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index 84c884b060c..f57500e62ac 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -1745,9 +1745,8 @@ phi_translate_set (bitmap_set_t dest, bitmap_set_t set, basic_block pred,
pre_expr translated;
translated = phi_translate (expr, set, NULL, pred, phiblock);
- /* Don't add constants or empty translations to the cache, since
- we won't look them up that way, or use the result, anyway. */
- if (translated && !value_id_constant_p (get_expr_value_id (translated)))
+ /* Don't add empty translations to the cache */
+ if (translated)
phi_trans_add (expr, translated, pred);
if (translated != NULL)
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
index c53c5287453..8f238a33da6 100644
--- a/gcc/tree-ssa.c
+++ b/gcc/tree-ssa.c
@@ -1125,9 +1125,14 @@ useless_type_conversion_p_1 (tree outer_type, tree inner_type)
{
/* Don't lose casts between pointers to volatile and non-volatile
qualified types. Doing so would result in changing the semantics
- of later accesses. */
- if ((TYPE_VOLATILE (TREE_TYPE (outer_type))
- != TYPE_VOLATILE (TREE_TYPE (inner_type)))
+ of later accesses. For function types the volatile qualifier
+ is used to indicate noreturn functions. */
+ if (TREE_CODE (TREE_TYPE (outer_type)) != FUNCTION_TYPE
+ && TREE_CODE (TREE_TYPE (outer_type)) != METHOD_TYPE
+ && TREE_CODE (TREE_TYPE (inner_type)) != FUNCTION_TYPE
+ && TREE_CODE (TREE_TYPE (inner_type)) != METHOD_TYPE
+ && (TYPE_VOLATILE (TREE_TYPE (outer_type))
+ != TYPE_VOLATILE (TREE_TYPE (inner_type)))
&& TYPE_VOLATILE (TREE_TYPE (outer_type)))
return false;
diff --git a/gcc/tree.c b/gcc/tree.c
index b131a20875c..7064e06bcec 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -6406,11 +6406,28 @@ get_narrower (tree op, int *unsignedp_ptr)
int
int_fits_type_p (const_tree c, const_tree type)
{
- tree type_low_bound = TYPE_MIN_VALUE (type);
- tree type_high_bound = TYPE_MAX_VALUE (type);
- bool ok_for_low_bound, ok_for_high_bound;
- unsigned HOST_WIDE_INT low;
- HOST_WIDE_INT high;
+ tree type_low_bound, type_high_bound;
+ bool ok_for_low_bound, ok_for_high_bound, unsc;
+ double_int dc, dd;
+
+ dc = tree_to_double_int (c);
+ unsc = TYPE_UNSIGNED (TREE_TYPE (c));
+
+ if (TREE_CODE (TREE_TYPE (c)) == INTEGER_TYPE
+ && TYPE_IS_SIZETYPE (TREE_TYPE (c))
+ && unsc)
+ /* So c is an unsigned integer whose type is sizetype and type is not.
+ sizetype'd integers are sign extended even though they are
+ unsigned. If the integer value fits in the lower end word of c,
+ and if the higher end word has all its bits set to 1, that
+ means the higher end bits are set to 1 only for sign extension.
+ So let's convert c into an equivalent zero extended unsigned
+ integer. */
+ dc = double_int_zext (dc, TYPE_PRECISION (TREE_TYPE (c)));
+
+retry:
+ type_low_bound = TYPE_MIN_VALUE (type);
+ type_high_bound = TYPE_MAX_VALUE (type);
/* If at least one bound of the type is a constant integer, we can check
ourselves and maybe make a decision. If no such decision is possible, but
@@ -6422,25 +6439,25 @@ int_fits_type_p (const_tree c, const_tree type)
for "unknown if constant fits", 0 for "constant known *not* to fit" and 1
for "constant known to fit". */
- if (TREE_TYPE (c) == sizetype
- && TYPE_UNSIGNED (TREE_TYPE (c))
- && TREE_INT_CST_HIGH (c) == -1
- && !TREE_OVERFLOW (c))
- /* So c is an unsigned integer which type is sizetype.
- sizetype'd integers are sign extended even though they are
- unsigned. If the integer value fits in the lower end word of c,
- and if the higher end word has all its bits set to 1, that
- means the higher end bits are set to 1 only for sign extension.
- So let's convert c into an equivalent zero extended unsigned
- integer. */
- c = force_fit_type_double (size_type_node,
- TREE_INT_CST_LOW (c),
- TREE_INT_CST_HIGH (c),
- false, false);
- /* Check if C >= type_low_bound. */
+ /* Check if c >= type_low_bound. */
if (type_low_bound && TREE_CODE (type_low_bound) == INTEGER_CST)
{
- if (tree_int_cst_lt (c, type_low_bound))
+ dd = tree_to_double_int (type_low_bound);
+ if (TREE_CODE (type) == INTEGER_TYPE
+ && TYPE_IS_SIZETYPE (type)
+ && TYPE_UNSIGNED (type))
+ dd = double_int_zext (dd, TYPE_PRECISION (type));
+ if (unsc != TYPE_UNSIGNED (TREE_TYPE (type_low_bound)))
+ {
+ int c_neg = (!unsc && double_int_negative_p (dc));
+ int t_neg = (unsc && double_int_negative_p (dd));
+
+ if (c_neg && !t_neg)
+ return 0;
+ if ((c_neg || !t_neg) && double_int_ucmp (dc, dd) < 0)
+ return 0;
+ }
+ else if (double_int_cmp (dc, dd, unsc) < 0)
return 0;
ok_for_low_bound = true;
}
@@ -6450,7 +6467,22 @@ int_fits_type_p (const_tree c, const_tree type)
/* Check if c <= type_high_bound. */
if (type_high_bound && TREE_CODE (type_high_bound) == INTEGER_CST)
{
- if (tree_int_cst_lt (type_high_bound, c))
+ dd = tree_to_double_int (type_high_bound);
+ if (TREE_CODE (type) == INTEGER_TYPE
+ && TYPE_IS_SIZETYPE (type)
+ && TYPE_UNSIGNED (type))
+ dd = double_int_zext (dd, TYPE_PRECISION (type));
+ if (unsc != TYPE_UNSIGNED (TREE_TYPE (type_high_bound)))
+ {
+ int c_neg = (!unsc && double_int_negative_p (dc));
+ int t_neg = (unsc && double_int_negative_p (dd));
+
+ if (t_neg && !c_neg)
+ return 0;
+ if ((t_neg || !c_neg) && double_int_ucmp (dc, dd) > 0)
+ return 0;
+ }
+ else if (double_int_cmp (dc, dd, unsc) > 0)
return 0;
ok_for_high_bound = true;
}
@@ -6464,7 +6496,7 @@ int_fits_type_p (const_tree c, const_tree type)
/* Perform some generic filtering which may allow making a decision
even if the bounds are not constant. First, negative integers
never fit in unsigned types, */
- if (TYPE_UNSIGNED (type) && tree_int_cst_sgn (c) < 0)
+ if (TYPE_UNSIGNED (type) && !unsc && double_int_negative_p (dc))
return 0;
/* Second, narrower types always fit in wider ones. */
@@ -6472,10 +6504,18 @@ int_fits_type_p (const_tree c, const_tree type)
return 1;
/* Third, unsigned integers with top bit set never fit signed types. */
- if (! TYPE_UNSIGNED (type)
- && TYPE_UNSIGNED (TREE_TYPE (c))
- && tree_int_cst_msb (c))
- return 0;
+ if (! TYPE_UNSIGNED (type) && unsc)
+ {
+ int prec = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (c))) - 1;
+ if (prec < HOST_BITS_PER_WIDE_INT)
+ {
+ if (((((unsigned HOST_WIDE_INT) 1) << prec) & dc.low) != 0)
+ return 0;
+ }
+ else if (((((unsigned HOST_WIDE_INT) 1)
+ << (prec - HOST_BITS_PER_WIDE_INT)) & dc.high) != 0)
+ return 0;
+ }
/* If we haven't been able to decide at this point, there nothing more we
can check ourselves here. Look at the base type if we have one and it
@@ -6483,12 +6523,13 @@ int_fits_type_p (const_tree c, const_tree type)
if (TREE_CODE (type) == INTEGER_TYPE
&& TREE_TYPE (type) != 0
&& TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (type)))
- return int_fits_type_p (c, TREE_TYPE (type));
+ {
+ type = TREE_TYPE (type);
+ goto retry;
+ }
/* Or to fit_double_type, if nothing else. */
- low = TREE_INT_CST_LOW (c);
- high = TREE_INT_CST_HIGH (c);
- return !fit_double_type (low, high, &low, &high, type);
+ return !fit_double_type (dc.low, dc.high, &dc.low, &dc.high, type);
}
/* Stores bounds of an integer TYPE in MIN and MAX. If TYPE has non-constant
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index ae4e64e071a..cf3d9302673 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,3 +1,28 @@
+2008-10-17 Jerry DeLisle <jvdelisle@gcc.gnu.org
+
+ PR libfortran/37863
+ * io/write_float.def (WRITE_FLOAT): Round to 1.0 correctly.
+ * io/io.h (st_parameter_44): Fix id type declaration.
+
+2008-10-16 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ * io/file_pos.c (unformatted_backspace): Normal case is
+ GFC_CONVERT_NATIVE.
+ * io/transfer.c (read_sf): Mark paths leading to generate_error()
+ as unlikely.
+ (readl_block_form): Likewise.
+ (read_block_direct): Likewise.
+ (write_block): Likewise.
+ (write_buf): Likewise.
+ (us_read): Likewise. Normal case is GFC_CONVERT_NATIVE.
+ (next_record_w_unf): Mark paths leading to generate_error()
+ as unlikely.
+
+2008-10-16 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR libfortran/34670
+ * generated/spread_r4.c: Regenerated.
+
2008-10-15 Thomas Koenig <tkoenig@gcc.gnu.org>
PR libfortran/34670
diff --git a/libgfortran/generated/spread_r4.c b/libgfortran/generated/spread_r4.c
index a9357afdc61..c151df3122a 100644
--- a/libgfortran/generated/spread_r4.c
+++ b/libgfortran/generated/spread_r4.c
@@ -131,8 +131,7 @@ spread_r4 (gfc_array_r4 *ret, const gfc_array_r4 *source,
if (n == along - 1)
{
rdelta = ret->dim[n].stride;
- printf("ret_extent = %ld, ncopies = %ld\n",
- (long int) ret_extent, (long int) ncopies);
+
if (ret_extent != ncopies)
runtime_error("Incorrect extent in return value of SPREAD"
" intrinsic in dimension %ld: is %ld,"
diff --git a/libgfortran/io/file_pos.c b/libgfortran/io/file_pos.c
index 6dafbe59028..25b0108eef4 100644
--- a/libgfortran/io/file_pos.c
+++ b/libgfortran/io/file_pos.c
@@ -120,7 +120,7 @@ unformatted_backspace (st_parameter_filepos *fpp, gfc_unit *u)
goto io_error;
/* Only GFC_CONVERT_NATIVE and GFC_CONVERT_SWAP are valid here. */
- if (u->flags.convert == GFC_CONVERT_NATIVE)
+ if (likely (u->flags.convert == GFC_CONVERT_NATIVE))
{
switch (length)
{
diff --git a/libgfortran/io/io.h b/libgfortran/io/io.h
index 710224de21d..ec37be37a81 100644
--- a/libgfortran/io/io.h
+++ b/libgfortran/io/io.h
@@ -458,7 +458,7 @@ typedef struct st_parameter_43
typedef struct st_parameter_44
{
- GFC_IO_INT *id;
+ GFC_INTEGER_4 *id;
GFC_IO_INT pos;
CHARACTER1 (asynchronous);
CHARACTER2 (blank);
diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c
index acc7cbe9b94..8d4f785e49a 100644
--- a/libgfortran/io/transfer.c
+++ b/libgfortran/io/transfer.c
@@ -205,7 +205,8 @@ read_sf (st_parameter_dt *dtp, int *length, int no_error)
if (is_internal_unit (dtp))
{
readlen = *length;
- if (sread (dtp->u.p.current_unit->s, p, &readlen) != 0 || readlen < (size_t) *length)
+ if (unlikely (sread (dtp->u.p.current_unit->s, p, &readlen) != 0
+ || readlen < (size_t) *length))
{
generate_error (&dtp->common, LIBERROR_END, NULL);
return NULL;
@@ -219,7 +220,7 @@ read_sf (st_parameter_dt *dtp, int *length, int no_error)
do
{
- if (sread (dtp->u.p.current_unit->s, &q, &readlen) != 0)
+ if (unlikely (sread (dtp->u.p.current_unit->s, &q, &readlen) != 0))
{
generate_error (&dtp->common, LIBERROR_END, NULL);
return NULL;
@@ -229,7 +230,7 @@ read_sf (st_parameter_dt *dtp, int *length, int no_error)
EOR below. */
if (readlen < 1 && n == 0)
{
- if (no_error)
+ if (likely (no_error))
break;
generate_error (&dtp->common, LIBERROR_END, NULL);
return NULL;
@@ -250,7 +251,8 @@ read_sf (st_parameter_dt *dtp, int *length, int no_error)
{
readlen = 1;
pos = stream_offset (dtp->u.p.current_unit->s);
- if (sread (dtp->u.p.current_unit->s, &q, &readlen) != 0)
+ if (unlikely (sread (dtp->u.p.current_unit->s, &q, &readlen)
+ != 0))
{
generate_error (&dtp->common, LIBERROR_END, NULL);
return NULL;
@@ -266,7 +268,7 @@ read_sf (st_parameter_dt *dtp, int *length, int no_error)
so we can just continue with a short read. */
if (dtp->u.p.current_unit->pad_status == PAD_NO)
{
- if (no_error)
+ if (likely (no_error))
break;
generate_error (&dtp->common, LIBERROR_EOR, NULL);
return NULL;
@@ -332,7 +334,7 @@ read_block_form (st_parameter_dt *dtp, void *buf, size_t *nbytes)
dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
else
{
- if (dtp->u.p.current_unit->pad_status == PAD_NO)
+ if (unlikely (dtp->u.p.current_unit->pad_status == PAD_NO))
{
/* Not enough data left. */
generate_error (&dtp->common, LIBERROR_EOR, NULL);
@@ -340,7 +342,7 @@ read_block_form (st_parameter_dt *dtp, void *buf, size_t *nbytes)
}
}
- if (dtp->u.p.current_unit->bytes_left == 0)
+ if (unlikely (dtp->u.p.current_unit->bytes_left == 0))
{
dtp->u.p.current_unit->endfile = AT_ENDFILE;
generate_error (&dtp->common, LIBERROR_END, NULL);
@@ -368,7 +370,7 @@ read_block_form (st_parameter_dt *dtp, void *buf, size_t *nbytes)
dtp->u.p.current_unit->bytes_left -= (gfc_offset) *nbytes;
nread = *nbytes;
- if (sread (dtp->u.p.current_unit->s, buf, &nread) != 0)
+ if (unlikely (sread (dtp->u.p.current_unit->s, buf, &nread) != 0))
{
generate_error (&dtp->common, LIBERROR_OS, NULL);
return FAILURE;
@@ -379,7 +381,7 @@ read_block_form (st_parameter_dt *dtp, void *buf, size_t *nbytes)
if (nread != *nbytes)
{ /* Short read, this shouldn't happen. */
- if (dtp->u.p.current_unit->pad_status == PAD_YES)
+ if (likely (dtp->u.p.current_unit->pad_status == PAD_YES))
*nbytes = nread;
else
{
@@ -410,7 +412,8 @@ read_block_direct (st_parameter_dt *dtp, void *buf, size_t *nbytes)
{
to_read_record = *nbytes;
have_read_record = to_read_record;
- if (sread (dtp->u.p.current_unit->s, buf, &have_read_record) != 0)
+ if (unlikely (sread (dtp->u.p.current_unit->s, buf, &have_read_record)
+ != 0))
{
generate_error (&dtp->common, LIBERROR_OS, NULL);
return;
@@ -418,7 +421,7 @@ read_block_direct (st_parameter_dt *dtp, void *buf, size_t *nbytes)
dtp->u.p.current_unit->strm_pos += (gfc_offset) have_read_record;
- if (to_read_record != have_read_record)
+ if (unlikely (to_read_record != have_read_record))
{
/* Short read, e.g. if we hit EOF. For stream files,
we have to set the end-of-file condition. */
@@ -445,7 +448,8 @@ read_block_direct (st_parameter_dt *dtp, void *buf, size_t *nbytes)
dtp->u.p.current_unit->bytes_left -= to_read_record;
- if (sread (dtp->u.p.current_unit->s, buf, &to_read_record) != 0)
+ if (unlikely (sread (dtp->u.p.current_unit->s, buf, &to_read_record)
+ != 0))
{
generate_error (&dtp->common, LIBERROR_OS, NULL);
return;
@@ -459,7 +463,7 @@ read_block_direct (st_parameter_dt *dtp, void *buf, size_t *nbytes)
return;
}
- if (short_record)
+ if (unlikely (short_record))
{
generate_error (&dtp->common, LIBERROR_SHORT_RECORD, NULL);
return;
@@ -471,7 +475,7 @@ read_block_direct (st_parameter_dt *dtp, void *buf, size_t *nbytes)
until the request has been fulfilled or the record has run out
of continuation subrecords. */
- if (dtp->u.p.current_unit->endfile == AT_ENDFILE)
+ if (unlikely (dtp->u.p.current_unit->endfile == AT_ENDFILE))
{
generate_error (&dtp->common, LIBERROR_END, NULL);
return;
@@ -509,8 +513,8 @@ read_block_direct (st_parameter_dt *dtp, void *buf, size_t *nbytes)
dtp->u.p.current_unit->bytes_left_subrecord -= to_read_subrecord;
have_read_subrecord = to_read_subrecord;
- if (sread (dtp->u.p.current_unit->s, buf + have_read_record,
- &have_read_subrecord) != 0)
+ if (unlikely (sread (dtp->u.p.current_unit->s, buf + have_read_record,
+ &have_read_subrecord) != 0))
{
generate_error (&dtp->common, LIBERROR_OS, NULL);
return;
@@ -518,7 +522,7 @@ read_block_direct (st_parameter_dt *dtp, void *buf, size_t *nbytes)
have_read_record += have_read_subrecord;
- if (to_read_subrecord != have_read_subrecord)
+ if (unlikely (to_read_subrecord != have_read_subrecord))
{
/* Short read, e.g. if we hit EOF. This means the record
@@ -532,7 +536,7 @@ read_block_direct (st_parameter_dt *dtp, void *buf, size_t *nbytes)
if (to_read_record > 0)
{
- if (dtp->u.p.current_unit->continued)
+ if (likely (dtp->u.p.current_unit->continued))
{
next_record_r_unf (dtp, 0);
us_read (dtp, 1);
@@ -556,7 +560,7 @@ read_block_direct (st_parameter_dt *dtp, void *buf, size_t *nbytes)
}
dtp->u.p.current_unit->bytes_left -= have_read_record;
- if (short_record)
+ if (unlikely (short_record))
{
generate_error (&dtp->common, LIBERROR_SHORT_RECORD, NULL);
return;
@@ -581,9 +585,11 @@ write_block (st_parameter_dt *dtp, int length)
{
/* For preconnected units with default record length, set bytes left
to unit record length and proceed, otherwise error. */
- if ((dtp->u.p.current_unit->unit_number == options.stdout_unit
- || dtp->u.p.current_unit->unit_number == options.stderr_unit)
- && dtp->u.p.current_unit->recl == DEFAULT_RECL)
+ if (likely ((dtp->u.p.current_unit->unit_number
+ == options.stdout_unit
+ || dtp->u.p.current_unit->unit_number
+ == options.stderr_unit)
+ && dtp->u.p.current_unit->recl == DEFAULT_RECL))
dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
else
{
@@ -605,7 +611,7 @@ write_block (st_parameter_dt *dtp, int length)
return NULL;
}
- if (dtp->u.p.current_unit->endfile == AT_ENDFILE)
+ if (unlikely (dtp->u.p.current_unit->endfile == AT_ENDFILE))
generate_error (&dtp->common, LIBERROR_END, NULL);
}
else
@@ -642,7 +648,7 @@ write_buf (st_parameter_dt *dtp, void *buf, size_t nbytes)
if (is_stream_io (dtp))
{
- if (swrite (dtp->u.p.current_unit->s, buf, &nbytes) != 0)
+ if (unlikely (swrite (dtp->u.p.current_unit->s, buf, &nbytes) != 0))
{
generate_error (&dtp->common, LIBERROR_OS, NULL);
return FAILURE;
@@ -657,7 +663,7 @@ write_buf (st_parameter_dt *dtp, void *buf, size_t nbytes)
if (dtp->u.p.current_unit->flags.access == ACCESS_DIRECT)
{
- if (dtp->u.p.current_unit->bytes_left < (gfc_offset) nbytes)
+ if (unlikely (dtp->u.p.current_unit->bytes_left < (gfc_offset) nbytes))
{
generate_error (&dtp->common, LIBERROR_DIRECT_EOR, NULL);
return FAILURE;
@@ -666,7 +672,7 @@ write_buf (st_parameter_dt *dtp, void *buf, size_t nbytes)
if (buf == NULL && nbytes == 0)
return SUCCESS;
- if (swrite (dtp->u.p.current_unit->s, buf, &nbytes) != 0)
+ if (unlikely (swrite (dtp->u.p.current_unit->s, buf, &nbytes) != 0))
{
generate_error (&dtp->common, LIBERROR_OS, NULL);
return FAILURE;
@@ -703,8 +709,8 @@ write_buf (st_parameter_dt *dtp, void *buf, size_t nbytes)
dtp->u.p.current_unit->bytes_left_subrecord -=
(gfc_offset) to_write_subrecord;
- if (swrite (dtp->u.p.current_unit->s, buf + have_written,
- &to_write_subrecord) != 0)
+ if (unlikely (swrite (dtp->u.p.current_unit->s, buf + have_written,
+ &to_write_subrecord) != 0))
{
generate_error (&dtp->common, LIBERROR_OS, NULL);
return FAILURE;
@@ -721,7 +727,7 @@ write_buf (st_parameter_dt *dtp, void *buf, size_t nbytes)
us_write (dtp, 1);
}
dtp->u.p.current_unit->bytes_left -= have_written;
- if (short_record)
+ if (unlikely (short_record))
{
generate_error (&dtp->common, LIBERROR_SHORT_RECORD, NULL);
return FAILURE;
@@ -973,7 +979,7 @@ formatted_transfer_scalar (st_parameter_dt *dtp, bt type, void *p, int kind,
if (f == NULL)
{
/* No data descriptors left. */
- if (n > 0)
+ if (unlikely (n > 0))
generate_error (&dtp->common, LIBERROR_FORMAT,
"Insufficient data descriptors in format after reversion");
return;
@@ -1671,7 +1677,7 @@ us_read (st_parameter_dt *dtp, int continued)
nr = n;
- if (sread (dtp->u.p.current_unit->s, &i, &n) != 0)
+ if (unlikely (sread (dtp->u.p.current_unit->s, &i, &n) != 0))
{
generate_error (&dtp->common, LIBERROR_BAD_US, NULL);
return;
@@ -1683,14 +1689,14 @@ us_read (st_parameter_dt *dtp, int continued)
return; /* end of file */
}
- if (n != nr)
+ if (unlikely (n != nr))
{
generate_error (&dtp->common, LIBERROR_BAD_US, NULL);
return;
}
/* Only GFC_CONVERT_NATIVE and GFC_CONVERT_SWAP are valid here. */
- if (dtp->u.p.current_unit->flags.convert == GFC_CONVERT_NATIVE)
+ if (likely (dtp->u.p.current_unit->flags.convert == GFC_CONVERT_NATIVE))
{
switch (nr)
{
@@ -2535,7 +2541,7 @@ write_us_marker (st_parameter_dt *dtp, const gfc_offset buf)
len = compile_options.record_marker;
/* Only GFC_CONVERT_NATIVE and GFC_CONVERT_SWAP are valid here. */
- if (dtp->u.p.current_unit->flags.convert == GFC_CONVERT_NATIVE)
+ if (likely (dtp->u.p.current_unit->flags.convert == GFC_CONVERT_NATIVE))
{
switch (len)
{
@@ -2600,7 +2606,7 @@ next_record_w_unf (st_parameter_dt *dtp, int next_subrecord)
else
m_write = m;
- if (write_us_marker (dtp, m_write) != 0)
+ if (unlikely (write_us_marker (dtp, m_write) != 0))
goto io_error;
if (compile_options.record_marker == 0)
@@ -2611,8 +2617,8 @@ next_record_w_unf (st_parameter_dt *dtp, int next_subrecord)
/* Seek to the head and overwrite the bogus length with the real
length. */
- if (sseek (dtp->u.p.current_unit->s, c - m - record_marker)
- == FAILURE)
+ if (unlikely (sseek (dtp->u.p.current_unit->s, c - m - record_marker)
+ == FAILURE))
goto io_error;
if (next_subrecord)
@@ -2620,12 +2626,13 @@ next_record_w_unf (st_parameter_dt *dtp, int next_subrecord)
else
m_write = m;
- if (write_us_marker (dtp, m_write) != 0)
+ if (unlikely (write_us_marker (dtp, m_write) != 0))
goto io_error;
/* Seek past the end of the current record. */
- if (sseek (dtp->u.p.current_unit->s, c + record_marker) == FAILURE)
+ if (unlikely (sseek (dtp->u.p.current_unit->s, c + record_marker)
+ == FAILURE))
goto io_error;
return;
diff --git a/libgfortran/io/write_float.def b/libgfortran/io/write_float.def
index 0ee8f3560c4..73a6ed14a1b 100644
--- a/libgfortran/io/write_float.def
+++ b/libgfortran/io/write_float.def
@@ -746,7 +746,7 @@ sprintf (buffer, "%+-#" STR(MIN_FIELD_WIDTH) ".*" \
if (tmp < 0.5)\
tmp = 0.0;\
else if (tmp < 1.0)\
- tmp = tmp + 0.5;\
+ tmp = 1.0;\
}\
zero_flag = (tmp == 0.0);\
\
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 7d653fec328..18aa1778d5e 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,67 @@
+2008-10-17 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * include/bits/forward_list.tcc (forward_list<>::
+ _M_initialize_dispatch(_InputIterator, _InputIterator, __false_type)):
+ Simplify.
+
+2008-10-17 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * include/bits/forward_list.h (forward_list<>::
+ forward_list(size_type)): Tweak, use _Base default constructor.
+
+2008-10-17 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * include/bits/forward_list.h (forward_list<>::insert_after): Minor
+ cosmetic changes.
+
+2008-10-16 Edward Smith-Rowland <3dw4rd@verizon.net>
+
+ * include/bits/forward_list.h: Factor list construction to dispatch
+ routines.
+ * include/bits/forward_list.tcc: Likewise.
+ * testsuite/23_containers/forward_list/modifiers/2.cc:
+
+2008-10-16 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * include/bits/forward_list.tcc (operator==): Use auto.
+
+2008-10-16 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * include/bits/forward_list.h (_Fwd_list_base<>::_M_insert_after):
+ Move out of line, tweak to return _Fwd_list_node_base*.
+ (forward_list<>::insert_after(const_iterator, const _Tp&),
+ forward_list<>::insert_after(const_iterator, _Tp&&)): Use it.
+ * include/bits/forward_list.tcc (_Fwd_list_base<>::_M_insert_after):
+ Define.
+
+ * include/bits/forward_list.h (forward_list<>): Consistently qualify
+ calls of base class functions with this->.
+ * include/bits/forward_list.tcc (forward_list<>): Likewise.
+
+ * include/bits/forward_list.h: Move some functions out of line...
+ * include/bits/forward_list.tcc: ... here.
+
+ * include/bits/forward_list.h (forward_list<>::resize(size_type)): Fix.
+
+2008-10-15 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * include/bits/forward_list.h: Remove pointless const qualifiers in
+ const_casts.
+ * include/bits/forward_list.tcc: Likewise.
+
+ * include/bits/forward_list.h (forward_list<>::pointer,
+ const_pointer, reference, const_reference): Fix, use _Tp_alloc_type.
+ * testsuite/23_containers/forward_list/requirements/
+ explicit_instantiation/1.cc: New.
+ * testsuite/23_containers/forward_list/requirements/
+ explicit_instantiation/1.cc: Likewise.
+
+2008-10-15 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * include/bits/forward_list.h (forward_list<>::max_size): Use
+ Node_allocator; minor cosmetic changes.
+ * testsuite/23_containers/forward_list/capacity/1.cc: Adjust.
+
2008-10-15 Edward Smith-Rowland <3dw4rd@verizon.net>
* include/std/forward_list: New.
diff --git a/libstdc++-v3/include/bits/forward_list.h b/libstdc++-v3/include/bits/forward_list.h
index 8e5a6b0a72c..60b187fb483 100644
--- a/libstdc++-v3/include/bits/forward_list.h
+++ b/libstdc++-v3/include/bits/forward_list.h
@@ -31,8 +31,8 @@
* This is a Standard C++ Library header.
*/
-#ifndef _GLIBCXX_FORWARD_LIST_H
-#define _GLIBCXX_FORWARD_LIST_H 1
+#ifndef _FORWARD_LIST_H
+#define _FORWARD_LIST_H 1
#pragma GCC system_header
@@ -88,7 +88,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
_M_reverse_after()
{
_Fwd_list_node_base* __tail = this->_M_next;
- if (! __tail)
+ if (!__tail)
return;
while (_Fwd_list_node_base* __temp = __tail->_M_next)
{
@@ -282,6 +282,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
typedef typename _Alloc::template rebind<_Fwd_list_node<_Tp>>::other
_Node_alloc_type;
+ typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type;
+
struct _Fwd_list_impl
: public _Node_alloc_type
{
@@ -291,7 +293,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
: _Node_alloc_type(), _M_head()
{ }
- explicit
_Fwd_list_impl(const _Node_alloc_type& __a)
: _Node_alloc_type(__a), _M_head()
{ }
@@ -300,7 +301,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
_Fwd_list_impl _M_impl;
public:
- typedef _Alloc allocator_type;
typedef _Fwd_list_iterator<_Tp> iterator;
typedef _Fwd_list_const_iterator<_Tp> const_iterator;
@@ -314,15 +314,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
_M_get_Node_allocator() const
{ return *static_cast<const _Node_alloc_type*>(&this->_M_impl); }
- allocator_type
- get_allocator() const
- { return this->_M_get_Node_allocator(); }
-
_Fwd_list_base()
: _M_impl()
{ this->_M_impl._M_head._M_next = 0; }
- _Fwd_list_base(const allocator_type& __a)
+ _Fwd_list_base(const _Alloc& __a)
: _M_impl(__a)
{ this->_M_impl._M_head._M_next = 0; }
@@ -350,32 +346,25 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
template<typename... _Args>
_Node*
_M_create_node(_Args&&... __args)
- {
- _Node* __node = this->_M_get_node();
- try
- {
- _M_get_Node_allocator().construct(__node,
- std::forward<_Args>(__args)...);
- __node->_M_next = 0;
- }
- catch(...)
- {
- this->_M_put_node(__node);
- __throw_exception_again;
- }
- return __node;
- }
+ {
+ _Node* __node = this->_M_get_node();
+ try
+ {
+ _M_get_Node_allocator().construct(__node,
+ std::forward<_Args>(__args)...);
+ __node->_M_next = 0;
+ }
+ catch(...)
+ {
+ this->_M_put_node(__node);
+ __throw_exception_again;
+ }
+ return __node;
+ }
template<typename... _Args>
- void
- _M_insert_after(const_iterator __pos, _Args&&... __args)
- {
- _Fwd_list_node_base* __to
- = const_cast<_Fwd_list_node_base* const>(__pos._M_node);
- _Node* __thing = _M_create_node(std::forward<_Args>(__args)...);
- __thing->_M_next = __to->_M_next;
- __to->_M_next = __thing;
- }
+ _Fwd_list_node_base*
+ _M_insert_after(const_iterator __pos, _Args&&... __args);
void
_M_put_node(_Node* __p)
@@ -425,21 +414,22 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
class forward_list : private _Fwd_list_base<_Tp, _Alloc>
{
private:
- typedef _Fwd_list_base<_Tp, _Alloc> _Base;
- typedef _Fwd_list_node<_Tp> _Node;
+ typedef _Fwd_list_base<_Tp, _Alloc> _Base;
+ typedef _Fwd_list_node<_Tp> _Node;
+ typedef typename _Base::_Tp_alloc_type _Tp_alloc_type;
public:
// types:
- typedef typename _Alloc::reference reference;
- typedef typename _Alloc::const_reference const_reference;
- typedef _Fwd_list_iterator<_Tp> iterator;
- typedef _Fwd_list_const_iterator<_Tp> const_iterator;
- typedef std::size_t size_type;
- typedef std::ptrdiff_t difference_type;
- typedef _Tp value_type;
- typedef typename _Base::allocator_type allocator_type;
- typedef typename _Alloc::pointer pointer;
- typedef typename _Alloc::const_pointer const_pointer;
+ typedef _Tp value_type;
+ typedef typename _Tp_alloc_type::pointer pointer;
+ typedef typename _Tp_alloc_type::const_pointer const_pointer;
+ typedef typename _Tp_alloc_type::reference reference;
+ typedef typename _Tp_alloc_type::const_reference const_reference;
+ typedef _Fwd_list_iterator<_Tp> iterator;
+ typedef _Fwd_list_const_iterator<_Tp> const_iterator;
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+ typedef _Alloc allocator_type;
// 23.2.3.1 construct/copy/destroy:
@@ -479,7 +469,9 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
* the default value.
*/
explicit
- forward_list(size_type __n);
+ forward_list(size_type __n)
+ : _Base()
+ { _M_fill_initialize(__n, value_type()); }
/**
* @brief Creates a %forward_list with copies of an exemplar element.
@@ -491,7 +483,9 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
* value.
*/
forward_list(size_type __n, const _Tp& __value,
- const _Alloc& __al = _Alloc());
+ const _Alloc& __al = _Alloc())
+ : _Base(__al)
+ { _M_fill_initialize(__n, __value); }
/**
* @brief Builds a %forward_list from a range.
@@ -505,7 +499,13 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
*/
template<typename _InputIterator>
forward_list(_InputIterator __first, _InputIterator __last,
- const _Alloc& __al = _Alloc());
+ const _Alloc& __al = _Alloc())
+ : _Base(__al)
+ {
+ // Check whether it's an integral type. If so, it's not an iterator.
+ typedef typename std::__is_integer<_InputIterator>::__type _Integral;
+ _M_initialize_dispatch(__first, __last, _Integral());
+ }
/**
* @brief The %forward_list copy constructor.
@@ -515,7 +515,9 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
* The newly-created %forward_list uses a copy of the allocation
* object used by @a list.
*/
- forward_list(const forward_list& __list);
+ forward_list(const forward_list& __list)
+ : _Base(__list.get_allocator())
+ { _M_initialize_dispatch(__list.begin(), __list.end(), __false_type()); }
/**
* @brief The %forward_list move constructor.
@@ -538,7 +540,9 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
* in the initializer_list @a il. This is linear in il.size().
*/
forward_list(std::initializer_list<_Tp> __il,
- const _Alloc& __al = _Alloc());
+ const _Alloc& __al = _Alloc())
+ : _Base(__al)
+ { _M_initialize_dispatch(__il.begin(), __il.end(), __false_type()); }
/**
* @brief The forward_list dtor.
@@ -585,7 +589,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
* elements in the initializer_list @a il. This is linear in
* il.size().
*/
- forward_list
+ forward_list&
operator=(std::initializer_list<_Tp> __il)
{
assign(__il);
@@ -604,9 +608,9 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
* that the resulting %forward_list's size is the same as the number
* of elements assigned. Old data may be lost.
*/
- template<typename InputIterator>
+ template<typename _InputIterator>
void
- assign(InputIterator __first, InputIterator __last)
+ assign(_InputIterator __first, _InputIterator __last)
{
clear();
insert_after(cbefore_begin(), __first, __last);
@@ -647,7 +651,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
/// Get a copy of the memory allocation object.
allocator_type
get_allocator() const
- { return _Base::get_allocator(); }
+ { return this->_M_get_Node_allocator(); }
// 23.2.3.2 iterators:
@@ -743,7 +747,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
*/
size_type
max_size() const
- { return _Alloc().max_size(); }
+ { return this->_M_get_Node_allocator().max_size(); }
// 23.2.3.3 element access:
@@ -783,9 +787,10 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
* and references.
*/
template<typename... _Args>
- void
- emplace_front(_Args&&... __args)
- { _M_insert_after(cbefore_begin(), std::forward<_Args>(__args)...); }
+ void
+ emplace_front(_Args&&... __args)
+ { this->_M_insert_after(cbefore_begin(),
+ std::forward<_Args>(__args)...); }
/**
* @brief Add data to the front of the %forward_list.
@@ -799,14 +804,14 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
*/
void
push_front(const _Tp& __val)
- { _M_insert_after(cbefore_begin(), __val); }
+ { this->_M_insert_after(cbefore_begin(), __val); }
/**
*
*/
void
push_front(_Tp&& __val)
- { _M_insert_after(cbefore_begin(), std::move(__val)); }
+ { this->_M_insert_after(cbefore_begin(), std::move(__val)); }
/**
* @brief Removes first element.
@@ -822,7 +827,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
*/
void
pop_front()
- { _M_erase_after(&this->_M_impl._M_head); }
+ { this->_M_erase_after(&this->_M_impl._M_head); }
/**
* @brief Constructs object in %forward_list after the specified
@@ -838,9 +843,10 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
* and references.
*/
template<typename... _Args>
- iterator
- emplace_after(const_iterator __pos, _Args&&... __args)
- { _M_insert_after(__pos, std::forward<_Args>(__args)...); }
+ iterator
+ emplace_after(const_iterator __pos, _Args&&... __args)
+ { return iterator(this->_M_insert_after(__pos,
+ std::forward<_Args>(__args)...)); }
/**
* @brief Inserts given value into %forward_list after specified
@@ -856,28 +862,14 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
*/
iterator
insert_after(const_iterator __pos, const _Tp& __val)
- {
- _Fwd_list_node_base* __to
- = const_cast<_Fwd_list_node_base* const>(__pos._M_node);
- _Node* __thing = _M_create_node(__val);
- __thing->_M_next = __to->_M_next;
- __to->_M_next = __thing;
- return iterator(__to->_M_next);
- }
+ { return iterator(this->_M_insert_after(__pos, __val)); }
/**
*
*/
iterator
insert_after(const_iterator __pos, _Tp&& __val)
- {
- _Fwd_list_node_base* __to
- = const_cast<_Fwd_list_node_base* const>(__pos._M_node);
- _Node* __thing = _M_create_node(std::move(__val));
- __thing->_M_next = __to->_M_next;
- __to->_M_next = __thing;
- return iterator(__to->_M_next);
- }
+ { return iterator(this->_M_insert_after(__pos, std::move(__val))); }
/**
* @brief Inserts a number of copies of given data into the
@@ -893,8 +885,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
* does not invalidate iterators and references.
*/
void
- insert_after(const_iterator __pos,
- size_type __n, const _Tp& __val);
+ insert_after(const_iterator __pos, size_type __n, const _Tp& __val)
+ {
+ forward_list __tmp(__n, __val, this->get_allocator());
+ this->splice_after(__pos, std::move(__tmp));
+ }
/**
* @brief Inserts a range into the %forward_list.
@@ -912,7 +907,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
template<typename _InputIterator>
void
insert_after(const_iterator __pos,
- _InputIterator __first, _InputIterator __last);
+ _InputIterator __first, _InputIterator __last)
+ {
+ forward_list __tmp(__first, __last, this->get_allocator());
+ this->splice_after(__pos, std::move(__tmp));
+ }
/**
* @brief Inserts the contents of an initializer_list into
@@ -928,7 +927,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
* does not invalidate iterators and references.
*/
void
- insert_after(const_iterator __pos, std::initializer_list<_Tp> __il);
+ insert_after(const_iterator __pos, std::initializer_list<_Tp> __il)
+ {
+ forward_list __tmp(__il, this->get_allocator());
+ this->splice_after(__pos, std::move(__tmp));
+ }
/**
* @brief Removes the element pointed to by the iterator following
@@ -950,9 +953,9 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
erase_after(const_iterator __pos)
{
_Fwd_list_node_base* __tmp
- = const_cast<_Fwd_list_node_base* const>(__pos._M_node);
+ = const_cast<_Fwd_list_node_base*>(__pos._M_node);
if (__tmp)
- return iterator(_Base::_M_erase_after(__tmp));
+ return iterator(this->_M_erase_after(__tmp));
else
return end();
}
@@ -980,8 +983,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
erase_after(const_iterator __pos, iterator __last)
{
_Fwd_list_node_base* __tmp
- = const_cast<_Fwd_list_node_base* const>(__pos._M_node);
- return iterator(_M_erase_after(__tmp, __last._M_node));
+ = const_cast<_Fwd_list_node_base*>(__pos._M_node);
+ return iterator(this->_M_erase_after(__tmp, __last._M_node));
}
/**
@@ -1012,7 +1015,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
*/
void
resize(size_type __sz)
- { resize(__sz, _Tp(0)); }
+ { resize(__sz, _Tp()); }
/**
* @brief Resizes the %forward_list to the specified number of
@@ -1039,7 +1042,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
*/
void
clear()
- { _M_erase_after(&this->_M_impl._M_head, 0); }
+ { this->_M_erase_after(&this->_M_impl._M_head, 0); }
// 23.2.3.5 forward_list operations:
@@ -1055,18 +1058,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
* Requires this != @a x.
*/
void
- splice_after(const_iterator __pos,
- forward_list&& __list)
- {
- if (!__list.empty() && &__list != this)
- {
- _Fwd_list_node_base* __tmp
- = const_cast<_Fwd_list_node_base* const>(__pos._M_node);
- const_iterator __before = __list.cbefore_begin();
- __tmp->_M_transfer_after(const_cast<_Fwd_list_node_base* const>
- (__before._M_node));
- }
- }
+ splice_after(const_iterator __pos, forward_list&& __list);
/**
* @brief Insert element from another %forward_list.
@@ -1079,8 +1071,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
* inserts it into the current list after @a pos.
*/
void
- splice_after(const_iterator __pos,
- forward_list&& __list,
+ splice_after(const_iterator __pos, forward_list&& __list,
const_iterator __it)
{ this->splice_after(__pos, __list, __it, __it._M_next()); }
@@ -1098,18 +1089,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
* Undefined if @a pos is in (before,last).
*/
void
- splice_after(const_iterator __pos,
- forward_list&& __list,
- const_iterator __before,
- const_iterator __last)
- {
- _Fwd_list_node_base* __tmp
- = const_cast<_Fwd_list_node_base* const>(__pos._M_node);
- __tmp->_M_transfer_after(const_cast<_Fwd_list_node_base* const>
- (__before._M_node),
- const_cast<_Fwd_list_node_base* const>
- (__last._M_node));
- }
+ splice_after(const_iterator __pos, forward_list&& __list,
+ const_iterator __before, const_iterator __last);
/**
* @brief Remove all elements equal to value.
@@ -1151,7 +1132,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
* the pointer is the user's responsibility.
*/
void
- unique();
+ unique()
+ { this->unique(std::equal_to<_Tp>()); }
/**
* @brief Remove consecutive elements satisfying a predicate.
@@ -1230,8 +1212,24 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
* Reverse the order of elements in the list in linear time.
*/
void
- reverse()
- { this->_M_impl._M_head._M_reverse_after(); }
+ reverse();
+
+ private:
+ template<typename _Integer>
+ void
+ _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type)
+ { _M_fill_initialize(static_cast<size_type>(__n), __x); }
+
+ // Called by the range constructor to implement [23.1.1]/9
+ template<typename _InputIterator>
+ void
+ _M_initialize_dispatch(_InputIterator __first, _InputIterator __last,
+ __false_type);
+
+ // Called by forward_list(n,v,a), and the range constructor when it
+ // turns out to be the same thing.
+ void
+ _M_fill_initialize(size_type __n, const value_type& __value);
};
/**
@@ -1247,26 +1245,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
template<typename _Tp, typename _Alloc>
bool
operator==(const forward_list<_Tp, _Alloc>& __lx,
- const forward_list<_Tp, _Alloc>& __ly)
- {
- // We don't have size() so we need to walk through both lists
- // making sure both iterators are valid.
- typename std::forward_list<_Tp, _Alloc>::const_iterator __ix
- = __lx.cbegin();
- typename std::forward_list<_Tp, _Alloc>::const_iterator __iy
- = __ly.cbegin();
- while (__ix != __lx.cend() && __iy != __ly.cend())
- {
- if (*__ix != *__iy)
- return false;
- ++__ix;
- ++__iy;
- }
- if (__ix == __lx.cend() && __iy == __ly.cend())
- return true;
- else
- return false;
- }
+ const forward_list<_Tp, _Alloc>& __ly);
/**
* @brief Forward list ordering relation.
@@ -1291,7 +1270,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
inline bool
operator!=(const forward_list<_Tp, _Alloc>& __lx,
const forward_list<_Tp, _Alloc>& __ly)
- { return ! (__lx == __ly); }
+ { return !(__lx == __ly); }
/// Based on operator<
template<typename _Tp, typename _Alloc>
@@ -1305,14 +1284,14 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
inline bool
operator>=(const forward_list<_Tp, _Alloc>& __lx,
const forward_list<_Tp, _Alloc>& __ly)
- { return ! (__lx < __ly); }
+ { return !(__lx < __ly); }
/// Based on operator<
template<typename _Tp, typename _Alloc>
inline bool
operator<=(const forward_list<_Tp, _Alloc>& __lx,
const forward_list<_Tp, _Alloc>& __ly)
- { return ! (__ly < __lx); }
+ { return !(__ly < __lx); }
/// See std::forward_list::forward_swap().
template<typename _Tp, typename _Alloc>
@@ -1339,4 +1318,4 @@ _GLIBCXX_END_NAMESPACE // namespace std
#endif // __GXX_EXPERIMENTAL_CXX0X__
-#endif // _GLIBCXX_FORWARD_LIST_H
+#endif // _FORWARD_LIST_H
diff --git a/libstdc++-v3/include/bits/forward_list.tcc b/libstdc++-v3/include/bits/forward_list.tcc
index 7a3a3d0beda..02b1a0d1d42 100644
--- a/libstdc++-v3/include/bits/forward_list.tcc
+++ b/libstdc++-v3/include/bits/forward_list.tcc
@@ -158,6 +158,20 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
}
template<typename _Tp, typename _Alloc>
+ template<typename... _Args>
+ _Fwd_list_node_base*
+ _Fwd_list_base<_Tp, _Alloc>::
+ _M_insert_after(const_iterator __pos, _Args&&... __args)
+ {
+ _Fwd_list_node_base* __to
+ = const_cast<_Fwd_list_node_base*>(__pos._M_node);
+ _Node* __thing = _M_create_node(std::forward<_Args>(__args)...);
+ __thing->_M_next = __to->_M_next;
+ __to->_M_next = __thing;
+ return __to->_M_next;
+ }
+
+ template<typename _Tp, typename _Alloc>
_Fwd_list_node_base*
_Fwd_list_base<_Tp, _Alloc>::
_M_erase_after(_Fwd_list_node_base* __pos)
@@ -192,77 +206,35 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
return __pos;
}
- template<typename _Tp, typename _Alloc>
- forward_list<_Tp, _Alloc>::
- forward_list(size_type __n)
- : _Base()
- {
- _Fwd_list_node_base* __to = &this->_M_impl._M_head;
- for (size_type __i = 0; __i < __n; ++__i)
- {
- __to->_M_next = _M_create_node(_Tp());
- __to = __to->_M_next;
- }
- }
-
- template<typename _Tp, typename _Alloc>
- forward_list<_Tp, _Alloc>::
- forward_list(size_type __n, const _Tp& __value, const _Alloc& __al)
- : _Base(__al)
- {
- _Fwd_list_node_base* __to = &this->_M_impl._M_head;
- for (size_type __i = 0; __i < __n; ++__i)
- {
- __to->_M_next = _M_create_node(__value);
- __to = __to->_M_next;
- }
- }
-
+ // Called by the range constructor to implement [23.1.1]/9
template<typename _Tp, typename _Alloc>
template<typename _InputIterator>
+ void
forward_list<_Tp, _Alloc>::
- forward_list(_InputIterator __first, _InputIterator __last,
- const _Alloc& __al)
- : _Base(__al)
+ _M_initialize_dispatch(_InputIterator __first, _InputIterator __last,
+ __false_type)
{
_Fwd_list_node_base* __to = &this->_M_impl._M_head;
- _InputIterator __curr = __first;
- while (__curr != __last)
+ for (; __first != __last; ++__first)
{
- __to->_M_next = _M_create_node(*__curr);
+ __to->_M_next = this->_M_create_node(*__first);
__to = __to->_M_next;
- ++__curr;
}
}
+ // Called by forward_list(n,v,a), and the range constructor
+ // when it turns out to be the same thing.
template<typename _Tp, typename _Alloc>
+ void
forward_list<_Tp, _Alloc>::
- forward_list(const forward_list& __list)
- : _Base(__list._M_get_Node_allocator())
- {
- const _Fwd_list_node_base* __from = &__list._M_impl._M_head;
- _Fwd_list_node_base* __to = &this->_M_impl._M_head;
- while (__from->_M_next != 0)
- {
- const _Node* __temp = static_cast<_Node*>(__from->_M_next);
- __to->_M_next = _M_create_node(__temp->_M_value);
- __from = __from->_M_next;
- __to = __to->_M_next;
- }
- }
-
- template<typename _Tp, typename _Alloc>
- forward_list<_Tp, _Alloc>::
- forward_list(std::initializer_list<_Tp> __il, const _Alloc& __al)
- : _Base(__al)
+ _M_fill_initialize(size_type __n, const value_type& __value)
{
_Fwd_list_node_base* __to = &this->_M_impl._M_head;
- for (const _Tp* __item = __il.begin();
- __item != __il.end(); ++__item)
- {
- __to->_M_next = _M_create_node(*__item);
- __to = __to->_M_next;
- }
+ for (; __n > 0; --__n)
+ {
+ __to->_M_next = this->_M_create_node(__value);
+ __to = __to->_M_next;
+ }
}
template<typename _Tp, typename _Alloc>
@@ -295,75 +267,49 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
template<typename _Tp, typename _Alloc>
void
forward_list<_Tp, _Alloc>::
- insert_after(const_iterator __pos,
- size_type __n, const _Tp& __val)
+ resize(size_type __sz, value_type __val)
{
- _Fwd_list_node_base* __to
- = const_cast<_Fwd_list_node_base* const>(__pos._M_node);
- _Fwd_list_node_base* __keep = __to->_M_next;
- for (size_type __i = 0; __i < __n; ++__i)
+ iterator __k = before_begin();
+
+ size_type __len = 0;
+ while (__k._M_next() != end() && __len < __sz)
{
- __to->_M_next = _M_create_node(__val);
- __to = __to->_M_next;
+ ++__k;
+ ++__len;
}
- __to->_M_next = __keep;
+ if (__len == __sz)
+ erase_after(__k, end());
+ else
+ insert_after(__k, __sz - __len, __val);
}
template<typename _Tp, typename _Alloc>
- template<typename _InputIterator>
- void
- forward_list<_Tp, _Alloc>::
- insert_after(const_iterator __pos,
- _InputIterator __first, _InputIterator __last)
- {
- _Fwd_list_node_base* __to
- = const_cast<_Fwd_list_node_base* const>(__pos._M_node);
- _Fwd_list_node_base* __keep = __to->_M_next;
- _InputIterator __curr = __first;
- while (__curr != __last)
- {
- __to->_M_next = _M_create_node(*__curr);
- __to = __to->_M_next;
- ++__curr;
- }
- __to->_M_next = __keep;
- }
-
- template<typename _Tp, typename _Alloc>
void
forward_list<_Tp, _Alloc>::
- insert_after(const_iterator __pos, std::initializer_list<_Tp> __il)
+ splice_after(const_iterator __pos, forward_list&& __list)
{
- _Fwd_list_node_base* __to
- = const_cast<_Fwd_list_node_base* const>(__pos._M_node);
- _Fwd_list_node_base* __keep = __to->_M_next;
- const _Tp* __item = __il.begin();
- while (__item != __il.end())
+ if (!__list.empty() && &__list != this)
{
- __to->_M_next = _M_create_node(*__item);
- __to = __to->_M_next;
- ++__item;
+ _Fwd_list_node_base* __tmp
+ = const_cast<_Fwd_list_node_base*>(__pos._M_node);
+ const_iterator __before = __list.cbefore_begin();
+ __tmp->_M_transfer_after(const_cast<_Fwd_list_node_base*>
+ (__before._M_node));
}
- __to->_M_next = __keep;
}
template<typename _Tp, typename _Alloc>
void
forward_list<_Tp, _Alloc>::
- resize(size_type __sz, value_type __val)
+ splice_after(const_iterator __pos, forward_list&& __list,
+ const_iterator __before, const_iterator __last)
{
- iterator __k = before_begin();
-
- size_type __len = 0;
- while (__k._M_next() != end() && __len < __sz)
- {
- ++__k;
- ++__len;
- }
- if (__len == __sz)
- erase_after(__k, end());
- else
- insert_after(__k, __sz - __len, __val);
+ _Fwd_list_node_base* __tmp
+ = const_cast<_Fwd_list_node_base*>(__pos._M_node);
+ __tmp->_M_transfer_after(const_cast<_Fwd_list_node_base*>
+ (__before._M_node),
+ const_cast<_Fwd_list_node_base*>
+ (__last._M_node));
}
template<typename _Tp, typename _Alloc>
@@ -375,7 +321,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
while (_Node* __temp = static_cast<_Node*>(__curr->_M_next))
{
if (__temp->_M_value == __val)
- _M_erase_after(__curr);
+ this->_M_erase_after(__curr);
else
__curr = static_cast<_Node*>(__curr->_M_next);
}
@@ -391,33 +337,13 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
while (_Node* __temp = static_cast<_Node*>(__curr->_M_next))
{
if (__pred(__temp->_M_value))
- _M_erase_after(__curr);
+ this->_M_erase_after(__curr);
else
__curr = static_cast<_Node*>(__curr->_M_next);
}
}
template<typename _Tp, typename _Alloc>
- void
- forward_list<_Tp, _Alloc>::
- unique()
- {
- iterator __first = begin();
- iterator __last = end();
- if (__first == __last)
- return;
- iterator __next = __first;
- while (++__next != __last)
- {
- if (*__first == *__next)
- erase_after(__first);
- else
- __first = __next;
- __next = __first;
- }
- }
-
- template<typename _Tp, typename _Alloc>
template<typename _BinPred>
void
forward_list<_Tp, _Alloc>::
@@ -426,12 +352,12 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
iterator __first = begin();
iterator __last = end();
if (__first == __last)
- return;
+ return;
iterator __next = __first;
while (++__next != __last)
{
if (__binary_pred(*__first, *__next))
- erase_after(__first);
+ erase_after(__first);
else
__first = __next;
__next = __first;
@@ -462,6 +388,34 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
}
}
+ template<typename _Tp, typename _Alloc>
+ void
+ forward_list<_Tp, _Alloc>::
+ reverse()
+ { this->_M_impl._M_head._M_reverse_after(); }
+
+ template<typename _Tp, typename _Alloc>
+ bool
+ operator==(const forward_list<_Tp, _Alloc>& __lx,
+ const forward_list<_Tp, _Alloc>& __ly)
+ {
+ // We don't have size() so we need to walk through both lists
+ // making sure both iterators are valid.
+ auto __ix = __lx.cbegin();
+ auto __iy = __ly.cbegin();
+ while (__ix != __lx.cend() && __iy != __ly.cend())
+ {
+ if (*__ix != *__iy)
+ return false;
+ ++__ix;
+ ++__iy;
+ }
+ if (__ix == __lx.cend() && __iy == __ly.cend())
+ return true;
+ else
+ return false;
+ }
+
_GLIBCXX_END_NAMESPACE // namespace std
#endif /* _FORWARD_LIST_TCC */
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/capacity/1.cc b/libstdc++-v3/testsuite/23_containers/forward_list/capacity/1.cc
index 1489f9b9da5..e5ad77be917 100644
--- a/libstdc++-v3/testsuite/23_containers/forward_list/capacity/1.cc
+++ b/libstdc++-v3/testsuite/23_containers/forward_list/capacity/1.cc
@@ -39,7 +39,8 @@ test01()
fld.resize(0);
VERIFY(fld.empty() == true);
- VERIFY(fld.max_size() == fld.get_allocator().max_size());
+ VERIFY( fld.max_size()
+ == std::allocator<std::_Fwd_list_node<double> >().max_size() );
}
int
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/modifiers/2.cc b/libstdc++-v3/testsuite/23_containers/forward_list/modifiers/2.cc
index 9d79b22986b..a6283580586 100644
--- a/libstdc++-v3/testsuite/23_containers/forward_list/modifiers/2.cc
+++ b/libstdc++-v3/testsuite/23_containers/forward_list/modifiers/2.cc
@@ -51,7 +51,7 @@ test02()
// Note: Calling l.insert_after(pos, 5, 42); without the long five
// gets resolved to the iterator range version and fails to compile!
- fl.insert_after(pos, 5L, 42);
+ fl.insert_after(pos, 5, 42);
VERIFY(*pos == 1);
++pos;
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/explicit_instantiation/1.cc b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/explicit_instantiation/1.cc
new file mode 100644
index 00000000000..2650632e26c
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/explicit_instantiation/1.cc
@@ -0,0 +1,36 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2008 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// This file tests explicit instantiation of library containers
+
+#include <forward_list>
+
+// { dg-do compile }
+
+template class std::forward_list<int>;
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/explicit_instantiation/3.cc b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/explicit_instantiation/3.cc
new file mode 100644
index 00000000000..ca34423cc4d
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/explicit_instantiation/3.cc
@@ -0,0 +1,37 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2008 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// This file tests explicit instantiation of library containers
+
+#include <forward_list>
+
+// { dg-do compile }
+
+// libstdc++/21770
+template class std::forward_list<int, std::allocator<char> >;