summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2014-11-19 11:15:14 -0500
committerDavid Malcolm <dmalcolm@redhat.com>2014-11-19 11:16:49 -0500
commit91b959f6dd1c7cd4ecdf7368cb022730ae08d667 (patch)
tree5368eda05ee3b4a07666ca0e96c7c9821d420c32
parentcf2cd094c5c77adb40a2f3f69021ee0b6f8534ab (diff)
parentaec08e4dc853a1460f6965fb75fdbacb517bd868 (diff)
downloadgcc-91b959f6dd1c7cd4ecdf7368cb022730ae08d667.tar.gz
Merge branch 'master' r217725-r217783 into gimple-classes-v2-option-3
Merger of changes on trunk r217725 (2014-11-18) to r217783 (2014-11-19) into the branch. gcc/ChangeLog.gimple-classes: * gimple.c (gimple_build_assign_with_ops): Strengthen return type of new overload, from gimple to gassign *. Conflicts: gcc/gimple-ssa-strength-reduction.c gcc/gimple.h gcc/omp-low.c gcc/tree-ssa-math-opts.c
-rw-r--r--ChangeLog29
-rw-r--r--MAINTAINERS1
-rw-r--r--config/ChangeLog6
-rw-r--r--config/mt-ospace4
-rw-r--r--gcc/ChangeLog261
-rw-r--r--gcc/ChangeLog.gimple-classes5
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/asan.c20
-rw-r--r--gcc/attribs.c6
-rw-r--r--gcc/c-family/ChangeLog11
-rw-r--r--gcc/c-family/c-common.c2
-rw-r--r--gcc/c-family/c-common.h2
-rw-r--r--gcc/c-family/c-ubsan.c28
-rw-r--r--gcc/c/c-parser.c40
-rw-r--r--gcc/calls.c14
-rw-r--r--gcc/cgraph.c2
-rw-r--r--gcc/cgraphunit.c11
-rw-r--r--gcc/collect2.c6
-rw-r--r--gcc/common.opt2
-rw-r--r--gcc/config/aarch64/aarch64.c8
-rw-r--r--gcc/config/aarch64/aarch64.h19
-rw-r--r--gcc/config/arc/arc.c4
-rw-r--r--gcc/config/arm/arm.md22
-rw-r--r--gcc/config/i386/i386.c19
-rw-r--r--gcc/config/mips/mips.c2
-rw-r--r--gcc/config/mips/mips.md22
-rw-r--r--gcc/config/moxie/moxie.c5
-rw-r--r--gcc/config/s390/s390.c2
-rw-r--r--gcc/config/sh/sh.c4
-rw-r--r--gcc/config/xtensa/xtensa.c2
-rw-r--r--gcc/cp/ChangeLog34
-rw-r--r--gcc/cp/constexpr.c402
-rw-r--r--gcc/cp/rtti.c2
-rw-r--r--gcc/doc/extend.texi13
-rw-r--r--gcc/doc/tm.texi4
-rw-r--r--gcc/fold-const.c7
-rw-r--r--gcc/gimple-builder.c2
-rw-r--r--gcc/gimple-fold.c36
-rw-r--r--gcc/gimple-ssa-strength-reduction.c9
-rw-r--r--gcc/gimple.c14
-rw-r--r--gcc/gimple.h27
-rw-r--r--gcc/gimplify.c17
-rw-r--r--gcc/go/gofrontend/gogo.cc132
-rw-r--r--gcc/internal-fn.c21
-rw-r--r--gcc/ipa-cp.c22
-rw-r--r--gcc/ipa-devirt.c8
-rw-r--r--gcc/ipa-inline-analysis.c13
-rw-r--r--gcc/ipa-inline-transform.c5
-rw-r--r--gcc/ipa-inline.c44
-rw-r--r--gcc/ipa-profile.c5
-rw-r--r--gcc/ipa-prop.c15
-rw-r--r--gcc/ipa-pure-const.c10
-rw-r--r--gcc/ipa-split.c2
-rw-r--r--gcc/ipa.c6
-rw-r--r--gcc/ira.c13
-rw-r--r--gcc/lto-wrapper.c6
-rw-r--r--gcc/omp-low.c31
-rw-r--r--gcc/simplify-rtx.c73
-rw-r--r--gcc/target.def8
-rw-r--r--gcc/targhooks.c7
-rw-r--r--gcc/targhooks.h2
-rw-r--r--gcc/testsuite/ChangeLog80
-rw-r--r--gcc/testsuite/c-c++-common/asan/misalign-1.c5
-rw-r--r--gcc/testsuite/c-c++-common/asan/misalign-2.c5
-rw-r--r--gcc/testsuite/c-c++-common/gomp/pr60823-4.c7
-rw-r--r--gcc/testsuite/c-c++-common/ubsan/pr63520.c16
-rw-r--r--gcc/testsuite/c-c++-common/ubsan/pr63879-1.c23
-rw-r--r--gcc/testsuite/c-c++-common/ubsan/pr63879-2.c13
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-empty8.C7
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-ref7.C11
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-stmtexpr2.C12
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-incr1.C12
-rw-r--r--gcc/testsuite/g++.dg/ubsan/pr63813.C12
-rw-r--r--gcc/testsuite/g++.dg/ubsan/pr63913.C12
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr61042.c10
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr63843.c31
-rw-r--r--gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-5.c1
-rw-r--r--gcc/testsuite/gcc.dg/cwsc0.c16
-rw-r--r--gcc/testsuite/gcc.dg/cwsc1.c46
-rw-r--r--gcc/testsuite/gcc.dg/memset-2.c11
-rw-r--r--gcc/testsuite/gcc.dg/pr51879-12.c4
-rw-r--r--gcc/testsuite/gcc.dg/pr62167-run.c47
-rw-r--r--gcc/testsuite/gcc.dg/pr62167.c50
-rw-r--r--gcc/testsuite/gcc.dg/pr63762.c77
-rw-r--r--gcc/testsuite/gcc.dg/pure-2.c6
-rw-r--r--gcc/testsuite/gcc.dg/ubsan/pr63690.c18
-rw-r--r--gcc/tree-cfg.c22
-rw-r--r--gcc/tree-loop-distribution.c3
-rw-r--r--gcc/tree-ssa-forwprop.c12
-rw-r--r--gcc/tree-ssa-loop-im.c2
-rw-r--r--gcc/tree-ssa-math-opts.c21
-rw-r--r--gcc/tree-ssa-phiopt.c10
-rw-r--r--gcc/tree-ssa-reassoc.c7
-rw-r--r--gcc/tree-ssa-strlen.c2
-rw-r--r--gcc/tree-ssa-tail-merge.c6
-rw-r--r--gcc/tree-vect-loop-manip.c2
-rw-r--r--gcc/tree-vect-loop.c8
-rw-r--r--gcc/tree-vect-patterns.c44
-rw-r--r--gcc/tree-vect-slp.c2
-rw-r--r--gcc/tree-vect-stmts.c26
-rw-r--r--gcc/tree-vrp.c17
-rw-r--r--gcc/tsan.c8
-rw-r--r--gcc/ubsan.c44
-rw-r--r--gcc/varpool.c2
-rw-r--r--libgomp/ChangeLog6
-rw-r--r--libgomp/testsuite/libgomp.c/examples-4/e.53.5.c2
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/e.53.5.f902
-rw-r--r--libstdc++-v3/ChangeLog9
-rw-r--r--libstdc++-v3/config/abi/pre/float128.ver10
-rwxr-xr-xlibstdc++-v3/configure3
-rw-r--r--libstdc++-v3/configure.ac3
-rw-r--r--libstdc++-v3/testsuite/util/testsuite_abi.cc9
112 files changed, 1754 insertions, 611 deletions
diff --git a/ChangeLog b/ChangeLog
index 0d93365e311..f155d54b359 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,32 @@
+2014-11-19 Maxim Kuvyrkov <maxim.kuvyrkov@linaro.org>
+
+ * MAINTAINERS (OS Port Maintainers): Add overdue maintainership note
+ from 2 years ago.
+
+2014-11-19 Alex Velenko <Alex.Velenko@arm.com>
+
+ Revert:
+ 2014-11-19 Alex Velenko <Alex.Velenko@arm.com>
+
+ * MAINTAINERS (Write After Approval): Added myself as line map
+ maintainer.
+
+2014-11-19 Renlin Li <Renlin.Li@arm.com>
+
+ Revert:
+ 2014-11-19 Renlin Li <Renlin.Li@arm.com>
+
+ * MAINTAINERS (Write After Approval): Added myself.
+
+2014-11-19 Renlin Li <Renlin.Li@arm.com>
+
+ * MAINTAINERS (Write After Approval): Added myself.
+
+2014-11-19 Alex Velenko <Alex.Velenko@arm.com>
+
+ * MAINTAINERS (Write After Approval): Added myself as line map
+ maintainer.
+
2014-11-17 Dodji Seketeli <dodji@redhat.com>
* MAINTAINERS (Various Maintainers): Added myself as line map
diff --git a/MAINTAINERS b/MAINTAINERS
index 56e68c5e7ab..b0cf9da458b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -121,6 +121,7 @@ xtensa port Sterling Augustine <augustine.sterling@gmail.com>
OS Port Maintainers (OS alphabetical order)
aix David Edelsohn <dje.gcc@gmail.com>
+Android sub-port Maxim Kuvyrkov <maxim.kuvyrkov@linaro.org>
darwin port Mike Stump <mikestump@comcast.net>
darwin port Eric Christopher <echristo@gmail.com>
darwin port Stan Shebs <stanshebs@earthlink.net>
diff --git a/config/ChangeLog b/config/ChangeLog
index 6f27566974d..ab3a773049d 100644
--- a/config/ChangeLog
+++ b/config/ChangeLog
@@ -1,3 +1,9 @@
+2014-11-17 Bob Dunlop <bob.dunlop@xyzzy.org.uk>
+
+ * mt-ospace (CFLAGS_FOR_TARGET): Append -g -Os rather than
+ overwriting.
+ (CXXFLAGS_FOR_TARGET): Similarly.
+
2014-11-17 H.J. Lu <hongjiu.lu@intel.com>
PR bootstrap/63888
diff --git a/config/mt-ospace b/config/mt-ospace
index 7f091041d8a..ce29ff4315d 100644
--- a/config/mt-ospace
+++ b/config/mt-ospace
@@ -1,3 +1,3 @@
# Build libraries optimizing for space, not speed.
- CFLAGS_FOR_TARGET = -g -Os
- CXXFLAGS_FOR_TARGET = -g -Os
+ CFLAGS_FOR_TARGET += -g -Os
+ CXXFLAGS_FOR_TARGET += -g -Os
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4a825c17310..e20f8cbe896 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,264 @@
+2014-11-19 Renlin Li <Renlin.Li@arm.com>
+
+ PR middle-end/63762
+ * ira.c (ira): Update preferred class.
+
+2014-11-19 Jakub Jelinek <jakub@redhat.com>
+
+ * gimple.h (gimple_build_assign_with_ops): Add unary arg overload.
+ (gimple_assign_set_rhs_with_ops_1): Renamed to ...
+ (gimple_assign_set_rhs_with_ops): ... this. Adjust binary arg
+ inline overload to use it. Add unary arg overload.
+ * gimple.c (gimple_build_assign_with_ops): New unary arg overload.
+ (gimple_assign_set_rhs_from_tree): Use
+ gimple_assign_set_rhs_with_ops instead of
+ gimple_assign_set_rhs_with_ops_1.
+ (gimple_assign_set_rhs_with_ops_1): Renamed to ...
+ (gimple_assign_set_rhs_with_ops): ... this.
+ * ipa-split.c (split_function): Remove last NULL argument
+ from gimple_build_assign_with_ops call.
+ * tree-ssa-loop-im.c
+ (move_computations_dom_walker::before_dom_children): Likewise.
+ * tsan.c (instrument_builtin_call): Likewise.
+ * tree-vect-stmts.c (vect_init_vector, vectorizable_mask_load_store,
+ vectorizable_conversion, vectorizable_load): Likewise.
+ * tree-vect-loop.c (vect_is_simple_reduction_1,
+ get_initial_def_for_induction): Likewise.
+ * tree-loop-distribution.c (generate_memset_builtin): Likewise.
+ * tree-vect-patterns.c (vect_handle_widen_op_by_const,
+ vect_recog_widen_mult_pattern, vect_operation_fits_smaller_type,
+ vect_recog_over_widening_pattern, vect_recog_rotate_pattern,
+ vect_recog_vector_vector_shift_pattern, vect_recog_divmod_pattern,
+ vect_recog_mixed_size_cond_pattern, adjust_bool_pattern_cast,
+ adjust_bool_pattern, vect_recog_bool_pattern): Likewise.
+ * tree-ssa-phiopt.c (conditional_replacement, abs_replacement,
+ neg_replacement): Likewise.
+ * asan.c (build_shadow_mem_access, maybe_create_ssa_name,
+ maybe_cast_to_ptrmode, asan_expand_check_ifn): Likewise.
+ * tree-vect-slp.c (vect_get_constant_vectors): Likewise.
+ * omp-low.c (lower_rec_input_clauses, expand_omp_for_generic,
+ expand_omp_for_static_nochunk, expand_omp_for_static_chunk,
+ simd_clone_adjust): Likewise.
+ * tree-vect-loop-manip.c (vect_create_cond_for_align_checks): Likewise.
+ * gimple-ssa-strength-reduction.c (introduce_cast_before_cand,
+ replace_one_candidate): Likewise.
+ * gimple-builder.c (build_type_cast): Likewise.
+ * tree-ssa-forwprop.c (simplify_rotate): Likewise.
+ (forward_propagate_addr_expr_1): Remove last NULL argument
+ from gimple_assign_set_rhs_with_ops call.
+ (simplify_vector_constructor): Use gimple_assign_set_rhs_with_ops
+ instead of gimple_assign_set_rhs_with_ops_1.
+ * tree-ssa-reassoc.c (maybe_optimize_range_tests): Remove last NULL
+ argument from gimple_build_assign_with_ops call.
+ (repropagate_negates): Remove last NULL argument from
+ gimple_assign_set_rhs_with_ops call.
+ * ubsan.c (ubsan_expand_null_ifn, ubsan_expand_objsize_ifn): Remove
+ last NULL argument from gimple_build_assign_with_ops call.
+ (instrument_bool_enum_load): Likewise. Remove last NULL argument
+ from gimple_assign_set_rhs_with_ops call.
+ * tree-ssa-math-opts.c (build_and_insert_cast, convert_mult_to_fma):
+ Remove last NULL argument from gimple_build_assign_with_ops call.
+ (bswap_replace): Likewise. Use gimple_assign_set_rhs_with_ops instead
+ of gimple_assign_set_rhs_with_ops_1.
+ (convert_plusminus_to_widen): Use gimple_assign_set_rhs_with_ops
+ instead of gimple_assign_set_rhs_with_ops_1.
+ * gimple-fold.c (replace_stmt_with_simplification): Likewise.
+ (rewrite_to_defined_overflow, gimple_build): Remove last NULL argument
+ from gimple_build_assign_with_ops call.
+ * tree-ssa-strlen.c (handle_pointer_plus): Remove last NULL argument
+ from gimple_assign_set_rhs_with_ops call.
+ * tree-vrp.c (simplify_truth_ops_using_ranges,
+ simplify_bit_ops_using_ranges): Remove last NULL argument from
+ gimple_assign_set_rhs_with_ops call.
+ (simplify_float_conversion_using_ranges,
+ simplify_internal_call_using_ranges): Remove last NULL argument from
+ gimple_build_assign_with_ops call.
+
+2014-11-19 Wilco Dijkstra <wdijkstr@arm.com>
+
+ PR target/61915
+ * config/aarch64/aarch64.c (generic_regmove_cost): Increase FP move
+ cost.
+
+2014-11-19 Marek Polacek <polacek@redhat.com>
+
+ PR sanitizer/63690
+ * ubsan.c (instrument_object_size): Check for MEM_REF.
+
+2014-11-19 Ilya Verbin <ilya.verbin@intel.com>
+
+ PR regression/63868
+ * cgraph.c (cgraph_node::create): Guard g->have_offload with
+ ifdef ENABLE_OFFLOADING.
+ * omp-low.c (create_omp_child_function): Likewise.
+ (expand_omp_target): Guard node->mark_force_output and offload_funcs
+ with ifdef ENABLE_OFFLOADING.
+ * varpool.c (varpool_node::get_create): Guard g->have_offload and
+ offload_vars with ifdef ENABLE_OFFLOADING.
+
+2014-11-19 Felix Yang <felix.yang@huawei.com>
+ Shanyao Chen <chenshanyao@huawei.com>
+
+ PR target/59593
+ * config/arm/arm.md (define_attr "arch"): Add v6t2.
+ (define_attr "arch_enabled"): Add test for the above.
+ (*movhi_insn_arch4): Add new alternative.
+
+2014-11-19 Richard Henderson <rth@redhat.com>
+
+ * c-family/c-common.c (c_common_reswords): Add
+ __builtin_call_with_static_chain.
+ * c-family/c-common.h (RID_BUILTIN_CALL_WITH_STATIC_CHAIN): New.
+ * c/c-parser.c (c_parser_postfix_expression): Handle it.
+ * doc/extend.texi (__builtin_call_with_static_chain): Document it.
+
+ * calls.c (prepare_call_address): Allow decl or type for first arg.
+ (expand_call): Pass type to prepare_call_address if no decl.
+ * gimple-fold.c (gimple_fold_call): Eliminate the static chain if
+ the function doesn't use it; fold it otherwise.
+ * gimplify.c (gimplify_call_expr): Gimplify the static chain.
+ * tree-cfg.c (verify_gimple_call): Allow a static chain on indirect
+ function calls.
+
+ * targhooks.c (default_static_chain): Remove check for
+ DECL_STATIC_CHAIN.
+ * config/moxie/moxie.c (moxie_static_chain): Likewise.
+ * config/i386/i386.c (ix86_static_chain): Allow decl or type
+ as the first argument.
+ * config/xtensa/xtensa.c (xtensa_static_chain): Change the name
+ of the unused first parameter.
+ * doc/tm.texi (TARGET_STATIC_CHAIN): Document the first parameter
+ may be a type.
+ * target.def (static_chain): Likewise.
+
+2014-11-19 Renlin Li <renlin.li@arm.com>
+
+ * config/aarch64/aarch64.h (TARGET_CPU_CPP_BUILTINS): Define __ARM_FP_FAST,
+ __ARM_FEATURE_FMA, __ARM_FP, __ARM_FEATURE_NUMERIC_MAXMIN, __ARM_NEON_FP.
+
+2014-11-19 Marek Polacek <polacek@redhat.com>
+
+ PR sanitizer/63879
+ * fold-const.c (negate_expr_p) <case NEGATE_EXPR>: Return
+ !TYPE_OVERFLOW_SANITIZED.
+ (fold_negate_expr) <case INTEGER_CST>: Fold when overflow
+ does not trap and when overflow wraps, or when SANITIZE_SI_OVERFLOW
+ is 0.
+
+2014-11-19 Ilya Tocar <ilya.tocar@intel.com>
+
+ * collect2.c (main): Don't call fatal_error before
+ diagnostic_initialize.
+ * lto-wrapper.c (main): Likewise.
+
+2014-11-19 Tom de Vries <tom@codesourcery.com>
+
+ PR tree-optimization/62167
+ * tree-ssa-tail-merge.c (stmt_local_def): Handle statements with vuse
+ conservatively.
+ (gimple_equal_p): Don't use vn_valueize to compare for lhs equality of
+ assigns.
+
+2014-11-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/63915
+ * tree-vect-stmts.c (vectorizable_simd_clone_call): Pass
+ true instead of false as last argument to gsi_replace.
+
+ PR sanitizer/63520
+ * internal-fn.c (expand_ubsan_result_store): New function.
+ (expand_addsub_overflow, expand_neg_overflow, expand_mul_overflow):
+ Use it instead of just emit_move_insn.
+
+2014-11-19 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/63844
+ * omp-low.c (fixup_child_record_type): Use a restrict qualified
+ referece type for the receiver parameter.
+
+2014-11-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR sanitizer/63913
+ * ubsan.c: Include tree-eh.h.
+ (instrument_bool_enum_load): Handle loads that can throw.
+
+ PR rtl-optimization/63843
+ * simplify-rtx.c (simplify_binary_operation_1) <case ASHIFTRT>: For
+ optimization of ashiftrt of subreg of lshiftrt, check that code
+ is ASHIFTRT.
+
+2014-11-18 Andrew MacLeod <amacleod@redhat.com>
+
+ * attribs.c (decl_attributes): Remove always true condition,
+ TREE_TYPE(x) will never compare equal to a TYPE_DECL.
+
+2014-11-18 James Greenhalgh <james.greenhalgh@arm.com>
+
+ PR target/63937
+ * target.def (use_by_pieces_infrastructure_p): Take unsigned
+ HOST_WIDE_INT as the size parameter.
+ * targhooks.c (default_use_by_pieces_infrastructure_p): Likewise.
+ * targhooks.h (default_use_by_pieces_infrastructure_p): Likewise.
+ * config/arc/arc.c (arc_use_by_pieces_infrastructure_p)): Likewise.
+ * config/mips/mips.c (mips_use_by_pieces_infrastructure_p)): Likewise.
+ * config/s390/s390.c (s390_use_by_pieces_infrastructure_p)): Likewise.
+ * config/sh/sh.c (sh_use_by_pieces_infrastructure_p)): Likewise.
+ * config/aarch64/aarch64.c
+ (aarch64_use_by_pieces_infrastructure_p)): Likewise.
+ * doc/tm.texi: Regenerate.
+
+2014-11-18 Jan Hubicka <hubicka@ucw.cz>
+
+ * ipa-cp.c (ipcp_cloning_candidate_p): Use opt_for_fn.
+ (ipa_value_from_jfunc, ipa_context_from_jfunc): Skip sanity check.
+ (ipa_get_indirect_edge_target_1): Use opt_for_fn.
+ (good_cloning_opportunity_p): Likewise.
+ (ipa-cp gate): Enable ipa-cp with LTO.
+ * ipa-profile.c (ipa_propagate_frequency): Use opt_for_fn.
+ * ipa.c (symbol_table::remove_unreachable_nodes): Always build type
+ inheritance.
+ * ipa-inline-transform.c (inline_transform): Check if there are inlines
+ to apply even at -O0.
+ * cgraphunit.c (cgraph_node::finalize_function): Use opt_for_fn.
+ (analyze_functions): Build type inheritance graph.
+ * ipa-inline.c (can_inline_edge_p): Use opt_for_fn.
+ (want_early_inline_function_p, want_inline_small_function_p):
+ Likewise.
+ (check_callers): Likewise.
+ (edge_badness): Likewise.
+ (inline_small_functions): Always be ready for indirect inlining
+ to happend.
+ (ipa_inline): Always use want_inline_function_to_all_callers_p.
+ (early_inline_small_functions): Use opt_for_fn.
+ * ipa-inline-analysis.c (estimate_function_body_sizes): use opt_for_fn.
+ (estimate_function_body_sizes): Likewise.
+ (compute_inline_parameters): Likewise.
+ (estimate_edge_devirt_benefit): Likewise.
+ (inline_analyze_function): Likewise.
+ * ipa-devirt.c (ipa_devirt): Likewise.
+ (gate): Use in_lto_p.
+ * ipa-prop.c (ipa_func_spec_opts_forbid_analysis_p): Use opt_for_fn.
+ (try_make_edge_direct_virtual_call): Likewise.
+ (update_indirect_edges_after_inlining): Likewise.
+ (ipa_free_all_structures_after_ipa_cp): Add in_lto_p check.
+ * common.opt (findirect-inlining): Turn into optimization.
+ * ipa-pure-const.c (add_new_function): Use opt_for_fn.
+ (pure_const_generate_summary): Likewise.
+ (gate_pure_const): Always enable with in_lto_p.
+
+2014-11-18 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * config/mips/mips.md (compression): Add `micromips32' setting.
+ (enabled, length): Handle it.
+ (shift_compression): Replace `micromips' with `micromips32' in
+ the `compression' attribute.
+ (*add<mode>3, sub<mode>3): Likewise.
+
+2014-11-18 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * gcc/config/mips/mips.md (*jump_absolute): Use a branch when in
+ range, a jump otherwise.
+
2014-11-18 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* config/arm/cortex-a15-neon.md (cortex_a15_vfp_to_from_gp):
diff --git a/gcc/ChangeLog.gimple-classes b/gcc/ChangeLog.gimple-classes
index 93c03acc7f3..52d1150c4d4 100644
--- a/gcc/ChangeLog.gimple-classes
+++ b/gcc/ChangeLog.gimple-classes
@@ -1,3 +1,8 @@
+2014-11-19 David Malcolm <dmalcolm@redhat.com>
+
+ * gimple.c (gimple_build_assign_with_ops): Strengthen return type
+ of new overload, from gimple to gassign *.
+
2014-11-18 David Malcolm <dmalcolm@redhat.com>
* cgraphbuild.c (pass_build_cgraph_edges::execute): Fix linebreak
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 347fa0198ca..1f93cf44076 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20141118
+20141119
diff --git a/gcc/asan.c b/gcc/asan.c
index b794b3cb678..be28ede0fb8 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -1600,15 +1600,14 @@ build_shadow_mem_access (gimple_stmt_iterator *gsi, location_t location,
g = gimple_build_assign_with_ops (NOP_EXPR,
make_ssa_name (shadow_ptr_type, NULL),
- gimple_assign_lhs (g), NULL_TREE);
+ gimple_assign_lhs (g));
gimple_set_location (g, location);
gsi_insert_after (gsi, g, GSI_NEW_STMT);
t = build2 (MEM_REF, shadow_type, gimple_assign_lhs (g),
build_int_cst (shadow_ptr_type, 0));
g = gimple_build_assign_with_ops (MEM_REF,
- make_ssa_name (shadow_type, NULL),
- t, NULL_TREE);
+ make_ssa_name (shadow_type, NULL), t);
gimple_set_location (g, location);
gsi_insert_after (gsi, g, GSI_NEW_STMT);
return gimple_assign_lhs (g);
@@ -1626,7 +1625,7 @@ maybe_create_ssa_name (location_t loc, tree base, gimple_stmt_iterator *iter,
gimple g
= gimple_build_assign_with_ops (TREE_CODE (base),
make_ssa_name (TREE_TYPE (base), NULL),
- base, NULL_TREE);
+ base);
gimple_set_location (g, loc);
if (before_p)
gsi_insert_before (iter, g, GSI_SAME_STMT);
@@ -1646,8 +1645,8 @@ maybe_cast_to_ptrmode (location_t loc, tree len, gimple_stmt_iterator *iter,
return len;
gimple g
= gimple_build_assign_with_ops (NOP_EXPR,
- make_ssa_name (pointer_sized_int_node, NULL),
- len, NULL);
+ make_ssa_name (pointer_sized_int_node,
+ NULL), len);
gimple_set_location (g, loc);
if (before_p)
gsi_insert_before (iter, g, GSI_SAME_STMT);
@@ -2537,8 +2536,7 @@ asan_expand_check_ifn (gimple_stmt_iterator *iter, bool use_calls)
gimple g
= gimple_build_assign_with_ops (NOP_EXPR,
make_ssa_name (pointer_sized_int_node,
- NULL),
- base, NULL_TREE);
+ NULL), base);
gimple_set_location (g, loc);
gsi_insert_before (iter, g, GSI_SAME_STMT);
tree base_addr = gimple_assign_lhs (g);
@@ -2552,8 +2550,7 @@ asan_expand_check_ifn (gimple_stmt_iterator *iter, bool use_calls)
gcc_assert (nargs == 2);
g = gimple_build_assign_with_ops (NOP_EXPR,
make_ssa_name (pointer_sized_int_node,
- NULL),
- len, NULL_TREE);
+ NULL), len);
gimple_set_location (g, loc);
gsi_insert_before (iter, g, GSI_SAME_STMT);
tree sz_arg = gimple_assign_lhs (g);
@@ -2612,8 +2609,7 @@ asan_expand_check_ifn (gimple_stmt_iterator *iter, bool use_calls)
g = gimple_build_assign_with_ops (NOP_EXPR,
make_ssa_name (pointer_sized_int_node,
- NULL),
- base, NULL_TREE);
+ NULL), base);
gimple_set_location (g, loc);
gsi_insert_before (&gsi, g, GSI_NEW_STMT);
tree base_addr = gimple_assign_lhs (g);
diff --git a/gcc/attribs.c b/gcc/attribs.c
index 427a0f63f3d..fe847034897 100644
--- a/gcc/attribs.c
+++ b/gcc/attribs.c
@@ -502,11 +502,7 @@ decl_attributes (tree *node, tree attributes, int flags)
if (spec->type_required && DECL_P (*anode))
{
anode = &TREE_TYPE (*anode);
- /* Allow ATTR_FLAG_TYPE_IN_PLACE for the type's naming decl. */
- if (!(TREE_CODE (*anode) == TYPE_DECL
- && *anode == TYPE_NAME (TYPE_MAIN_VARIANT
- (TREE_TYPE (*anode)))))
- flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
+ flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
}
if (spec->function_type_required && TREE_CODE (*anode) != FUNCTION_TYPE
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index fa0518a63eb..cc6771a1bf5 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,14 @@
+2014-11-18 Jakub Jelinek <jakub@redhat.com>
+
+ PR sanitizer/63813
+ * c-ubsan.c (ubsan_maybe_instrument_reference_or_call): Change type
+ argument to ptype, set type to TREE_TYPE (ptype). Don't call
+ get_pointer_alignment for non-pointers. Use ptype, or if it is
+ reference type, corresponding pointer type, as type of kind
+ argument.
+ (ubsan_maybe_instrument_reference,
+ ubsan_maybe_instrument_member_call): Adjust callers.
+
2014-11-15 Marek Polacek <polacek@redhat.com>
PR middle-end/63884
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 839111a2122..95b6b1b93e0 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -453,6 +453,8 @@ const struct c_common_resword c_common_reswords[] =
{ "__attribute__", RID_ATTRIBUTE, 0 },
{ "__auto_type", RID_AUTO_TYPE, D_CONLY },
{ "__bases", RID_BASES, D_CXXONLY },
+ { "__builtin_call_with_static_chain",
+ RID_BUILTIN_CALL_WITH_STATIC_CHAIN, D_CONLY },
{ "__builtin_choose_expr", RID_CHOOSE_EXPR, D_CONLY },
{ "__builtin_complex", RID_BUILTIN_COMPLEX, D_CONLY },
{ "__builtin_shuffle", RID_BUILTIN_SHUFFLE, 0 },
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index ca6fc8beaf8..7e53923a551 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -101,7 +101,7 @@ enum rid
RID_EXTENSION, RID_IMAGPART, RID_REALPART, RID_LABEL, RID_CHOOSE_EXPR,
RID_TYPES_COMPATIBLE_P, RID_BUILTIN_COMPLEX, RID_BUILTIN_SHUFFLE,
RID_DFLOAT32, RID_DFLOAT64, RID_DFLOAT128,
- RID_FRACT, RID_ACCUM, RID_AUTO_TYPE,
+ RID_FRACT, RID_ACCUM, RID_AUTO_TYPE, RID_BUILTIN_CALL_WITH_STATIC_CHAIN,
/* C11 */
RID_ALIGNAS, RID_GENERIC,
diff --git a/gcc/c-family/c-ubsan.c b/gcc/c-family/c-ubsan.c
index ab16799b0c9..90b03f23e73 100644
--- a/gcc/c-family/c-ubsan.c
+++ b/gcc/c-family/c-ubsan.c
@@ -383,18 +383,19 @@ ubsan_maybe_instrument_array_ref (tree *expr_p, bool ignore_off_by_one)
}
static tree
-ubsan_maybe_instrument_reference_or_call (location_t loc, tree op, tree type,
+ubsan_maybe_instrument_reference_or_call (location_t loc, tree op, tree ptype,
enum ubsan_null_ckind ckind)
{
- tree orig_op = op;
- bool instrument = false;
- unsigned int mina = 0;
-
if (current_function_decl == NULL_TREE
|| lookup_attribute ("no_sanitize_undefined",
DECL_ATTRIBUTES (current_function_decl)))
return NULL_TREE;
+ tree type = TREE_TYPE (ptype);
+ tree orig_op = op;
+ bool instrument = false;
+ unsigned int mina = 0;
+
if (flag_sanitize & SANITIZE_ALIGNMENT)
{
mina = min_align_of_type (type);
@@ -431,13 +432,20 @@ ubsan_maybe_instrument_reference_or_call (location_t loc, tree op, tree type,
}
else if (flag_sanitize & SANITIZE_NULL)
instrument = true;
- if (mina && mina > get_pointer_alignment (op) / BITS_PER_UNIT)
- instrument = true;
+ if (mina && mina > 1)
+ {
+ if (!POINTER_TYPE_P (TREE_TYPE (op))
+ || mina > get_pointer_alignment (op) / BITS_PER_UNIT)
+ instrument = true;
+ }
}
if (!instrument)
return NULL_TREE;
op = save_expr (orig_op);
- tree kind = build_int_cst (TREE_TYPE (op), ckind);
+ gcc_assert (POINTER_TYPE_P (ptype));
+ if (TREE_CODE (ptype) == REFERENCE_TYPE)
+ ptype = build_pointer_type (TREE_TYPE (ptype));
+ tree kind = build_int_cst (ptype, ckind);
tree align = build_int_cst (pointer_sized_int_node, mina);
tree call
= build_call_expr_internal_loc (loc, IFN_UBSAN_NULL, void_type_node,
@@ -453,7 +461,7 @@ ubsan_maybe_instrument_reference (tree stmt)
{
tree op = TREE_OPERAND (stmt, 0);
op = ubsan_maybe_instrument_reference_or_call (EXPR_LOCATION (stmt), op,
- TREE_TYPE (TREE_TYPE (stmt)),
+ TREE_TYPE (stmt),
UBSAN_REF_BINDING);
if (op)
TREE_OPERAND (stmt, 0) = op;
@@ -471,7 +479,7 @@ ubsan_maybe_instrument_member_call (tree stmt, bool is_ctor)
|| !POINTER_TYPE_P (TREE_TYPE (op)))
return;
op = ubsan_maybe_instrument_reference_or_call (EXPR_LOCATION (stmt), op,
- TREE_TYPE (TREE_TYPE (op)),
+ TREE_TYPE (op),
is_ctor ? UBSAN_CTOR_CALL
: UBSAN_MEMBER_CALL);
if (op)
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index f90f6af776e..8a4fd39fe80 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -7414,6 +7414,46 @@ c_parser_postfix_expression (c_parser *parser)
= comptypes (e1, e2) ? integer_one_node : integer_zero_node;
}
break;
+ case RID_BUILTIN_CALL_WITH_STATIC_CHAIN:
+ {
+ vec<c_expr_t, va_gc> *cexpr_list;
+ c_expr_t *e2_p;
+ tree chain_value;
+
+ c_parser_consume_token (parser);
+ if (!c_parser_get_builtin_args (parser,
+ "__builtin_call_with_static_chain",
+ &cexpr_list, false))
+ {
+ expr.value = error_mark_node;
+ break;
+ }
+ if (vec_safe_length (cexpr_list) != 2)
+ {
+ error_at (loc, "wrong number of arguments to "
+ "%<__builtin_call_with_static_chain%>");
+ expr.value = error_mark_node;
+ break;
+ }
+
+ expr = (*cexpr_list)[0];
+ e2_p = &(*cexpr_list)[1];
+ *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
+ chain_value = e2_p->value;
+ mark_exp_read (chain_value);
+
+ if (TREE_CODE (expr.value) != CALL_EXPR)
+ error_at (loc, "first argument to "
+ "%<__builtin_call_with_static_chain%> "
+ "must be a call expression");
+ else if (TREE_CODE (TREE_TYPE (chain_value)) != POINTER_TYPE)
+ error_at (loc, "second argument to "
+ "%<__builtin_call_with_static_chain%> "
+ "must be a pointer type");
+ else
+ CALL_EXPR_STATIC_CHAIN (expr.value) = chain_value;
+ break;
+ }
case RID_BUILTIN_COMPLEX:
{
vec<c_expr_t, va_gc> *cexpr_list;
diff --git a/gcc/calls.c b/gcc/calls.c
index 7f55aafa734..c64c0eb6bf7 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -197,7 +197,7 @@ static void restore_fixed_argument_area (rtx, rtx, int, int);
CALL_INSN_FUNCTION_USAGE information. */
rtx
-prepare_call_address (tree fndecl, rtx funexp, rtx static_chain_value,
+prepare_call_address (tree fndecl_or_type, rtx funexp, rtx static_chain_value,
rtx *call_fusage, int reg_parm_seen, int sibcallp)
{
/* Make a valid memory address and copy constants through pseudo-regs,
@@ -217,12 +217,13 @@ prepare_call_address (tree fndecl, rtx funexp, rtx static_chain_value,
#endif
}
- if (static_chain_value != 0)
+ if (static_chain_value != 0
+ && (TREE_CODE (fndecl_or_type) != FUNCTION_DECL
+ || DECL_STATIC_CHAIN (fndecl_or_type)))
{
rtx chain;
- gcc_assert (fndecl);
- chain = targetm.calls.static_chain (fndecl, false);
+ chain = targetm.calls.static_chain (fndecl_or_type, false);
static_chain_value = convert_memory_address (Pmode, static_chain_value);
emit_move_insn (chain, static_chain_value);
@@ -3278,8 +3279,9 @@ expand_call (tree exp, rtx target, int ignore)
}
after_args = get_last_insn ();
- funexp = prepare_call_address (fndecl, funexp, static_chain_value,
- &call_fusage, reg_parm_seen, pass == 0);
+ funexp = prepare_call_address (fndecl ? fndecl : fntype, funexp,
+ static_chain_value, &call_fusage,
+ reg_parm_seen, pass == 0);
load_register_parameters (args, num_actuals, &call_fusage, flags,
pass == 0, &sibcall_failure);
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index d7fd636703c..5323468b8f5 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -500,7 +500,9 @@ cgraph_node::create (tree decl)
&& lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl)))
{
node->offloadable = 1;
+#ifdef ENABLE_OFFLOADING
g->have_offload = true;
+#endif
}
node->register_symbol ();
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 3ac18bfee70..2fd99a7c098 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -450,7 +450,7 @@ cgraph_node::finalize_function (tree decl, bool no_collect)
declared inline and nested functions. These were optimized out
in the original implementation and it is unclear whether we want
to change the behavior here. */
- if ((!optimize
+ if ((!opt_for_fn (decl, optimize)
&& !node->cpp_implicit_alias
&& !DECL_DISREGARD_INLINE_LIMITS (decl)
&& !DECL_DECLARED_INLINE_P (decl)
@@ -929,8 +929,7 @@ analyze_functions (void)
FOR_EACH_SYMBOL (node)
if (node->cpp_implicit_alias)
node->fixup_same_cpp_alias_visibility (node->get_alias_target ());
- if (optimize && flag_devirtualize)
- build_type_inheritance_graph ();
+ build_type_inheritance_graph ();
/* Analysis adds static variables that in turn adds references to new functions.
So we need to iterate the process until it stabilize. */
@@ -1001,7 +1000,8 @@ analyze_functions (void)
for (edge = cnode->callees; edge; edge = edge->next_callee)
if (edge->callee->definition)
enqueue_node (edge->callee);
- if (optimize && opt_for_fn (cnode->decl, flag_devirtualize))
+ if (opt_for_fn (cnode->decl, optimize)
+ && opt_for_fn (cnode->decl, flag_devirtualize))
{
cgraph_edge *next;
@@ -1046,8 +1046,7 @@ analyze_functions (void)
symtab->process_new_functions ();
}
}
- if (optimize && flag_devirtualize)
- update_type_inheritance_graph ();
+ update_type_inheritance_graph ();
/* Collect entry points to the unit. */
if (symtab->dump_file)
diff --git a/gcc/collect2.c b/gcc/collect2.c
index 7c067ffcafb..9c3a1c55727 100644
--- a/gcc/collect2.c
+++ b/gcc/collect2.c
@@ -955,9 +955,6 @@ main (int argc, char **argv)
signal (SIGCHLD, SIG_DFL);
#endif
- if (atexit (collect_atexit) != 0)
- fatal_error ("atexit failed");
-
/* Unlock the stdio streams. */
unlock_std_streams ();
@@ -965,6 +962,9 @@ main (int argc, char **argv)
diagnostic_initialize (global_dc, 0);
+ if (atexit (collect_atexit) != 0)
+ fatal_error ("atexit failed");
+
/* Do not invoke xcalloc before this point, since locale needs to be
set first, in case a diagnostic is issued. */
diff --git a/gcc/common.opt b/gcc/common.opt
index 3a6d7e10c2c..41c8d4ed76d 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -1392,7 +1392,7 @@ Common Report Var(flag_inhibit_size_directive)
Do not generate .size directives
findirect-inlining
-Common Report Var(flag_indirect_inlining)
+Common Report Var(flag_indirect_inlining) Optimization
Perform indirect inlining
; General flag to enable inlining. Specifying -fno-inline will disable
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 4fec21ec88c..38321237eb3 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -229,8 +229,10 @@ __extension__
static const struct cpu_regmove_cost generic_regmove_cost =
{
NAMED_PARAM (GP2GP, 1),
- NAMED_PARAM (GP2FP, 2),
- NAMED_PARAM (FP2GP, 2),
+ /* Avoid the use of slow int<->fp moves for spilling by setting
+ their cost higher than memmov_cost. */
+ NAMED_PARAM (GP2FP, 5),
+ NAMED_PARAM (FP2GP, 5),
NAMED_PARAM (FP2FP, 2)
};
@@ -10196,7 +10198,7 @@ aarch64_asan_shadow_offset (void)
}
static bool
-aarch64_use_by_pieces_infrastructure_p (unsigned int size,
+aarch64_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
unsigned int align,
enum by_pieces_operation op,
bool speed_p)
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index c046b43c662..bbe33a92983 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -38,6 +38,8 @@
builtin_define ("__ARM_FEATURE_CLZ"); \
builtin_define ("__ARM_FEATURE_IDIV"); \
builtin_define ("__ARM_FEATURE_UNALIGNED"); \
+ if (flag_unsafe_math_optimizations) \
+ builtin_define ("__ARM_FP_FAST"); \
builtin_define ("__ARM_PCS_AAPCS64"); \
builtin_define_with_int_value \
("__ARM_SIZEOF_WCHAR_T", WCHAR_TYPE_SIZE / 8); \
@@ -52,10 +54,19 @@
else \
builtin_define ("__AARCH64EL__"); \
\
- if (TARGET_SIMD) \
- builtin_define ("__ARM_NEON"); \
- \
- if (TARGET_CRC32) \
+ if (TARGET_FLOAT) \
+ { \
+ builtin_define ("__ARM_FEATURE_FMA"); \
+ builtin_define_with_int_value ("__ARM_FP", 0x0C); \
+ } \
+ if (TARGET_SIMD) \
+ { \
+ builtin_define ("__ARM_FEATURE_NUMERIC_MAXMIN"); \
+ builtin_define ("__ARM_NEON"); \
+ builtin_define_with_int_value ("__ARM_NEON_FP", 0x0C);\
+ } \
+ \
+ if (TARGET_CRC32) \
builtin_define ("__ARM_FEATURE_CRC32"); \
\
switch (aarch64_cmodel) \
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 0f3825e10e5..764f7366c9a 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -416,7 +416,7 @@ static void output_short_suffix (FILE *file);
static bool arc_frame_pointer_required (void);
-static bool arc_use_by_pieces_infrastructure_p (unsigned int,
+static bool arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT,
unsigned int,
enum by_pieces_operation op,
bool);
@@ -9374,7 +9374,7 @@ arc_legitimize_reload_address (rtx *p, machine_mode mode, int opnum,
/* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P. */
static bool
-arc_use_by_pieces_infrastructure_p (unsigned int size,
+arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
unsigned int align,
enum by_pieces_operation op,
bool speed_p)
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index b9880b42301..3a6e0b04914 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -125,9 +125,10 @@
; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode. "v6"
; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
-; arm_arch6. This attribute is used to compute attribute "enabled",
-; use type "any" to enable an alternative in all cases.
-(define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,neon_for_64bits,avoid_neon_for_64bits,iwmmxt,iwmmxt2,armv6_or_vfpv3"
+; arm_arch6. "v6t2" for Thumb-2 with arm_arch6. This attribute is
+; used to compute attribute "enabled", use type "any" to enable an
+; alternative in all cases.
+(define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,v6t2,neon_for_64bits,avoid_neon_for_64bits,iwmmxt,iwmmxt2,armv6_or_vfpv3"
(const_string "any"))
(define_attr "arch_enabled" "no,yes"
@@ -162,6 +163,10 @@
(match_test "TARGET_32BIT && !arm_arch6"))
(const_string "yes")
+ (and (eq_attr "arch" "v6t2")
+ (match_test "TARGET_32BIT && arm_arch6 && arm_arch_thumb2"))
+ (const_string "yes")
+
(and (eq_attr "arch" "avoid_neon_for_64bits")
(match_test "TARGET_NEON")
(not (match_test "TARGET_PREFER_NEON_64BITS")))
@@ -6288,8 +6293,8 @@
;; Pattern to recognize insn generated default case above
(define_insn "*movhi_insn_arch4"
- [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r")
- (match_operand:HI 1 "general_operand" "rIk,K,r,mi"))]
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
+ (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
"TARGET_ARM
&& arm_arch4
&& (register_operand (operands[0], HImode)
@@ -6297,16 +6302,19 @@
"@
mov%?\\t%0, %1\\t%@ movhi
mvn%?\\t%0, #%B1\\t%@ movhi
+ movw%?\\t%0, %1\\t%@ movhi
str%(h%)\\t%1, %0\\t%@ movhi
ldr%(h%)\\t%0, %1\\t%@ movhi"
[(set_attr "predicable" "yes")
- (set_attr "pool_range" "*,*,*,256")
- (set_attr "neg_pool_range" "*,*,*,244")
+ (set_attr "pool_range" "*,*,*,*,256")
+ (set_attr "neg_pool_range" "*,*,*,*,244")
+ (set_attr "arch" "*,*,v6t2,*,*")
(set_attr_alternative "type"
[(if_then_else (match_operand 1 "const_int_operand" "")
(const_string "mov_imm" )
(const_string "mov_reg"))
(const_string "mvn_imm")
+ (const_string "mov_imm")
(const_string "store1")
(const_string "load1")])]
)
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 3166e0378a2..3b41de2e4f6 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -27356,13 +27356,10 @@ ix86_minimum_alignment (tree exp, machine_mode mode,
This is a register, unless all free registers are used by arguments. */
static rtx
-ix86_static_chain (const_tree fndecl, bool incoming_p)
+ix86_static_chain (const_tree fndecl_or_type, bool incoming_p)
{
unsigned regno;
- if (!DECL_STATIC_CHAIN (fndecl))
- return NULL;
-
if (TARGET_64BIT)
{
/* We always use R10 in 64-bit mode. */
@@ -27370,13 +27367,23 @@ ix86_static_chain (const_tree fndecl, bool incoming_p)
}
else
{
- tree fntype;
+ const_tree fntype, fndecl;
unsigned int ccvt;
/* By default in 32-bit mode we use ECX to pass the static chain. */
regno = CX_REG;
- fntype = TREE_TYPE (fndecl);
+ if (TREE_CODE (fndecl_or_type) == FUNCTION_DECL)
+ {
+ fntype = TREE_TYPE (fndecl_or_type);
+ fndecl = fndecl_or_type;
+ }
+ else
+ {
+ fntype = fndecl_or_type;
+ fndecl = NULL;
+ }
+
ccvt = ix86_get_callcvt (fntype);
if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
{
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 02268f3247e..db58d076e53 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -7235,7 +7235,7 @@ mips_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
/* Implement TARGET_USE_MOVE_BY_PIECES_INFRASTRUCTURE_P. */
bool
-mips_use_by_pieces_infrastructure_p (unsigned int size,
+mips_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
unsigned int align,
enum by_pieces_operation op,
bool speed_p)
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 647bf853c22..65c0a3f18fe 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -429,7 +429,7 @@
(const_string "yes")
(const_string "no")))
-(define_attr "compression" "none,all,micromips"
+(define_attr "compression" "none,all,micromips32,micromips"
(const_string "none"))
(define_attr "enabled" "no,yes"
@@ -440,7 +440,7 @@
|| TARGET_O32_FP64A_ABI")
(eq_attr "dword_mode" "yes"))
(const_string "no")
- (and (eq_attr "compression" "micromips")
+ (and (eq_attr "compression" "micromips32,micromips")
(match_test "!TARGET_MICROMIPS"))
(const_string "no")]
(const_string "yes")))
@@ -526,7 +526,9 @@
;; but there are special cases for branches (which must be handled here)
;; and for compressed single instructions.
(define_attr "length" ""
- (cond [(and (eq_attr "compression" "micromips,all")
+ (cond [(and (ior (eq_attr "compression" "micromips,all")
+ (and (eq_attr "compression" "micromips32")
+ (eq_attr "mode" "SI,SF")))
(eq_attr "dword_mode" "no")
(match_test "TARGET_MICROMIPS"))
(const_int 2)
@@ -979,8 +981,8 @@
(xor "xori")
(and "andi")])
-(define_code_attr shift_compression [(ashift "micromips")
- (lshiftrt "micromips")
+(define_code_attr shift_compression [(ashift "micromips32")
+ (lshiftrt "micromips32")
(ashiftrt "none")])
;; <fcond> is the c.cond.fmt condition associated with a particular code.
@@ -1163,7 +1165,7 @@
return "<d>addiu\t%0,%1,%2";
}
[(set_attr "alu_type" "add")
- (set_attr "compression" "micromips,*,micromips,micromips,micromips,micromips,*")
+ (set_attr "compression" "micromips32,*,micromips32,micromips32,micromips32,micromips32,*")
(set_attr "mode" "<MODE>")])
(define_insn "*add<mode>3_mips16"
@@ -1381,7 +1383,7 @@
""
"<d>subu\t%0,%1,%2"
[(set_attr "alu_type" "sub")
- (set_attr "compression" "micromips,*")
+ (set_attr "compression" "micromips32,*")
(set_attr "mode" "<MODE>")])
(define_insn "*subsi3_extended"
@@ -5955,14 +5957,12 @@
(label_ref (match_operand 0)))]
"!TARGET_MIPS16 && TARGET_ABSOLUTE_JUMPS"
{
- /* Use a branch for microMIPS. The assembler will choose
- a 16-bit branch, a 32-bit branch, or a 32-bit jump. */
- if (TARGET_MICROMIPS && !TARGET_ABICALLS_PIC2)
+ if (get_attr_length (insn) <= 8)
return "%*b\t%l0%/";
else
return MIPS_ABSOLUTE_JUMP ("%*j\t%l0%/");
}
- [(set_attr "type" "jump")])
+ [(set_attr "type" "branch")])
(define_insn "*jump_pic"
[(set (pc)
diff --git a/gcc/config/moxie/moxie.c b/gcc/config/moxie/moxie.c
index d4688d9c2f8..148d26be1f5 100644
--- a/gcc/config/moxie/moxie.c
+++ b/gcc/config/moxie/moxie.c
@@ -528,13 +528,10 @@ moxie_arg_partial_bytes (cumulative_args_t cum_v,
/* Worker function for TARGET_STATIC_CHAIN. */
static rtx
-moxie_static_chain (const_tree fndecl, bool incoming_p)
+moxie_static_chain (const_tree ARG_UNUSED (fndecl_or_type), bool incoming_p)
{
rtx addr, mem;
- if (!DECL_STATIC_CHAIN (fndecl))
- return NULL;
-
if (incoming_p)
addr = plus_constant (Pmode, arg_pointer_rtx, 2 * UNITS_PER_WORD);
else
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 31527624be4..ae3ffd12db1 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -12036,7 +12036,7 @@ s390_option_override (void)
/* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P. */
static bool
-s390_use_by_pieces_infrastructure_p (unsigned int size,
+s390_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
unsigned int align ATTRIBUTE_UNUSED,
enum by_pieces_operation op ATTRIBUTE_UNUSED,
bool speed_p ATTRIBUTE_UNUSED)
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 5bac2afbcbc..e4491210522 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -338,7 +338,7 @@ static void sh_conditional_register_usage (void);
static bool sh_legitimate_constant_p (machine_mode, rtx);
static int mov_insn_size (machine_mode, bool);
static int mov_insn_alignment_mask (machine_mode, bool);
-static bool sh_use_by_pieces_infrastructure_p (unsigned int,
+static bool sh_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT,
unsigned int,
enum by_pieces_operation,
bool);
@@ -13680,7 +13680,7 @@ sh_mode_priority (int entity ATTRIBUTE_UNUSED, int n)
/* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P. */
static bool
-sh_use_by_pieces_infrastructure_p (unsigned int size,
+sh_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
unsigned int align,
enum by_pieces_operation op,
bool speed_p)
diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c
index 159a1a76468..a0025a51331 100644
--- a/gcc/config/xtensa/xtensa.c
+++ b/gcc/config/xtensa/xtensa.c
@@ -3626,7 +3626,7 @@ xtensa_function_value_regno_p (const unsigned int regno)
expressions that denote where they are stored. */
static rtx
-xtensa_static_chain (const_tree ARG_UNUSED (fndecl), bool incoming_p)
+xtensa_static_chain (const_tree ARG_UNUSED (fndecl_or_type), bool incoming_p)
{
rtx base = incoming_p ? arg_pointer_rtx : stack_pointer_rtx;
return gen_frame_mem (Pmode, plus_constant (Pmode, base,
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 117355975fa..5769d2af30e 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,39 @@
2014-11-18 Jason Merrill <jason@redhat.com>
+ PR c++/63924
+ * constexpr.c (cxx_eval_constant_expression) [PARM_DECL]: A load
+ from a variable of empty class type is constant.
+
+ * constexpr.c (cxx_eval_statement_list): Handle statement-expressions.
+ (potential_constant_expression_1): Handle STMT_EXPR.
+
+ * constexpr.c (cxx_eval_constant_expression): Give jump_target a
+ default argument.
+ (lots): Omit NULL jump_target arguments.
+
+ * constexpr.c (struct constexpr_ctx): Add quiet field.
+ (cxx_eval_outermost_constant_expr, is_sub_constant_expr): Set it.
+ (lots): Replace allow_non_constant parameter with ctx->quiet.
+
+ PR c++/63940
+ * constexpr.c (cxx_eval_binary_expression): Don't assume the
+ expression was already folded.
+ (cxx_eval_unary_expression): Likewise.
+
+2014-11-18 Marc Glisse <marc.glisse@inria.fr>
+
+ PR libstdc++/43622
+ * rtti.c (emit_support_tinfos): Handle __float128.
+
+2014-11-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/63925
+ * constexpr.c (cxx_eval_increment_expression): Use POINTER_PLUS_EXPR.
+
+ PR c++/63934
+ * constexpr.c (cxx_eval_call_expression): Check DECL_CONSTRUCTOR_P
+ rather than VOID_TYPE_P.
+
* pt.c (instantiate_template_1): Use tsubst_aggr_type for context.
PR c++/58102
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 2f0708b40ec..1303fdc4d08 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -36,7 +36,7 @@ along with GCC; see the file COPYING3. If not see
static bool verify_constant (tree, bool, bool *, bool *);
#define VERIFY_CONSTANT(X) \
do { \
- if (verify_constant ((X), allow_non_constant, non_constant_p, overflow_p)) \
+ if (verify_constant ((X), ctx->quiet, non_constant_p, overflow_p)) \
return t; \
} while (0)
@@ -863,6 +863,7 @@ struct constexpr_ctx {
hash_map<tree,tree> *values;
tree ctor;
tree object;
+ bool quiet;
};
/* A table of all constexpr calls that have been evaluated by the
@@ -871,7 +872,7 @@ struct constexpr_ctx {
static GTY (()) hash_table<constexpr_call_hasher> *constexpr_call_table;
static tree cxx_eval_constant_expression (const constexpr_ctx *, tree,
- bool, bool, bool *, bool *, tree *);
+ bool, bool *, bool *, tree * = NULL);
/* Compute a hash value for a constexpr call representation. */
@@ -982,7 +983,7 @@ lookup_parameter_binding (const constexpr_call *call, tree t)
static tree
cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t,
- bool allow_non_constant, bool addr,
+ bool addr,
bool *non_constant_p, bool *overflow_p)
{
const int nargs = call_expr_nargs (t);
@@ -992,10 +993,9 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t,
for (i = 0; i < nargs; ++i)
{
args[i] = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, i),
- allow_non_constant, addr,
- non_constant_p, overflow_p,
- NULL);
- if (allow_non_constant && *non_constant_p)
+ addr,
+ non_constant_p, overflow_p);
+ if (ctx->quiet && *non_constant_p)
return t;
}
if (*non_constant_p)
@@ -1034,7 +1034,6 @@ adjust_temp_type (tree type, tree temp)
static void
cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t,
constexpr_call *new_call,
- bool allow_non_constant,
bool *non_constant_p, bool *overflow_p)
{
const int nargs = call_expr_nargs (t);
@@ -1067,11 +1066,11 @@ cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t,
type = TREE_TYPE (type);
x = convert_from_reference (x);
}
- arg = cxx_eval_constant_expression (ctx, x, allow_non_constant,
+ arg = cxx_eval_constant_expression (ctx, x,
TREE_CODE (type) == REFERENCE_TYPE,
- non_constant_p, overflow_p, NULL);
+ non_constant_p, overflow_p);
/* Don't VERIFY_CONSTANT here. */
- if (*non_constant_p && allow_non_constant)
+ if (*non_constant_p && ctx->quiet)
return;
/* Just discard ellipsis args after checking their constantitude. */
if (!parms)
@@ -1134,7 +1133,7 @@ cx_error_context (void)
static tree
cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
- bool allow_non_constant, bool addr,
+ bool addr,
bool *non_constant_p, bool *overflow_p)
{
location_t loc = EXPR_LOC_OR_LOC (t, input_location);
@@ -1148,16 +1147,16 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
if (TREE_CODE (fun) != FUNCTION_DECL)
{
/* Might be a constexpr function pointer. */
- fun = cxx_eval_constant_expression (ctx, fun, allow_non_constant,
+ fun = cxx_eval_constant_expression (ctx, fun,
/*addr*/false, non_constant_p,
- overflow_p, NULL);
+ overflow_p);
STRIP_NOPS (fun);
if (TREE_CODE (fun) == ADDR_EXPR)
fun = TREE_OPERAND (fun, 0);
}
if (TREE_CODE (fun) != FUNCTION_DECL)
{
- if (!allow_non_constant && !*non_constant_p)
+ if (!ctx->quiet && !*non_constant_p)
error_at (loc, "expression %qE does not designate a constexpr "
"function", fun);
*non_constant_p = true;
@@ -1166,11 +1165,11 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
if (DECL_CLONED_FUNCTION_P (fun))
fun = DECL_CLONED_FUNCTION (fun);
if (is_builtin_fn (fun))
- return cxx_eval_builtin_function_call (ctx, t, allow_non_constant,
+ return cxx_eval_builtin_function_call (ctx, t,
addr, non_constant_p, overflow_p);
if (!DECL_DECLARED_CONSTEXPR_P (fun))
{
- if (!allow_non_constant)
+ if (!ctx->quiet)
{
error_at (loc, "call to non-constexpr function %qD", fun);
explain_invalid_constexpr_fn (fun);
@@ -1185,9 +1184,9 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
if (call_expr_nargs (t) == 2)
{
tree arg = convert_from_reference (get_nth_callarg (t, 1));
- return cxx_eval_constant_expression (ctx, arg, allow_non_constant,
+ return cxx_eval_constant_expression (ctx, arg,
addr, non_constant_p,
- overflow_p, NULL);
+ overflow_p);
}
else if (TREE_CODE (t) == AGGR_INIT_EXPR
&& AGGR_INIT_ZERO_FIRST (t))
@@ -1202,7 +1201,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
new_call.fundef = retrieve_constexpr_fundef (fun);
if (new_call.fundef == NULL || new_call.fundef->body == NULL)
{
- if (!allow_non_constant)
+ if (!ctx->quiet)
{
if (DECL_INITIAL (fun))
{
@@ -1232,7 +1231,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
}
cxx_bind_parameters_in_call (ctx, t, &new_call,
- allow_non_constant, non_constant_p, overflow_p);
+ non_constant_p, overflow_p);
if (*non_constant_p)
return t;
@@ -1257,7 +1256,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
so that we can detect circular dependencies. */
else if (entry->result == NULL)
{
- if (!allow_non_constant)
+ if (!ctx->quiet)
error ("call has circular dependency");
*non_constant_p = true;
entry->result = result = error_mark_node;
@@ -1265,7 +1264,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
if (!depth_ok)
{
- if (!allow_non_constant)
+ if (!ctx->quiet)
error ("constexpr evaluation depth exceeds maximum of %d (use "
"-fconstexpr-depth= to increase the maximum)",
max_constexpr_depth);
@@ -1282,8 +1281,8 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
new_ctx.call = &new_call;
result = (cxx_eval_constant_expression
(&new_ctx, new_call.fundef->body,
- allow_non_constant, addr,
- non_constant_p, overflow_p, NULL));
+ addr,
+ non_constant_p, overflow_p));
}
else
{
@@ -1324,11 +1323,11 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
ctx->values->put (res, NULL_TREE);
tree jump_target = NULL_TREE;
- cxx_eval_constant_expression (ctx, body, allow_non_constant,
+ cxx_eval_constant_expression (ctx, body,
addr, non_constant_p, overflow_p,
&jump_target);
- if (VOID_TYPE_P (TREE_TYPE (res)))
+ if (DECL_CONSTRUCTOR_P (fun))
/* This can be null for a subobject constructor call, in
which case what we care about is the initialization
side-effects rather than the value. We could get at the
@@ -1340,7 +1339,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
result = *ctx->values->get (slot ? slot : res);
if (result == NULL_TREE)
{
- if (!allow_non_constant)
+ if (!ctx->quiet)
error ("constexpr call flows off the end "
"of the function");
*non_constant_p = true;
@@ -1367,7 +1366,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
{
/* If this was a call to initialize an object, set the type of
the CONSTRUCTOR to the type of that object. */
- if (DECL_CONSTRUCTOR_P (fun))
+ if (DECL_CONSTRUCTOR_P (fun) && !use_new_call)
{
tree ob_arg = get_nth_callarg (t, 0);
STRIP_NOPS (ob_arg);
@@ -1452,18 +1451,25 @@ verify_constant (tree t, bool allow_non_constant, bool *non_constant_p,
static tree
cxx_eval_unary_expression (const constexpr_ctx *ctx, tree t,
- bool allow_non_constant, bool addr,
+ bool addr,
bool *non_constant_p, bool *overflow_p)
{
tree r;
tree orig_arg = TREE_OPERAND (t, 0);
- tree arg = cxx_eval_constant_expression (ctx, orig_arg, allow_non_constant,
- addr, non_constant_p, overflow_p,
- NULL);
+ tree arg = cxx_eval_constant_expression (ctx, orig_arg,
+ addr, non_constant_p, overflow_p);
VERIFY_CONSTANT (arg);
- if (arg == orig_arg)
- return t;
- r = fold_build1 (TREE_CODE (t), TREE_TYPE (t), arg);
+ location_t loc = EXPR_LOCATION (t);
+ enum tree_code code = TREE_CODE (t);
+ tree type = TREE_TYPE (t);
+ r = fold_unary_loc (loc, code, type, arg);
+ if (r == NULL_TREE)
+ {
+ if (arg == orig_arg)
+ r = t;
+ else
+ r = build1_loc (loc, code, type, arg);
+ }
VERIFY_CONSTANT (r);
return r;
}
@@ -1473,7 +1479,7 @@ cxx_eval_unary_expression (const constexpr_ctx *ctx, tree t,
static tree
cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t,
- bool allow_non_constant, bool addr,
+ bool addr,
bool *non_constant_p, bool *overflow_p)
{
tree r;
@@ -1481,16 +1487,25 @@ cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t,
tree orig_rhs = TREE_OPERAND (t, 1);
tree lhs, rhs;
lhs = cxx_eval_constant_expression (ctx, orig_lhs,
- allow_non_constant, addr,
- non_constant_p, overflow_p, NULL);
+ addr,
+ non_constant_p, overflow_p);
VERIFY_CONSTANT (lhs);
rhs = cxx_eval_constant_expression (ctx, orig_rhs,
- allow_non_constant, addr,
- non_constant_p, overflow_p, NULL);
+ addr,
+ non_constant_p, overflow_p);
VERIFY_CONSTANT (rhs);
- if (lhs == orig_lhs && rhs == orig_rhs)
- return t;
- r = fold_build2 (TREE_CODE (t), TREE_TYPE (t), lhs, rhs);
+
+ location_t loc = EXPR_LOCATION (t);
+ enum tree_code code = TREE_CODE (t);
+ tree type = TREE_TYPE (t);
+ r = fold_binary_loc (loc, code, type, lhs, rhs);
+ if (r == NULL_TREE)
+ {
+ if (lhs == orig_lhs && rhs == orig_rhs)
+ r = t;
+ else
+ r = build2_loc (loc, code, type, lhs, rhs);
+ }
VERIFY_CONSTANT (r);
return r;
}
@@ -1501,23 +1516,22 @@ cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t,
static tree
cxx_eval_conditional_expression (const constexpr_ctx *ctx, tree t,
- bool allow_non_constant, bool addr,
+ bool addr,
bool *non_constant_p, bool *overflow_p,
tree *jump_target)
{
tree val = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
- allow_non_constant, addr,
- non_constant_p, overflow_p,
- NULL);
+ addr,
+ non_constant_p, overflow_p);
VERIFY_CONSTANT (val);
/* Don't VERIFY_CONSTANT the other operands. */
if (integer_zerop (val))
return cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 2),
- allow_non_constant, addr,
+ addr,
non_constant_p, overflow_p,
jump_target);
return cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
- allow_non_constant, addr,
+ addr,
non_constant_p, overflow_p,
jump_target);
}
@@ -1527,13 +1541,13 @@ cxx_eval_conditional_expression (const constexpr_ctx *ctx, tree t,
static tree
cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
- bool allow_non_constant, bool addr,
+ bool addr,
bool *non_constant_p, bool *overflow_p)
{
tree oldary = TREE_OPERAND (t, 0);
tree ary = cxx_eval_constant_expression (ctx, oldary,
- allow_non_constant, addr,
- non_constant_p, overflow_p, NULL);
+ addr,
+ non_constant_p, overflow_p);
tree index, oldidx;
HOST_WIDE_INT i;
tree elem_type;
@@ -1542,8 +1556,8 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
return t;
oldidx = TREE_OPERAND (t, 1);
index = cxx_eval_constant_expression (ctx, oldidx,
- allow_non_constant, false,
- non_constant_p, overflow_p, NULL);
+ false,
+ non_constant_p, overflow_p);
VERIFY_CONSTANT (index);
if (addr && ary == oldary && index == oldidx)
return t;
@@ -1573,19 +1587,18 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
initializer, it's value-initialized. */
tree val = build_value_init (elem_type, tf_warning_or_error);
return cxx_eval_constant_expression (ctx, val,
- allow_non_constant, addr,
- non_constant_p, overflow_p,
- NULL);
+ addr,
+ non_constant_p, overflow_p);
}
- if (!allow_non_constant)
+ if (!ctx->quiet)
error ("array subscript out of bound");
*non_constant_p = true;
return t;
}
else if (tree_int_cst_lt (index, integer_zero_node))
{
- if (!allow_non_constant)
+ if (!ctx->quiet)
error ("negative array subscript");
*non_constant_p = true;
return t;
@@ -1611,7 +1624,7 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
static tree
cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
- bool allow_non_constant, bool addr,
+ bool addr,
bool *non_constant_p, bool *overflow_p)
{
unsigned HOST_WIDE_INT i;
@@ -1620,8 +1633,8 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
tree part = TREE_OPERAND (t, 1);
tree orig_whole = TREE_OPERAND (t, 0);
tree whole = cxx_eval_constant_expression (ctx, orig_whole,
- allow_non_constant, addr,
- non_constant_p, overflow_p, NULL);
+ addr,
+ non_constant_p, overflow_p);
if (whole == orig_whole)
return t;
if (addr)
@@ -1631,13 +1644,13 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
CONSTRUCTOR. */
if (!*non_constant_p && TREE_CODE (whole) != CONSTRUCTOR)
{
- if (!allow_non_constant)
+ if (!ctx->quiet)
error ("%qE is not a constant expression", orig_whole);
*non_constant_p = true;
}
if (DECL_MUTABLE_P (part))
{
- if (!allow_non_constant)
+ if (!ctx->quiet)
error ("mutable %qD is not usable in a constant expression", part);
*non_constant_p = true;
}
@@ -1658,7 +1671,7 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
&& CONSTRUCTOR_NELTS (whole) > 0)
{
/* DR 1188 says we don't have to deal with this. */
- if (!allow_non_constant)
+ if (!ctx->quiet)
error ("accessing %qD member instead of initialized %qD member in "
"constant expression", part, CONSTRUCTOR_ELT (whole, 0)->index);
*non_constant_p = true;
@@ -1670,7 +1683,7 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
/* 'whole' is part of the aggregate initializer we're currently
building; if there's no initializer for this member yet, that's an
error. */
- if (!allow_non_constant)
+ if (!ctx->quiet)
error ("accessing uninitialized member %qD", part);
*non_constant_p = true;
return t;
@@ -1679,8 +1692,8 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
/* If there's no explicit init for this field, it's value-initialized. */
value = build_value_init (TREE_TYPE (t), tf_warning_or_error);
return cxx_eval_constant_expression (ctx, value,
- allow_non_constant, addr,
- non_constant_p, overflow_p, NULL);
+ addr,
+ non_constant_p, overflow_p);
}
/* Subroutine of cxx_eval_constant_expression.
@@ -1689,7 +1702,7 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
static tree
cxx_eval_bit_field_ref (const constexpr_ctx *ctx, tree t,
- bool allow_non_constant, bool addr,
+ bool addr,
bool *non_constant_p, bool *overflow_p)
{
tree orig_whole = TREE_OPERAND (t, 0);
@@ -1697,8 +1710,8 @@ cxx_eval_bit_field_ref (const constexpr_ctx *ctx, tree t,
bool fld_seen = false;
HOST_WIDE_INT istart, isize;
tree whole = cxx_eval_constant_expression (ctx, orig_whole,
- allow_non_constant, addr,
- non_constant_p, overflow_p, NULL);
+ addr,
+ non_constant_p, overflow_p);
tree start, field, value;
unsigned HOST_WIDE_INT i;
@@ -1710,7 +1723,7 @@ cxx_eval_bit_field_ref (const constexpr_ctx *ctx, tree t,
&& TREE_CODE (whole) != VECTOR_CST
&& TREE_CODE (whole) != CONSTRUCTOR)
{
- if (!allow_non_constant)
+ if (!ctx->quiet)
error ("%qE is not a constant expression", orig_whole);
*non_constant_p = true;
}
@@ -1775,20 +1788,20 @@ cxx_eval_bit_field_ref (const constexpr_ctx *ctx, tree t,
static tree
cxx_eval_logical_expression (const constexpr_ctx *ctx, tree t,
tree bailout_value, tree continue_value,
- bool allow_non_constant, bool addr,
+ bool addr,
bool *non_constant_p, bool *overflow_p)
{
tree r;
tree lhs = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
- allow_non_constant, addr,
- non_constant_p, overflow_p, NULL);
+ addr,
+ non_constant_p, overflow_p);
VERIFY_CONSTANT (lhs);
if (tree_int_cst_equal (lhs, bailout_value))
return lhs;
gcc_assert (tree_int_cst_equal (lhs, continue_value));
r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
- allow_non_constant, addr, non_constant_p,
- overflow_p, NULL);
+ addr, non_constant_p,
+ overflow_p);
VERIFY_CONSTANT (r);
return r;
}
@@ -1909,7 +1922,7 @@ verify_ctor_sanity (const constexpr_ctx *ctx, tree type)
static tree
cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t,
- bool allow_non_constant, bool addr,
+ bool addr,
bool *non_constant_p, bool *overflow_p)
{
vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (t);
@@ -1930,11 +1943,10 @@ cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t,
initializers can refer to it. */
CONSTRUCTOR_APPEND_ELT (*p, index, new_ctx.ctor);
tree elt = cxx_eval_constant_expression (&new_ctx, value,
- allow_non_constant, addr,
- non_constant_p, overflow_p,
- NULL);
+ addr,
+ non_constant_p, overflow_p);
/* Don't VERIFY_CONSTANT here. */
- if (allow_non_constant && *non_constant_p)
+ if (ctx->quiet && *non_constant_p)
break;
if (elt != value)
changed = true;
@@ -1990,7 +2002,7 @@ cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t,
static tree
cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
- bool value_init, bool allow_non_constant, bool addr,
+ bool value_init, bool addr,
bool *non_constant_p, bool *overflow_p)
{
tree elttype = TREE_TYPE (atype);
@@ -2041,7 +2053,7 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
eltinit = cp_build_array_ref (input_location, init, idx,
tf_warning_or_error);
eltinit = cxx_eval_vec_init_1 (&new_ctx, elttype, eltinit, value_init,
- allow_non_constant, addr,
+ addr,
non_constant_p, overflow_p);
}
else if (pre_init)
@@ -2049,8 +2061,8 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
/* Initializing an element using value or default initialization
we just pre-built above. */
eltinit = (cxx_eval_constant_expression
- (&new_ctx, init, allow_non_constant,
- addr, non_constant_p, overflow_p, NULL));
+ (&new_ctx, init,
+ addr, non_constant_p, overflow_p));
}
else
{
@@ -2063,10 +2075,10 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
eltinit = move (eltinit);
eltinit = force_rvalue (eltinit, tf_warning_or_error);
eltinit = (cxx_eval_constant_expression
- (&new_ctx, eltinit, allow_non_constant, addr,
- non_constant_p, overflow_p, NULL));
+ (&new_ctx, eltinit, addr,
+ non_constant_p, overflow_p));
}
- if (*non_constant_p && !allow_non_constant)
+ if (*non_constant_p && !ctx->quiet)
break;
if (new_ctx.ctor != ctx->ctor)
{
@@ -2088,14 +2100,14 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
static tree
cxx_eval_vec_init (const constexpr_ctx *ctx, tree t,
- bool allow_non_constant, bool addr,
+ bool addr,
bool *non_constant_p, bool *overflow_p)
{
tree atype = TREE_TYPE (t);
tree init = VEC_INIT_EXPR_INIT (t);
tree r = cxx_eval_vec_init_1 (ctx, atype, init,
VEC_INIT_EXPR_VALUE_INIT (t),
- allow_non_constant, addr, non_constant_p, overflow_p);
+ addr, non_constant_p, overflow_p);
if (*non_constant_p)
return t;
else
@@ -2295,13 +2307,13 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
static tree
cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t,
- bool allow_non_constant, bool addr,
+ bool addr,
bool *non_constant_p, bool *overflow_p)
{
tree orig_op0 = TREE_OPERAND (t, 0);
- tree op0 = cxx_eval_constant_expression (ctx, orig_op0, allow_non_constant,
+ tree op0 = cxx_eval_constant_expression (ctx, orig_op0,
/*addr*/false, non_constant_p,
- overflow_p, NULL);
+ overflow_p);
bool empty_base = false;
tree r;
@@ -2313,8 +2325,8 @@ cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t,
&empty_base);
if (r)
- r = cxx_eval_constant_expression (ctx, r, allow_non_constant,
- addr, non_constant_p, overflow_p, NULL);
+ r = cxx_eval_constant_expression (ctx, r,
+ addr, non_constant_p, overflow_p);
else
{
tree sub = op0;
@@ -2326,7 +2338,7 @@ cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t,
gcc_assert (!same_type_ignoring_top_level_qualifiers_p
(TREE_TYPE (TREE_TYPE (sub)), TREE_TYPE (t)));
/* DR 1188 says we don't have to deal with this. */
- if (!allow_non_constant)
+ if (!ctx->quiet)
error ("accessing value of %qE through a %qT glvalue in a "
"constant expression", build_fold_indirect_ref (sub),
TREE_TYPE (t));
@@ -2405,7 +2417,7 @@ non_const_var_error (tree r)
static tree
cxx_eval_trinary_expression (const constexpr_ctx *ctx, tree t,
- bool allow_non_constant, bool addr,
+ bool addr,
bool *non_constant_p, bool *overflow_p)
{
int i;
@@ -2415,9 +2427,8 @@ cxx_eval_trinary_expression (const constexpr_ctx *ctx, tree t,
for (i = 0; i < 3; i++)
{
args[i] = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, i),
- allow_non_constant, addr,
- non_constant_p, overflow_p,
- NULL);
+ addr,
+ non_constant_p, overflow_p);
VERIFY_CONSTANT (args[i]);
}
@@ -2441,7 +2452,7 @@ var_in_constexpr_fn (tree t)
static tree
cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
- bool allow_non_constant, bool addr,
+ bool addr,
bool *non_constant_p, bool *overflow_p)
{
constexpr_ctx new_ctx = *ctx;
@@ -2449,8 +2460,8 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
/* First we figure out where we're storing to. */
tree target = TREE_OPERAND (t, 0);
target = cxx_eval_constant_expression (ctx, target,
- allow_non_constant, true,
- non_constant_p, overflow_p, NULL);
+ true,
+ non_constant_p, overflow_p);
if (*non_constant_p)
return t;
@@ -2482,7 +2493,7 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
{
/* A constant-expression cannot modify objects from outside the
constant-expression. */
- if (!allow_non_constant)
+ if (!ctx->quiet)
error ("modification of %qD is not a constant-expression", object);
*non_constant_p = true;
return t;
@@ -2525,8 +2536,8 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
}
tree init = cxx_eval_constant_expression (&new_ctx, TREE_OPERAND (t, 1),
- allow_non_constant, false,
- non_constant_p, overflow_p, NULL);
+ false,
+ non_constant_p, overflow_p);
if (target == object)
/* The hash table might have moved since the get earlier. */
ctx->values->put (object, init);
@@ -2545,7 +2556,7 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
static tree
cxx_eval_increment_expression (const constexpr_ctx *ctx, tree t,
- bool allow_non_constant, bool addr,
+ bool addr,
bool *non_constant_p, bool *overflow_p)
{
enum tree_code code = TREE_CODE (t);
@@ -2555,25 +2566,34 @@ cxx_eval_increment_expression (const constexpr_ctx *ctx, tree t,
gcc_assert (TREE_CONSTANT (offset));
/* The operand as an lvalue. */
- op = cxx_eval_constant_expression (ctx, op, allow_non_constant, true,
- non_constant_p, overflow_p, NULL);
+ op = cxx_eval_constant_expression (ctx, op, true,
+ non_constant_p, overflow_p);
/* The operand as an rvalue. */
tree val = rvalue (op);
- val = cxx_eval_constant_expression (ctx, val, allow_non_constant, false,
- non_constant_p, overflow_p, NULL);
+ val = cxx_eval_constant_expression (ctx, val, false,
+ non_constant_p, overflow_p);
VERIFY_CONSTANT (val);
/* The modified value. */
bool inc = (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR);
- tree mod = fold_build2 (inc ? PLUS_EXPR : MINUS_EXPR,
- type, val, offset);
+ tree mod;
+ if (POINTER_TYPE_P (type))
+ {
+ /* The middle end requires pointers to use POINTER_PLUS_EXPR. */
+ offset = convert_to_ptrofftype (offset);
+ if (!inc)
+ offset = fold_build1 (NEGATE_EXPR, TREE_TYPE (offset), offset);
+ mod = fold_build2 (POINTER_PLUS_EXPR, type, val, offset);
+ }
+ else
+ mod = fold_build2 (inc ? PLUS_EXPR : MINUS_EXPR, type, val, offset);
VERIFY_CONSTANT (mod);
/* Storing the modified value. */
tree store = build2 (MODIFY_EXPR, type, op, mod);
- cxx_eval_constant_expression (ctx, store, allow_non_constant,
- true, non_constant_p, overflow_p, NULL);
+ cxx_eval_constant_expression (ctx, store,
+ true, non_constant_p, overflow_p);
/* And the value of the expression. */
if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR)
@@ -2660,12 +2680,19 @@ label_matches (tree *jump_target, tree_stmt_iterator i,
static tree
cxx_eval_statement_list (const constexpr_ctx *ctx, tree t,
- bool allow_non_constant,
bool *non_constant_p, bool *overflow_p,
tree *jump_target)
{
tree_stmt_iterator i;
tree_stmt_iterator default_label = tree_stmt_iterator();
+ tree local_target;
+ /* In a statement-expression we want to return the last value. */
+ tree r = NULL_TREE;
+ if (!jump_target)
+ {
+ local_target = NULL_TREE;
+ jump_target = &local_target;
+ }
for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
{
reenter:
@@ -2680,10 +2707,9 @@ cxx_eval_statement_list (const constexpr_ctx *ctx, tree t,
else
continue;
}
- cxx_eval_constant_expression (ctx, stmt,
- allow_non_constant, false,
- non_constant_p, overflow_p,
- jump_target);
+ r = cxx_eval_constant_expression (ctx, stmt, false,
+ non_constant_p, overflow_p,
+ jump_target);
if (*non_constant_p)
break;
if (returns (jump_target) || breaks (jump_target))
@@ -2695,7 +2721,7 @@ cxx_eval_statement_list (const constexpr_ctx *ctx, tree t,
*jump_target = NULL_TREE;
goto reenter;
}
- return NULL_TREE;
+ return r;
}
/* Evaluate a LOOP_EXPR for side-effects. Handles break and return
@@ -2703,14 +2729,13 @@ cxx_eval_statement_list (const constexpr_ctx *ctx, tree t,
static tree
cxx_eval_loop_expr (const constexpr_ctx *ctx, tree t,
- bool allow_non_constant,
bool *non_constant_p, bool *overflow_p,
tree *jump_target)
{
tree body = TREE_OPERAND (t, 0);
while (true)
{
- cxx_eval_statement_list (ctx, body, allow_non_constant,
+ cxx_eval_statement_list (ctx, body,
non_constant_p, overflow_p, jump_target);
if (returns (jump_target) || breaks (jump_target))
break;
@@ -2725,18 +2750,17 @@ cxx_eval_loop_expr (const constexpr_ctx *ctx, tree t,
static tree
cxx_eval_switch_expr (const constexpr_ctx *ctx, tree t,
- bool allow_non_constant,
bool *non_constant_p, bool *overflow_p,
tree *jump_target)
{
tree cond = TREE_OPERAND (t, 0);
- cond = cxx_eval_constant_expression (ctx, cond, allow_non_constant, false,
- non_constant_p, overflow_p, NULL);
+ cond = cxx_eval_constant_expression (ctx, cond, false,
+ non_constant_p, overflow_p);
VERIFY_CONSTANT (cond);
*jump_target = cond;
tree body = TREE_OPERAND (t, 1);
- cxx_eval_statement_list (ctx, body, allow_non_constant,
+ cxx_eval_statement_list (ctx, body,
non_constant_p, overflow_p, jump_target);
if (breaks (jump_target) || switches (jump_target))
*jump_target = NULL_TREE;
@@ -2750,7 +2774,7 @@ cxx_eval_switch_expr (const constexpr_ctx *ctx, tree t,
static tree
cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
- bool allow_non_constant, bool addr,
+ bool addr,
bool *non_constant_p, bool *overflow_p,
tree *jump_target)
{
@@ -2766,7 +2790,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
{
if (TREE_CODE (t) == PTRMEM_CST)
t = cplus_expand_constant (t);
- else if (TREE_OVERFLOW (t) && (!flag_permissive || allow_non_constant))
+ else if (TREE_OVERFLOW (t) && (!flag_permissive || ctx->quiet))
*overflow_p = true;
return t;
}
@@ -2798,7 +2822,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
r = *p;
if (DECL_P (r))
{
- if (!allow_non_constant)
+ if (!ctx->quiet)
non_const_var_error (r);
*non_constant_p = true;
}
@@ -2821,9 +2845,15 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
r = *p;
else if (addr)
/* Defer in case this is only used for its type. */;
+ else if (is_empty_class (TREE_TYPE (t)))
+ {
+ /* If the class is empty, we aren't actually loading anything. */
+ r = build_constructor (TREE_TYPE (t), NULL);
+ TREE_CONSTANT (r) = true;
+ }
else
{
- if (!allow_non_constant)
+ if (!ctx->quiet)
error ("%qE is not a constant expression", t);
*non_constant_p = true;
}
@@ -2831,7 +2861,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
case CALL_EXPR:
case AGGR_INIT_EXPR:
- r = cxx_eval_call_expression (ctx, t, allow_non_constant, addr,
+ r = cxx_eval_call_expression (ctx, t, addr,
non_constant_p, overflow_p);
break;
@@ -2852,9 +2882,8 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
if (tree init = DECL_INITIAL (r))
{
init = cxx_eval_constant_expression (ctx, init,
- allow_non_constant, false,
- non_constant_p, overflow_p,
- NULL);
+ false,
+ non_constant_p, overflow_p);
ctx->values->put (r, init);
}
else if (ctx == &new_ctx)
@@ -2867,7 +2896,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
case TARGET_EXPR:
if (!literal_type_p (TREE_TYPE (t)))
{
- if (!allow_non_constant)
+ if (!ctx->quiet)
{
error ("temporary of non-literal type %qT in a "
"constant expression", TREE_TYPE (t));
@@ -2891,8 +2920,8 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
/* Pass false for 'addr' because this indicates
initialization of a temporary. */
r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
- allow_non_constant, false,
- non_constant_p, overflow_p, NULL);
+ false,
+ non_constant_p, overflow_p);
if (!*non_constant_p)
/* Adjust the type of the result to the type of the temporary. */
r = adjust_temp_type (TREE_TYPE (t), r);
@@ -2904,26 +2933,26 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
/* In C++11 constexpr evaluation we are looking for the value,
not the side-effect of the initialization. */
r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
- allow_non_constant, false,
- non_constant_p, overflow_p, NULL);
+ false,
+ non_constant_p, overflow_p);
break;
}
/* else fall through */
case MODIFY_EXPR:
- r = cxx_eval_store_expression (ctx, t, allow_non_constant, addr,
+ r = cxx_eval_store_expression (ctx, t, addr,
non_constant_p, overflow_p);
break;
case SCOPE_REF:
r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
- allow_non_constant, addr,
- non_constant_p, overflow_p, NULL);
+ addr,
+ non_constant_p, overflow_p);
break;
case RETURN_EXPR:
r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
- allow_non_constant, addr,
- non_constant_p, overflow_p, NULL);
+ addr,
+ non_constant_p, overflow_p);
*jump_target = t;
break;
@@ -2935,7 +2964,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
case EXPR_STMT:
case EH_SPEC_BLOCK:
r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
- allow_non_constant, addr,
+ addr,
non_constant_p, overflow_p,
jump_target);
break;
@@ -2944,7 +2973,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
check for a constant operand or result; an address can be
constant without its operand being, and vice versa. */
case INDIRECT_REF:
- r = cxx_eval_indirect_ref (ctx, t, allow_non_constant, addr,
+ r = cxx_eval_indirect_ref (ctx, t, addr,
non_constant_p, overflow_p);
break;
@@ -2952,10 +2981,8 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
{
tree oldop = TREE_OPERAND (t, 0);
tree op = cxx_eval_constant_expression (ctx, oldop,
- allow_non_constant,
/*addr*/true,
- non_constant_p, overflow_p,
- NULL);
+ non_constant_p, overflow_p);
/* Don't VERIFY_CONSTANT here. */
if (*non_constant_p)
return t;
@@ -2976,7 +3003,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
case BIT_NOT_EXPR:
case TRUTH_NOT_EXPR:
case FIXED_CONVERT_EXPR:
- r = cxx_eval_unary_expression (ctx, t, allow_non_constant, addr,
+ r = cxx_eval_unary_expression (ctx, t, addr,
non_constant_p, overflow_p);
break;
@@ -3005,17 +3032,17 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
STRIP_NOPS (op1);
if ((TREE_CODE (op0) == TARGET_EXPR && op1 == TARGET_EXPR_SLOT (op0))
|| TREE_CODE (op1) == EMPTY_CLASS_EXPR)
- r = cxx_eval_constant_expression (ctx, op0, allow_non_constant,
+ r = cxx_eval_constant_expression (ctx, op0,
addr, non_constant_p, overflow_p,
jump_target);
else
{
/* Check that the LHS is constant and then discard it. */
- cxx_eval_constant_expression (ctx, op0, allow_non_constant,
+ cxx_eval_constant_expression (ctx, op0,
false, non_constant_p, overflow_p,
jump_target);
op1 = TREE_OPERAND (t, 1);
- r = cxx_eval_constant_expression (ctx, op1, allow_non_constant,
+ r = cxx_eval_constant_expression (ctx, op1,
addr, non_constant_p, overflow_p,
jump_target);
}
@@ -3061,7 +3088,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
case LTGT_EXPR:
case RANGE_EXPR:
case COMPLEX_EXPR:
- r = cxx_eval_binary_expression (ctx, t, allow_non_constant, addr,
+ r = cxx_eval_binary_expression (ctx, t, addr,
non_constant_p, overflow_p);
break;
@@ -3071,7 +3098,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
case TRUTH_ANDIF_EXPR:
r = cxx_eval_logical_expression (ctx, t, boolean_false_node,
boolean_true_node,
- allow_non_constant, addr,
+ addr,
non_constant_p, overflow_p);
break;
@@ -3079,12 +3106,12 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
case TRUTH_ORIF_EXPR:
r = cxx_eval_logical_expression (ctx, t, boolean_true_node,
boolean_false_node,
- allow_non_constant, addr,
+ addr,
non_constant_p, overflow_p);
break;
case ARRAY_REF:
- r = cxx_eval_array_reference (ctx, t, allow_non_constant, addr,
+ r = cxx_eval_array_reference (ctx, t, addr,
non_constant_p, overflow_p);
break;
@@ -3095,28 +3122,28 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
build_non_dependent_expr, because any expression that
calls or takes the address of the function will have
pulled a FUNCTION_DECL out of the COMPONENT_REF. */
- gcc_checking_assert (allow_non_constant || errorcount);
+ gcc_checking_assert (ctx->quiet || errorcount);
*non_constant_p = true;
return t;
}
- r = cxx_eval_component_reference (ctx, t, allow_non_constant, addr,
+ r = cxx_eval_component_reference (ctx, t, addr,
non_constant_p, overflow_p);
break;
case BIT_FIELD_REF:
- r = cxx_eval_bit_field_ref (ctx, t, allow_non_constant, addr,
+ r = cxx_eval_bit_field_ref (ctx, t, addr,
non_constant_p, overflow_p);
break;
case COND_EXPR:
case VEC_COND_EXPR:
- r = cxx_eval_conditional_expression (ctx, t, allow_non_constant, addr,
+ r = cxx_eval_conditional_expression (ctx, t, addr,
non_constant_p, overflow_p,
jump_target);
break;
case CONSTRUCTOR:
- r = cxx_eval_bare_aggregate (ctx, t, allow_non_constant, addr,
+ r = cxx_eval_bare_aggregate (ctx, t, addr,
non_constant_p, overflow_p);
break;
@@ -3126,13 +3153,13 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
be NULL, meaning default-initialization, or it will be an lvalue
or xvalue of the same type, meaning direct-initialization from the
corresponding member. */
- r = cxx_eval_vec_init (ctx, t, allow_non_constant, addr,
+ r = cxx_eval_vec_init (ctx, t, addr,
non_constant_p, overflow_p);
break;
case FMA_EXPR:
case VEC_PERM_EXPR:
- r = cxx_eval_trinary_expression (ctx, t, allow_non_constant, addr,
+ r = cxx_eval_trinary_expression (ctx, t, addr,
non_constant_p, overflow_p);
break;
@@ -3142,16 +3169,15 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
{
tree oldop = TREE_OPERAND (t, 0);
tree op = cxx_eval_constant_expression (ctx, oldop,
- allow_non_constant, addr,
- non_constant_p, overflow_p,
- NULL);
+ addr,
+ non_constant_p, overflow_p);
if (*non_constant_p)
return t;
if (POINTER_TYPE_P (TREE_TYPE (t))
&& TREE_CODE (op) == INTEGER_CST
&& !integer_zerop (op))
{
- if (!allow_non_constant)
+ if (!ctx->quiet)
error_at (EXPR_LOC_OR_LOC (t, input_location),
"reinterpret_cast from integer to pointer");
*non_constant_p = true;
@@ -3178,12 +3204,12 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
case STATEMENT_LIST:
new_ctx = *ctx;
new_ctx.ctor = new_ctx.object = NULL_TREE;
- return cxx_eval_statement_list (&new_ctx, t, allow_non_constant,
+ return cxx_eval_statement_list (&new_ctx, t,
non_constant_p, overflow_p, jump_target);
case BIND_EXPR:
return cxx_eval_constant_expression (ctx, BIND_EXPR_BODY (t),
- allow_non_constant, addr,
+ addr,
non_constant_p, overflow_p,
jump_target);
@@ -3191,7 +3217,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
case POSTINCREMENT_EXPR:
case PREDECREMENT_EXPR:
case POSTDECREMENT_EXPR:
- return cxx_eval_increment_expression (ctx, t, allow_non_constant,
+ return cxx_eval_increment_expression (ctx, t,
addr, non_constant_p, overflow_p);
case LAMBDA_EXPR:
@@ -3208,7 +3234,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
case NON_DEPENDENT_EXPR:
case BASELINK:
case OFFSET_REF:
- if (!allow_non_constant)
+ if (!ctx->quiet)
error_at (EXPR_LOC_OR_LOC (t, input_location),
"expression %qE is not a constant-expression", t);
*non_constant_p = true;
@@ -3220,7 +3246,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
/* A placeholder without a referent. We can get here when
checking whether NSDMIs are noexcept, or in massage_init_elt;
just say it's non-constant for now. */
- gcc_assert (allow_non_constant);
+ gcc_assert (ctx->quiet);
*non_constant_p = true;
break;
}
@@ -3233,8 +3259,8 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
gcc_assert (same_type_ignoring_top_level_qualifiers_p
(TREE_TYPE (t), TREE_TYPE (ctor)));
return cxx_eval_constant_expression
- (ctx, ctor, allow_non_constant, addr,
- non_constant_p, overflow_p, NULL);
+ (ctx, ctor, addr,
+ non_constant_p, overflow_p);
}
break;
@@ -3244,12 +3270,12 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
break;
case LOOP_EXPR:
- cxx_eval_loop_expr (ctx, t, allow_non_constant,
+ cxx_eval_loop_expr (ctx, t,
non_constant_p, overflow_p, jump_target);
break;
case SWITCH_EXPR:
- cxx_eval_switch_expr (ctx, t, allow_non_constant,
+ cxx_eval_switch_expr (ctx, t,
non_constant_p, overflow_p, jump_target);
break;
@@ -3275,7 +3301,7 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
{
bool non_constant_p = false;
bool overflow_p = false;
- constexpr_ctx ctx = { NULL, NULL, NULL, NULL };
+ constexpr_ctx ctx = { NULL, NULL, NULL, NULL, allow_non_constant };
hash_map<tree,tree> map;
ctx.values = &map;
tree type = initialized_type (t);
@@ -3310,8 +3336,8 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
r = TARGET_EXPR_INITIAL (r);
}
- r = cxx_eval_constant_expression (&ctx, r, allow_non_constant,
- false, &non_constant_p, &overflow_p, NULL);
+ r = cxx_eval_constant_expression (&ctx, r,
+ false, &non_constant_p, &overflow_p);
verify_constant (r, allow_non_constant, &non_constant_p, &overflow_p);
@@ -3384,11 +3410,11 @@ is_sub_constant_expr (tree t)
{
bool non_constant_p = false;
bool overflow_p = false;
- constexpr_ctx ctx = { NULL, NULL, NULL, NULL };
+ constexpr_ctx ctx = { NULL, NULL, NULL, NULL, true };
hash_map <tree, tree> map;
ctx.values = &map;
- cxx_eval_constant_expression (&ctx, t, true, false, &non_constant_p,
- &overflow_p, NULL);
+ cxx_eval_constant_expression (&ctx, t, false, &non_constant_p,
+ &overflow_p);
return !non_constant_p && !overflow_p;
}
@@ -3872,6 +3898,9 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags)
return false;
return true;
+ case STMT_EXPR:
+ return potential_constant_expression_1 (STMT_EXPR_STMT (t), rval, flags);
+
case LAMBDA_EXPR:
case DYNAMIC_CAST_EXPR:
case PSEUDO_DTOR_EXPR:
@@ -3887,7 +3916,6 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags)
/* GCC internal stuff. */
case VA_ARG_EXPR:
case OBJ_TYPE_REF:
- case STMT_EXPR:
case TRANSACTION_EXPR:
case ASM_EXPR:
fail:
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index 0d6dd960003..aef71f27bc5 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -1547,6 +1547,8 @@ emit_support_tinfos (void)
emit_support_tinfo_1 (int_n_trees[ix].signed_type);
emit_support_tinfo_1 (int_n_trees[ix].unsigned_type);
}
+ for (tree t = registered_builtin_types; t; t = TREE_CHAIN (t))
+ emit_support_tinfo_1 (TREE_VALUE (t));
}
/* Finish a type info decl. DECL_PTR is a pointer to an unemitted
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index d10a815a977..7178c9a7e8e 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -8913,6 +8913,7 @@ in the Cilk Plus language manual which can be found at
@node Other Builtins
@section Other Built-in Functions Provided by GCC
@cindex built-in functions
+@findex __builtin_call_with_static_chain
@findex __builtin_fpclassify
@findex __builtin_isfinite
@findex __builtin_isnormal
@@ -9501,6 +9502,18 @@ depending on the arguments' types. For example:
@end deftypefn
+@deftypefn {Built-in Function} @var{type} __builtin_call_with_static_chain (@var{call_exp}, @var{pointer_exp})
+
+The @var{call_exp} expression must be a function call, and the
+@var{pointer_exp} expression must be a pointer. The @var{pointer_exp}
+is passed to the function call in the target's static chain location.
+The result of builtin is the result of the function call.
+
+@emph{Note:} This builtin is only available for C@.
+This builtin can be used to call Go closures from C.
+
+@end deftypefn
+
@deftypefn {Built-in Function} @var{type} __builtin_choose_expr (@var{const_exp}, @var{exp1}, @var{exp2})
You can use the built-in function @code{__builtin_choose_expr} to
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index c09c51030ef..5b9da4776a1 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -3462,7 +3462,7 @@ If the static chain is passed in memory, these macros should not be
defined; instead, the @code{TARGET_STATIC_CHAIN} hook should be used.
@end defmac
-@deftypefn {Target Hook} rtx TARGET_STATIC_CHAIN (const_tree @var{fndecl}, bool @var{incoming_p})
+@deftypefn {Target Hook} rtx TARGET_STATIC_CHAIN (const_tree @var{fndecl_or_type}, bool @var{incoming_p})
This hook replaces the use of @code{STATIC_CHAIN_REGNUM} et al for
targets that may use different static chain locations for different
nested functions. This may be required if the target has function
@@ -6205,7 +6205,7 @@ optimized for speed rather than size.
If you don't define this, a reasonable default is used.
@end defmac
-@deftypefn {Target Hook} bool TARGET_USE_BY_PIECES_INFRASTRUCTURE_P (unsigned int @var{size}, unsigned int @var{alignment}, enum by_pieces_operation @var{op}, bool @var{speed_p})
+@deftypefn {Target Hook} bool TARGET_USE_BY_PIECES_INFRASTRUCTURE_P (unsigned HOST_WIDE_INT @var{size}, unsigned int @var{alignment}, enum by_pieces_operation @var{op}, bool @var{speed_p})
GCC will attempt several strategies when asked to copy between
two areas of memory, or to set, clear or store to memory, for example
when copying a @code{struct}. The @code{by_pieces} infrastructure
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index f6fb8af8084..9183430205b 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -408,9 +408,11 @@ negate_expr_p (tree t)
&& TYPE_OVERFLOW_WRAPS (type));
case FIXED_CST:
- case NEGATE_EXPR:
return true;
+ case NEGATE_EXPR:
+ return !TYPE_OVERFLOW_SANITIZED (type);
+
case REAL_CST:
/* We want to canonicalize to positive real constants. Pretend
that only negative ones can be easily negated. */
@@ -555,7 +557,8 @@ fold_negate_expr (location_t loc, tree t)
tem = fold_negate_const (t, type);
if (TREE_OVERFLOW (tem) == TREE_OVERFLOW (t)
|| (!TYPE_OVERFLOW_TRAPS (type)
- && (flag_sanitize & SANITIZE_SI_OVERFLOW) == 0))
+ && TYPE_OVERFLOW_WRAPS (type))
+ || (flag_sanitize & SANITIZE_SI_OVERFLOW) == 0)
return tem;
break;
diff --git a/gcc/gimple-builder.c b/gcc/gimple-builder.c
index a7c6c4e9635..c5c9938b81a 100644
--- a/gcc/gimple-builder.c
+++ b/gcc/gimple-builder.c
@@ -120,7 +120,7 @@ build_type_cast (tree to_type, tree op, tree lhs)
{
if (lhs == NULL_TREE)
lhs = make_ssa_name (to_type, NULL);
- return gimple_build_assign_with_ops (NOP_EXPR, lhs, op, NULL_TREE);
+ return gimple_build_assign_with_ops (NOP_EXPR, lhs, op);
}
gassign *
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index fb87b7f053f..8e0c9e055ef 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -2723,6 +2723,27 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
}
}
+ /* Check for indirect calls that became direct calls, and then
+ no longer require a static chain. */
+ if (gimple_call_chain (stmt))
+ {
+ tree fn = gimple_call_fndecl (stmt);
+ if (fn && !DECL_STATIC_CHAIN (fn))
+ {
+ gimple_call_set_chain (stmt, NULL);
+ changed = true;
+ }
+ else
+ {
+ tree tmp = maybe_fold_reference (gimple_call_chain (stmt), false);
+ if (tmp)
+ {
+ gimple_call_set_chain (stmt, tmp);
+ changed = true;
+ }
+ }
+ }
+
if (inplace)
return changed;
@@ -2962,8 +2983,7 @@ replace_stmt_with_simplification (gimple_stmt_iterator *gsi,
maybe_build_generic_op (rcode,
TREE_TYPE (gimple_assign_lhs (stmt)),
&ops[0], ops[1], ops[2]);
- gimple_assign_set_rhs_with_ops_1 (gsi, rcode,
- ops[0], ops[1], ops[2]);
+ gimple_assign_set_rhs_with_ops (gsi, rcode, ops[0], ops[1], ops[2]);
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "gimple_simplified to ");
@@ -5627,8 +5647,8 @@ rewrite_to_defined_overflow (gimple stmt)
if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
gimple_assign_set_rhs_code (stmt, PLUS_EXPR);
gimple_seq_add_stmt (&stmts, stmt);
- gimple cvt = gimple_build_assign_with_ops
- (NOP_EXPR, lhs, gimple_assign_lhs (stmt), NULL_TREE);
+ gimple cvt = gimple_build_assign_with_ops (NOP_EXPR, lhs,
+ gimple_assign_lhs (stmt));
gimple_seq_add_stmt (&stmts, cvt);
return stmts;
@@ -5658,10 +5678,9 @@ gimple_build (gimple_seq *seq, location_t loc,
|| code == IMAGPART_EXPR
|| code == VIEW_CONVERT_EXPR)
stmt = gimple_build_assign_with_ops (code, res,
- build1 (code, type,
- op0), NULL_TREE);
+ build1 (code, type, op0));
else
- stmt = gimple_build_assign_with_ops (code, res, op0, NULL_TREE);
+ stmt = gimple_build_assign_with_ops (code, res, op0);
gimple_set_location (stmt, loc);
gimple_seq_add_stmt_without_update (seq, stmt);
}
@@ -5716,8 +5735,7 @@ gimple_build (gimple_seq *seq, location_t loc,
if (code == BIT_FIELD_REF)
stmt = gimple_build_assign_with_ops (code, res,
build3 (BIT_FIELD_REF, type,
- op0, op1, op2),
- NULL_TREE);
+ op0, op1, op2));
else
stmt = gimple_build_assign_with_ops (code, res, op0, op1, op2);
gimple_set_location (stmt, loc);
diff --git a/gcc/gimple-ssa-strength-reduction.c b/gcc/gimple-ssa-strength-reduction.c
index b49e819a39e..e719129df24 100644
--- a/gcc/gimple-ssa-strength-reduction.c
+++ b/gcc/gimple-ssa-strength-reduction.c
@@ -3264,8 +3264,7 @@ introduce_cast_before_cand (slsr_cand_t c, tree to_type, tree from_expr)
gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
cast_lhs = make_temp_ssa_name (to_type, NULL, "slsr");
- cast_stmt = gimple_build_assign_with_ops (NOP_EXPR, cast_lhs,
- from_expr, NULL_TREE);
+ cast_stmt = gimple_build_assign_with_ops (NOP_EXPR, cast_lhs, from_expr);
gimple_set_location (cast_stmt, gimple_location (c->cand_stmt));
gsi_insert_before (&gsi, cast_stmt, GSI_SAME_STMT);
@@ -3434,10 +3433,8 @@ replace_one_candidate (slsr_cand_t c, unsigned i, tree basis_name)
else
{
gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
- gassign *cast_stmt
- = gimple_build_assign_with_ops (NOP_EXPR, lhs,
- basis_name,
- NULL_TREE);
+ gassign *cast_stmt = gimple_build_assign_with_ops (NOP_EXPR, lhs,
+ basis_name);
gimple_set_location (cast_stmt, gimple_location (c->cand_stmt));
gsi_replace (&gsi, cast_stmt, false);
c->cand_stmt = cast_stmt;
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 6b908bfd1a1..69cac22a2b3 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -453,6 +453,14 @@ gimple_build_assign_with_ops (enum tree_code subcode, tree lhs, tree op1,
PASS_MEM_STAT);
}
+gassign *
+gimple_build_assign_with_ops (enum tree_code subcode, tree lhs, tree op1
+ MEM_STAT_DECL)
+{
+ return gimple_build_assign_with_ops (subcode, lhs, op1, NULL_TREE, NULL_TREE
+ PASS_MEM_STAT);
+}
+
/* Build a GIMPLE_COND statement.
@@ -1569,7 +1577,7 @@ gimple_assign_set_rhs_from_tree (gimple_stmt_iterator *gsi, tree expr)
tree op1, op2, op3;
extract_ops_from_tree_1 (expr, &subcode, &op1, &op2, &op3);
- gimple_assign_set_rhs_with_ops_1 (gsi, subcode, op1, op2, op3);
+ gimple_assign_set_rhs_with_ops (gsi, subcode, op1, op2, op3);
}
@@ -1580,8 +1588,8 @@ gimple_assign_set_rhs_from_tree (gimple_stmt_iterator *gsi, tree expr)
did not have enough operand slots. */
void
-gimple_assign_set_rhs_with_ops_1 (gimple_stmt_iterator *gsi, enum tree_code code,
- tree op1, tree op2, tree op3)
+gimple_assign_set_rhs_with_ops (gimple_stmt_iterator *gsi, enum tree_code code,
+ tree op1, tree op2, tree op3)
{
unsigned new_rhs_ops = get_gimple_rhs_num_ops (code);
gimple stmt = gsi_stmt (*gsi);
diff --git a/gcc/gimple.h b/gcc/gimple.h
index baf45811a5a..7f319056a60 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -1300,10 +1300,11 @@ gcall *gimple_build_call_from_tree (tree);
gassign *gimple_build_assign_stat (tree, tree MEM_STAT_DECL);
#define gimple_build_assign(l,r) gimple_build_assign_stat (l, r MEM_STAT_INFO)
gassign *gimple_build_assign_with_ops (enum tree_code, tree,
- tree, tree,
- tree CXX_MEM_STAT_INFO);
+ tree, tree, tree CXX_MEM_STAT_INFO);
gassign *gimple_build_assign_with_ops (enum tree_code, tree,
- tree, tree CXX_MEM_STAT_INFO);
+ tree, tree CXX_MEM_STAT_INFO);
+gassign *gimple_build_assign_with_ops (enum tree_code, tree,
+ tree CXX_MEM_STAT_INFO);
gcond *gimple_build_cond (enum tree_code, tree, tree, tree, tree);
gcond *gimple_build_cond_from_tree (tree, tree, tree);
void gimple_cond_set_condition_from_tree (gcond *, tree);
@@ -1369,8 +1370,8 @@ bool gimple_assign_ssa_name_copy_p (gimple);
bool gimple_assign_unary_nop_p (gimple);
void gimple_set_bb (gimple, basic_block);
void gimple_assign_set_rhs_from_tree (gimple_stmt_iterator *, tree);
-void gimple_assign_set_rhs_with_ops_1 (gimple_stmt_iterator *, enum tree_code,
- tree, tree, tree);
+void gimple_assign_set_rhs_with_ops (gimple_stmt_iterator *, enum tree_code,
+ tree, tree, tree);
tree gimple_get_lhs (const_gimple);
void gimple_set_lhs (gimple, tree);
gimple gimple_copy (gimple);
@@ -2448,14 +2449,24 @@ gimple_assign_set_rhs3 (gimple gs, tree rhs)
gimple_set_op (gs, 3, rhs);
}
-/* A wrapper around gimple_assign_set_rhs_with_ops_1, for callers which expect
- to see only a maximum of two operands. */
+/* A wrapper around 3 operand gimple_assign_set_rhs_with_ops, for callers
+ which expect to see only two operands. */
static inline void
gimple_assign_set_rhs_with_ops (gimple_stmt_iterator *gsi, enum tree_code code,
tree op1, tree op2)
{
- gimple_assign_set_rhs_with_ops_1 (gsi, code, op1, op2, NULL);
+ gimple_assign_set_rhs_with_ops (gsi, code, op1, op2, NULL);
+}
+
+/* A wrapper around 3 operand gimple_assign_set_rhs_with_ops, for callers
+ which expect to see only one operands. */
+
+static inline void
+gimple_assign_set_rhs_with_ops (gimple_stmt_iterator *gsi, enum tree_code code,
+ tree op1)
+{
+ gimple_assign_set_rhs_with_ops (gsi, code, op1, NULL, NULL);
}
/* Returns true if GS is a nontemporal move. */
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index a985315dccd..8e3dd834a01 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -2432,7 +2432,7 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
}
}
- /* Finally, gimplify the function arguments. */
+ /* Gimplify the function arguments. */
if (nargs > 0)
{
for (i = (PUSH_ARGS_REVERSED ? nargs - 1 : 0);
@@ -2454,6 +2454,21 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
}
}
+ /* Gimplify the static chain. */
+ if (CALL_EXPR_STATIC_CHAIN (*expr_p))
+ {
+ if (fndecl && !DECL_STATIC_CHAIN (fndecl))
+ CALL_EXPR_STATIC_CHAIN (*expr_p) = NULL;
+ else
+ {
+ enum gimplify_status t;
+ t = gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p), pre_p,
+ EXPR_LOCATION (*expr_p));
+ if (t == GS_ERROR)
+ ret = GS_ERROR;
+ }
+ }
+
/* Verify the function result. */
if (want_value && fndecl
&& VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype))))
diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc
index 7c318ab1b89..453db9af9c1 100644
--- a/gcc/go/gofrontend/gogo.cc
+++ b/gcc/go/gofrontend/gogo.cc
@@ -1018,11 +1018,11 @@ class Var_init
{
public:
Var_init()
- : var_(NULL), init_(NULL)
+ : var_(NULL), init_(NULL), dep_count_(0)
{ }
Var_init(Named_object* var, Bstatement* init)
- : var_(var), init_(init)
+ : var_(var), init_(init), dep_count_(0)
{ }
// Return the variable.
@@ -1035,13 +1035,38 @@ class Var_init
init() const
{ return this->init_; }
+ // Return the number of remaining dependencies.
+ size_t
+ dep_count() const
+ { return this->dep_count_; }
+
+ // Increment the number of dependencies.
+ void
+ add_dependency()
+ { ++this->dep_count_; }
+
+ // Decrement the number of dependencies.
+ void
+ remove_dependency()
+ { --this->dep_count_; }
+
private:
// The variable being initialized.
Named_object* var_;
// The initialization statement.
Bstatement* init_;
+ // The number of initializations this is dependent on. A variable
+ // initialization should not be emitted if any of its dependencies
+ // have not yet been resolved.
+ size_t dep_count_;
};
+// For comparing Var_init keys in a map.
+
+inline bool
+operator<(const Var_init& v1, const Var_init& v2)
+{ return v1.var()->name() < v2.var()->name(); }
+
typedef std::list<Var_init> Var_inits;
// Sort the variable initializations. The rule we follow is that we
@@ -1052,14 +1077,21 @@ typedef std::list<Var_init> Var_inits;
static void
sort_var_inits(Gogo* gogo, Var_inits* var_inits)
{
+ if (var_inits->empty())
+ return;
+
typedef std::pair<Named_object*, Named_object*> No_no;
typedef std::map<No_no, bool> Cache;
Cache cache;
- Var_inits ready;
- while (!var_inits->empty())
+ // A mapping from a variable initialization to a set of
+ // variable initializations that depend on it.
+ typedef std::map<Var_init, std::set<Var_init*> > Init_deps;
+ Init_deps init_deps;
+ for (Var_inits::iterator p1 = var_inits->begin();
+ p1 != var_inits->end();
+ ++p1)
{
- Var_inits::iterator p1 = var_inits->begin();
Named_object* var = p1->var();
Expression* init = var->var_value()->init();
Block* preinit = var->var_value()->preinit();
@@ -1067,11 +1099,13 @@ sort_var_inits(Gogo* gogo, Var_inits* var_inits)
// Start walking through the list to see which variables VAR
// needs to wait for.
- Var_inits::iterator p2 = p1;
- ++p2;
-
- for (; p2 != var_inits->end(); ++p2)
+ for (Var_inits::iterator p2 = var_inits->begin();
+ p2 != var_inits->end();
+ ++p2)
{
+ if (var == p2->var())
+ continue;
+
Named_object* p2var = p2->var();
No_no key(var, p2var);
std::pair<Cache::iterator, bool> ins =
@@ -1080,6 +1114,10 @@ sort_var_inits(Gogo* gogo, Var_inits* var_inits)
ins.first->second = expression_requires(init, preinit, dep, p2var);
if (ins.first->second)
{
+ // VAR depends on P2VAR.
+ init_deps[*p2].insert(&(*p1));
+ p1->add_dependency();
+
// Check for cycles.
key = std::make_pair(p2var, var);
ins = cache.insert(std::make_pair(key, false));
@@ -1100,36 +1138,66 @@ sort_var_inits(Gogo* gogo, Var_inits* var_inits)
p2var->message_name().c_str());
p2 = var_inits->end();
}
- else
- {
- // We can't emit P1 until P2 is emitted. Move P1.
- Var_inits::iterator p3 = p2;
- ++p3;
- var_inits->splice(p3, *var_inits, p1);
- }
- break;
}
}
+ }
- if (p2 == var_inits->end())
+ // If there are no dependencies then the declaration order is sorted.
+ if (!init_deps.empty())
+ {
+ // Otherwise, sort variable initializations by emitting all variables with
+ // no dependencies in declaration order. VAR_INITS is already in
+ // declaration order.
+ Var_inits ready;
+ while (!var_inits->empty())
{
- // VAR does not depends upon any other initialization expressions.
-
- // Check for a loop of VAR on itself. We only do this if
- // INIT is not NULL and there is no dependency; when INIT is
- // NULL, it means that PREINIT sets VAR, which we will
- // interpret as a loop.
- if (init != NULL && dep == NULL
- && expression_requires(init, preinit, NULL, var))
- error_at(var->location(),
- "initialization expression for %qs depends upon itself",
- var->message_name().c_str());
- ready.splice(ready.end(), *var_inits, p1);
+ Var_inits::iterator v1;;
+ for (v1 = var_inits->begin(); v1 != var_inits->end(); ++v1)
+ {
+ if (v1->dep_count() == 0)
+ break;
+ }
+ go_assert(v1 != var_inits->end());
+
+ // V1 either has no dependencies or its dependencies have already
+ // been emitted, add it to READY next. When V1 is emitted, remove
+ // a dependency from each V that depends on V1.
+ ready.splice(ready.end(), *var_inits, v1);
+
+ Init_deps::iterator p1 = init_deps.find(*v1);
+ if (p1 != init_deps.end())
+ {
+ std::set<Var_init*> resolved = p1->second;
+ for (std::set<Var_init*>::iterator pv = resolved.begin();
+ pv != resolved.end();
+ ++pv)
+ (*pv)->remove_dependency();
+ init_deps.erase(p1);
+ }
}
+ var_inits->swap(ready);
+ go_assert(init_deps.empty());
}
- // Now READY is the list in the desired initialization order.
- var_inits->swap(ready);
+ // VAR_INITS is in the correct order. For each VAR in VAR_INITS,
+ // check for a loop of VAR on itself. We only do this if
+ // INIT is not NULL and there is no dependency; when INIT is
+ // NULL, it means that PREINIT sets VAR, which we will
+ // interpret as a loop.
+ for (Var_inits::const_iterator p = var_inits->begin();
+ p != var_inits->end();
+ ++p)
+ {
+ Named_object* var = p->var();
+ Expression* init = var->var_value()->init();
+ Block* preinit = var->var_value()->preinit();
+ Named_object* dep = gogo->var_depends_on(var->var_value());
+ if (init != NULL && dep == NULL
+ && expression_requires(init, preinit, NULL, var))
+ error_at(var->location(),
+ "initialization expression for %qs depends upon itself",
+ var->message_name().c_str());
+ }
}
// Write out the global definitions.
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index 8bf43d937be..0ba20245d67 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -395,6 +395,21 @@ expand_arith_overflow_result_store (tree lhs, rtx target,
write_complex_part (target, lres, false);
}
+/* Helper for expand_*_overflow. Store RES into TARGET. */
+
+static void
+expand_ubsan_result_store (rtx target, rtx res)
+{
+ if (GET_CODE (target) == SUBREG && SUBREG_PROMOTED_VAR_P (target))
+ /* If this is a scalar in a register that is stored in a wider mode
+ than the declared mode, compute the result into its declared mode
+ and then convert to the wider mode. Our value is the computed
+ expression. */
+ convert_move (SUBREG_REG (target), res, SUBREG_PROMOTED_SIGN (target));
+ else
+ emit_move_insn (target, res);
+}
+
/* Add sub/add overflow checking to the statement STMT.
CODE says whether the operation is +, or -. */
@@ -809,7 +824,7 @@ expand_addsub_overflow (location_t loc, tree_code code, tree lhs,
if (lhs)
{
if (is_ubsan)
- emit_move_insn (target, res);
+ expand_ubsan_result_store (target, res);
else
{
if (do_xor)
@@ -904,7 +919,7 @@ expand_neg_overflow (location_t loc, tree lhs, tree arg1, bool is_ubsan)
if (lhs)
{
if (is_ubsan)
- emit_move_insn (target, res);
+ expand_ubsan_result_store (target, res);
else
expand_arith_overflow_result_store (lhs, target, mode, res);
}
@@ -1590,7 +1605,7 @@ expand_mul_overflow (location_t loc, tree lhs, tree arg0, tree arg1,
if (lhs)
{
if (is_ubsan)
- emit_move_insn (target, res);
+ expand_ubsan_result_store (target, res);
else
expand_arith_overflow_result_store (lhs, target, mode, res);
}
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index e598241c01d..f97912ba72d 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -566,7 +566,7 @@ ipcp_cloning_candidate_p (struct cgraph_node *node)
gcc_checking_assert (node->has_gimple_body_p ());
- if (!flag_ipa_cp_clone)
+ if (!opt_for_fn (node->decl, flag_ipa_cp_clone))
{
if (dump_file)
fprintf (dump_file, "Not considering %s for cloning; "
@@ -902,10 +902,7 @@ ipa_value_from_jfunc (struct ipa_node_params *info, struct ipa_jump_func *jfunc)
ipcp_lattice<tree> *lat;
if (!info->lattices)
- {
- gcc_checking_assert (!flag_ipa_cp);
- return NULL_TREE;
- }
+ return NULL_TREE;
lat = ipa_get_scalar_lat (info, idx);
if (!lat->is_single_const ())
return NULL_TREE;
@@ -967,10 +964,7 @@ ipa_context_from_jfunc (ipa_node_params *info, cgraph_edge *cs, int csidx,
else
{
if (!info->lattices)
- {
- gcc_checking_assert (!flag_ipa_cp);
- return ctx;
- }
+ return ctx;
ipcp_lattice<ipa_polymorphic_call_context> *lat;
lat = ipa_get_poly_ctx_lat (info, srcidx);
if (!lat->is_single_const ())
@@ -1786,7 +1780,7 @@ ipa_get_indirect_edge_target_1 (struct cgraph_edge *ie,
return NULL_TREE;
}
- if (!flag_devirtualize)
+ if (!opt_for_fn (ie->caller->decl, flag_devirtualize))
return NULL_TREE;
gcc_assert (!ie->indirect_info->agg_contents);
@@ -1884,8 +1878,8 @@ ipa_get_indirect_edge_target_1 (struct cgraph_edge *ie,
struct cgraph_node *node;
if (*speculative)
return target;
- if (!flag_devirtualize_speculatively || ie->speculative
- || !ie->maybe_hot_p ())
+ if (!opt_for_fn (ie->caller->decl, flag_devirtualize_speculatively)
+ || ie->speculative || !ie->maybe_hot_p ())
return NULL;
node = try_speculative_devirtualization (ie->indirect_info->otr_type,
ie->indirect_info->otr_token,
@@ -2003,7 +1997,7 @@ good_cloning_opportunity_p (struct cgraph_node *node, int time_benefit,
int freq_sum, gcov_type count_sum, int size_cost)
{
if (time_benefit == 0
- || !flag_ipa_cp_clone
+ || !opt_for_fn (node->decl, flag_ipa_cp_clone)
|| !optimize_function_for_speed_p (DECL_STRUCT_FUNCTION (node->decl)))
return false;
@@ -4315,7 +4309,7 @@ public:
{
/* FIXME: We should remove the optimize check after we ensure we never run
IPA passes when not optimizing. */
- return flag_ipa_cp && optimize;
+ return (flag_ipa_cp && optimize) || in_lto_p;
}
virtual unsigned int execute (function *) { return ipcp_driver (); }
diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c
index 5e1f5713122..99475f6b640 100644
--- a/gcc/ipa-devirt.c
+++ b/gcc/ipa-devirt.c
@@ -2818,6 +2818,8 @@ ipa_devirt (void)
FOR_EACH_DEFINED_FUNCTION (n)
{
bool update = false;
+ if (!opt_for_fn (n->decl, flag_devirtualize))
+ continue;
if (dump_file && n->indirect_calls)
fprintf (dump_file, "\n\nProcesing function %s/%i\n",
n->name (), n->order);
@@ -2846,7 +2848,7 @@ ipa_devirt (void)
npolymorphic++;
- if (!flag_devirtualize_speculatively)
+ if (!opt_for_fn (n->decl, flag_devirtualize_speculatively))
continue;
if (!e->maybe_hot_p ())
@@ -3116,6 +3118,10 @@ public:
/* opt_pass methods: */
virtual bool gate (function *)
{
+ /* In LTO, always run the IPA passes and decide on function basis if the
+ pass is enabled. */
+ if (in_lto_p)
+ return true;
return (flag_devirtualize
&& (flag_devirtualize_speculatively
|| (warn_suggest_final_methods
diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c
index 548fd85a18a..2f2993ce299 100644
--- a/gcc/ipa-inline-analysis.c
+++ b/gcc/ipa-inline-analysis.c
@@ -2474,7 +2474,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
info->conds = NULL;
info->entry = NULL;
- if (optimize && !early)
+ if (opt_for_fn (node->decl, optimize) && !early)
{
calculate_dominance_info (CDI_DOMINATORS);
loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
@@ -2817,7 +2817,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
inline_summary (node)->self_time = time;
inline_summary (node)->self_size = size;
nonconstant_names.release ();
- if (optimize && !early)
+ if (opt_for_fn (node->decl, optimize) && !early)
{
loop_optimizer_finalize ();
free_dominance_info (CDI_DOMINATORS);
@@ -2874,8 +2874,9 @@ compute_inline_parameters (struct cgraph_node *node, bool early)
info->stack_frame_offset = 0;
/* Can this function be inlined at all? */
- if (!optimize && !lookup_attribute ("always_inline",
- DECL_ATTRIBUTES (node->decl)))
+ if (!opt_for_fn (node->decl, optimize)
+ && !lookup_attribute ("always_inline",
+ DECL_ATTRIBUTES (node->decl)))
info->inlinable = false;
else
info->inlinable = tree_inlinable_function_p (node->decl);
@@ -2992,7 +2993,7 @@ estimate_edge_devirt_benefit (struct cgraph_edge *ie,
if (!known_vals.exists () && !known_contexts.exists ())
return false;
- if (!flag_indirect_inlining)
+ if (!opt_for_fn (ie->caller->decl, flag_indirect_inlining))
return false;
target = ipa_get_indirect_edge_target (ie, known_vals, known_contexts,
@@ -3988,7 +3989,7 @@ inline_analyze_function (struct cgraph_node *node)
if (dump_file)
fprintf (dump_file, "\nAnalyzing function: %s/%u\n",
node->name (), node->order);
- if (optimize && !node->thunk.thunk_p)
+ if (opt_for_fn (node->decl, optimize) && !node->thunk.thunk_p)
inline_indirect_intraprocedural_analysis (node);
compute_inline_parameters (node, false);
if (!optimize)
diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c
index dbc56c599b0..9b806c1bf66 100644
--- a/gcc/ipa-inline-transform.c
+++ b/gcc/ipa-inline-transform.c
@@ -467,6 +467,7 @@ inline_transform (struct cgraph_node *node)
{
unsigned int todo = 0;
struct cgraph_edge *e, *next;
+ bool has_inline = false;
/* FIXME: Currently the pass manager is adding inline transform more than
once to some clones. This needs revisiting after WPA cleanups. */
@@ -480,13 +481,15 @@ inline_transform (struct cgraph_node *node)
for (e = node->callees; e; e = next)
{
+ if (!e->inline_failed)
+ has_inline = true;
next = e->next_callee;
e->redirect_call_stmt_to_callee ();
}
node->remove_all_references ();
timevar_push (TV_INTEGRATION);
- if (node->callees && optimize)
+ if (node->callees && (optimize || has_inline))
todo = optimize_inline_calls (current_function_decl);
timevar_pop (TV_INTEGRATION);
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index ca50ad5268c..72c0715dc56 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -378,18 +378,10 @@ can_inline_edge_p (struct cgraph_edge *e, bool report,
optimization attribute. */
else if (caller_tree != callee_tree)
{
- struct cl_optimization *caller_opt
- = TREE_OPTIMIZATION ((caller_tree)
- ? caller_tree
- : optimization_default_node);
-
- struct cl_optimization *callee_opt
- = TREE_OPTIMIZATION ((callee_tree)
- ? callee_tree
- : optimization_default_node);
-
- if (((caller_opt->x_optimize > callee_opt->x_optimize)
- || (caller_opt->x_optimize_size != callee_opt->x_optimize_size))
+ if (((opt_for_fn (e->caller->decl, optimize)
+ > opt_for_fn (e->callee->decl, optimize))
+ || (opt_for_fn (e->caller->decl, optimize_size)
+ != opt_for_fn (e->callee->decl, optimize_size)))
/* gcc.dg/pr43564.c. Look at forced inline even in -O0. */
&& !DECL_DISREGARD_INLINE_LIMITS (e->callee->decl))
{
@@ -469,7 +461,7 @@ want_early_inline_function_p (struct cgraph_edge *e)
else if (flag_auto_profile && afdo_callsite_hot_enough_for_early_inline (e))
;
else if (!DECL_DECLARED_INLINE_P (callee->decl)
- && !flag_inline_small_functions)
+ && !opt_for_fn (e->caller->decl, flag_inline_small_functions))
{
e->inline_failed = CIF_FUNCTION_NOT_INLINE_CANDIDATE;
report_inline_failed_reason (e);
@@ -587,7 +579,7 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
if (DECL_DISREGARD_INLINE_LIMITS (callee->decl))
;
else if (!DECL_DECLARED_INLINE_P (callee->decl)
- && !flag_inline_small_functions)
+ && !opt_for_fn (e->caller->decl, flag_inline_small_functions))
{
e->inline_failed = CIF_FUNCTION_NOT_INLINE_CANDIDATE;
want_inline = false;
@@ -639,7 +631,7 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
want_inline = false;
}
else if (!DECL_DECLARED_INLINE_P (callee->decl)
- && !flag_inline_functions)
+ && !opt_for_fn (e->caller->decl, flag_inline_functions))
{
/* growth_likely_positive is expensive, always test it last. */
if (growth >= MAX_INLINE_INSNS_SINGLE
@@ -816,6 +808,8 @@ check_callers (struct cgraph_node *node, void *has_hot_call)
struct cgraph_edge *e;
for (e = node->callers; e; e = e->next_caller)
{
+ if (!opt_for_fn (e->caller->decl, flag_inline_functions_called_once))
+ return true;
if (!can_inline_edge_p (e, true))
return true;
if (!(*(bool *)has_hot_call) && e->maybe_hot_p ())
@@ -1010,6 +1004,8 @@ edge_badness (struct cgraph_edge *edge, bool dump)
compensated by the inline hints.
*/
+ /* TODO: We ought suport mixing units where some functions are profiled
+ and some not. */
else if (flag_guess_branch_prob)
{
badness = (relative_time_benefit (callee_info, edge, edge_time)
@@ -1575,8 +1571,7 @@ inline_small_functions (void)
int initial_size = 0;
struct cgraph_node **order = XCNEWVEC (cgraph_node *, symtab->cgraph_count);
struct cgraph_edge_hook_list *edge_removal_hook_holder;
- if (flag_indirect_inlining)
- new_indirect_edges.create (8);
+ new_indirect_edges.create (8);
edge_removal_hook_holder
= symtab->add_edge_removal_hook (&heap_edge_removal_hook, &edge_heap);
@@ -1773,7 +1768,8 @@ inline_small_functions (void)
if (where->global.inlined_to)
where = where->global.inlined_to;
if (!recursive_inlining (edge,
- flag_indirect_inlining
+ opt_for_fn (edge->caller->decl,
+ flag_indirect_inlining)
? &new_indirect_edges : NULL))
{
edge->inline_failed = CIF_RECURSIVE_INLINING;
@@ -1783,7 +1779,7 @@ inline_small_functions (void)
reset_edge_caches (where);
/* Recursive inliner inlines all recursive calls of the function
at once. Consequently we need to update all callee keys. */
- if (flag_indirect_inlining)
+ if (opt_for_fn (edge->caller->decl, flag_indirect_inlining))
add_new_edges_to_heap (&edge_heap, new_indirect_edges);
update_callee_keys (&edge_heap, where, updated_nodes);
bitmap_clear (updated_nodes);
@@ -1821,8 +1817,7 @@ inline_small_functions (void)
gcc_checking_assert (!callee->global.inlined_to);
inline_call (edge, true, &new_indirect_edges, &overall_size, true);
- if (flag_indirect_inlining)
- add_new_edges_to_heap (&edge_heap, new_indirect_edges);
+ add_new_edges_to_heap (&edge_heap, new_indirect_edges);
reset_edge_caches (edge->callee);
reset_node_growth_cache (callee);
@@ -2246,8 +2241,7 @@ ipa_inline (void)
reset_edge_caches (where);
inline_update_overall_summary (where);
}
- if (flag_inline_functions_called_once
- && want_inline_function_to_all_callers_p (node, cold))
+ if (want_inline_function_to_all_callers_p (node, cold))
{
int num_calls = 0;
node->call_for_symbol_thunks_and_aliases (sum_callers, &num_calls,
@@ -2345,8 +2339,8 @@ early_inline_small_functions (struct cgraph_node *node)
/* Do not consider functions not declared inline. */
if (!DECL_DECLARED_INLINE_P (callee->decl)
- && !flag_inline_small_functions
- && !flag_inline_functions)
+ && !opt_for_fn (node->decl, flag_inline_small_functions)
+ && !opt_for_fn (node->decl, flag_inline_functions))
continue;
if (dump_file)
diff --git a/gcc/ipa-profile.c b/gcc/ipa-profile.c
index 99d13098534..340d033b6a5 100644
--- a/gcc/ipa-profile.c
+++ b/gcc/ipa-profile.c
@@ -418,7 +418,8 @@ ipa_propagate_frequency (struct cgraph_node *node)
nor about virtuals. */
if (!node->local.local
|| node->alias
- || (flag_devirtualize && DECL_VIRTUAL_P (node->decl)))
+ || (opt_for_fn (node->decl, flag_devirtualize)
+ && DECL_VIRTUAL_P (node->decl)))
return false;
gcc_assert (node->analyzed);
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -754,7 +755,7 @@ public:
{}
/* opt_pass methods: */
- virtual bool gate (function *) { return flag_ipa_profile; }
+ virtual bool gate (function *) { return flag_ipa_profile || in_lto_p; }
virtual unsigned int execute (function *) { return ipa_profile (); }
}; // class pass_ipa_profile
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 6a70e161828..2e0016bfbe6 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -168,12 +168,10 @@ static bool
ipa_func_spec_opts_forbid_analysis_p (struct cgraph_node *node)
{
tree fs_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (node->decl);
- struct cl_optimization *os;
if (!fs_opts)
return false;
- os = TREE_OPTIMIZATION (fs_opts);
- return !os->x_optimize || !os->x_flag_ipa_cp;
+ return !opt_for_fn (node->decl, optimize) || !opt_for_fn (node->decl, flag_ipa_cp);
}
/* Return index of the formal whose tree is PTREE in function which corresponds
@@ -2899,13 +2897,14 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
tree target = NULL;
bool speculative = false;
- if (!flag_devirtualize)
+ if (!opt_for_fn (ie->caller->decl, flag_devirtualize))
return NULL;
gcc_assert (!ie->indirect_info->by_ref);
/* Try to do lookup via known virtual table pointer value. */
- if (!ie->indirect_info->vptr_changed || flag_devirtualize_speculatively)
+ if (!ie->indirect_info->vptr_changed
+ || opt_for_fn (ie->caller->decl, flag_devirtualize_speculatively))
{
tree vtable;
unsigned HOST_WIDE_INT offset;
@@ -2956,7 +2955,7 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
else
target = ipa_impossible_devirt_target (ie, NULL_TREE);
}
- else if (!target && flag_devirtualize_speculatively
+ else if (!target && opt_for_fn (ie->caller->decl, flag_devirtualize_speculatively)
&& !ie->speculative && ie->maybe_hot_p ())
{
cgraph_node *n;
@@ -3028,7 +3027,7 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
param_index = ici->param_index;
jfunc = ipa_get_ith_jump_func (top, param_index);
- if (!flag_indirect_inlining)
+ if (!opt_for_fn (node->decl, flag_indirect_inlining))
new_direct_edge = NULL;
else if (ici->polymorphic)
{
@@ -3582,7 +3581,7 @@ ipa_unregister_cgraph_hooks (void)
void
ipa_free_all_structures_after_ipa_cp (void)
{
- if (!optimize)
+ if (!optimize && !in_lto_p)
{
ipa_free_all_edge_args ();
ipa_free_all_node_params ();
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
index d03b27fbd1c..9c016c1d586 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -914,7 +914,8 @@ add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
static declarations. We do not need to scan them more than once
since all we would be interested in are the addressof
operations. */
- if (node->get_availability () > AVAIL_INTERPOSABLE)
+ if (node->get_availability () > AVAIL_INTERPOSABLE
+ && opt_for_fn (node->decl, flag_ipa_pure_const))
set_function_state (node, analyze_function (node, true));
}
@@ -984,7 +985,8 @@ pure_const_generate_summary (void)
when function got cloned and the clone is AVAILABLE. */
FOR_EACH_DEFINED_FUNCTION (node)
- if (node->get_availability () >= AVAIL_INTERPOSABLE)
+ if (node->get_availability () >= AVAIL_INTERPOSABLE
+ && opt_for_fn (node->decl, flag_ipa_pure_const))
set_function_state (node, analyze_function (node, true));
}
@@ -1595,9 +1597,7 @@ execute (function *)
static bool
gate_pure_const (void)
{
- return (flag_ipa_pure_const
- /* Don't bother doing anything if the program has errors. */
- && !seen_error ());
+ return flag_ipa_pure_const || in_lto_p;
}
pass_ipa_pure_const::pass_ipa_pure_const(gcc::context *ctxt)
diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
index 309cb6d7280..134b33ff64f 100644
--- a/gcc/ipa-split.c
+++ b/gcc/ipa-split.c
@@ -1587,7 +1587,7 @@ split_function (struct split_point *split_point)
tree tem = create_tmp_reg (restype, NULL);
tem = make_ssa_name (tem, call);
cpy = gimple_build_assign_with_ops (NOP_EXPR, retval,
- tem, NULL_TREE);
+ tem);
gsi_insert_after (&gsi, cpy, GSI_NEW_STMT);
retval = tem;
}
diff --git a/gcc/ipa.c b/gcc/ipa.c
index a6086d808b0..54b30aab83c 100644
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -304,8 +304,7 @@ symbol_table::remove_unreachable_nodes (bool before_inlining_p, FILE *file)
hash_set<void *> reachable_call_targets;
timevar_push (TV_IPA_UNREACHABLE);
- if (optimize && flag_devirtualize)
- build_type_inheritance_graph ();
+ build_type_inheritance_graph ();
if (file)
fprintf (file, "\nReclaiming functions:");
#ifdef ENABLE_CHECKING
@@ -391,7 +390,8 @@ symbol_table::remove_unreachable_nodes (bool before_inlining_p, FILE *file)
{
struct cgraph_edge *e;
/* Keep alive possible targets for devirtualization. */
- if (optimize && flag_devirtualize)
+ if (opt_for_fn (cnode->decl, optimize)
+ && opt_for_fn (cnode->decl, flag_devirtualize))
{
struct cgraph_edge *next;
for (e = cnode->indirect_calls; e; e = next)
diff --git a/gcc/ira.c b/gcc/ira.c
index 9c9e71d1be1..e610d358177 100644
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -5263,7 +5263,18 @@ ira (FILE *f)
ira_allocno_iterator ai;
FOR_EACH_ALLOCNO (a, ai)
- ALLOCNO_REGNO (a) = REGNO (ALLOCNO_EMIT_DATA (a)->reg);
+ {
+ int old_regno = ALLOCNO_REGNO (a);
+ int new_regno = REGNO (ALLOCNO_EMIT_DATA (a)->reg);
+
+ ALLOCNO_REGNO (a) = new_regno;
+
+ if (old_regno != new_regno)
+ setup_reg_classes (new_regno, reg_preferred_class (old_regno),
+ reg_alternate_class (old_regno),
+ reg_allocno_class (old_regno));
+ }
+
}
else
{
diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c
index 951a2ddc787..6b417821295 100644
--- a/gcc/lto-wrapper.c
+++ b/gcc/lto-wrapper.c
@@ -1314,13 +1314,13 @@ main (int argc, char *argv[])
xmalloc_set_program_name (progname);
- if (atexit (lto_wrapper_cleanup) != 0)
- fatal_error ("atexit failed");
-
gcc_init_libintl ();
diagnostic_initialize (global_dc, 0);
+ if (atexit (lto_wrapper_cleanup) != 0)
+ fatal_error ("atexit failed");
+
if (signal (SIGINT, SIG_IGN) != SIG_IGN)
signal (SIGINT, fatal_signal);
#ifdef SIGHUP
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index bc4233ac237..15aa140770c 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -1517,7 +1517,8 @@ fixup_child_record_type (omp_context *ctx)
layout_type (type);
}
- TREE_TYPE (ctx->receiver_decl) = build_pointer_type (type);
+ TREE_TYPE (ctx->receiver_decl)
+ = build_qualified_type (build_reference_type (type), TYPE_QUAL_RESTRICT);
}
/* Instantiate decls as necessary in CTX to satisfy the data sharing
@@ -1961,7 +1962,9 @@ create_omp_child_function (omp_context *ctx, bool task_copy)
if (is_targetreg_ctx (octx))
{
cgraph_node::get_create (decl)->offloadable = 1;
+#ifdef ENABLE_OFFLOADING
g->have_offload = true;
+#endif
break;
}
}
@@ -3843,8 +3846,7 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (ctx->stmt);
gimple_omp_for_set_clauses (ctx->stmt, c);
g = gimple_build_assign_with_ops (INTEGER_CST, lane,
- build_int_cst (unsigned_type_node, 0),
- NULL_TREE);
+ build_int_cst (unsigned_type_node, 0));
gimple_seq_add_stmt (ilist, g);
for (int i = 0; i < 2; i++)
if (llist[i])
@@ -3855,7 +3857,7 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
gimple_seq *seq = i == 0 ? ilist : dlist;
gimple_seq_add_stmt (seq, g);
tree t = build_int_cst (unsigned_type_node, 0);
- g = gimple_build_assign_with_ops (INTEGER_CST, idx, t, NULL_TREE);
+ g = gimple_build_assign_with_ops (INTEGER_CST, idx, t);
gimple_seq_add_stmt (seq, g);
tree body = create_artificial_label (UNKNOWN_LOCATION);
tree header = create_artificial_label (UNKNOWN_LOCATION);
@@ -5854,8 +5856,7 @@ expand_omp_for_generic (struct omp_region *region,
if (useless_type_conversion_p (TREE_TYPE (fd->loop.v), TREE_TYPE (iend)))
assign_stmt = gimple_build_assign (fd->loop.v, iend);
else
- assign_stmt = gimple_build_assign_with_ops (NOP_EXPR, fd->loop.v, iend,
- NULL_TREE);
+ assign_stmt = gimple_build_assign_with_ops (NOP_EXPR, fd->loop.v, iend);
gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
}
if (fd->collapse > 1)
@@ -6275,8 +6276,7 @@ expand_omp_for_static_nochunk (struct omp_region *region,
if (useless_type_conversion_p (TREE_TYPE (fd->loop.v), TREE_TYPE (e)))
assign_stmt = gimple_build_assign (fd->loop.v, e);
else
- assign_stmt = gimple_build_assign_with_ops (NOP_EXPR, fd->loop.v, e,
- NULL_TREE);
+ assign_stmt = gimple_build_assign_with_ops (NOP_EXPR, fd->loop.v, e);
gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
}
if (fd->collapse > 1)
@@ -6666,8 +6666,7 @@ expand_omp_for_static_chunk (struct omp_region *region,
if (useless_type_conversion_p (TREE_TYPE (fd->loop.v), TREE_TYPE (e)))
assign_stmt = gimple_build_assign (fd->loop.v, e);
else
- assign_stmt = gimple_build_assign_with_ops (NOP_EXPR, fd->loop.v, e,
- NULL_TREE);
+ assign_stmt = gimple_build_assign_with_ops (NOP_EXPR, fd->loop.v, e);
gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
}
if (fd->collapse > 1)
@@ -8303,7 +8302,6 @@ expand_omp_target (struct omp_region *region)
if (kind == GF_OMP_TARGET_KIND_REGION)
{
unsigned srcidx, dstidx, num;
- struct cgraph_node *node;
/* If the target region needs data sent from the parent
function, then the very first statement (except possible
@@ -8430,18 +8428,22 @@ expand_omp_target (struct omp_region *region)
DECL_STRUCT_FUNCTION (child_fn)->curr_properties = cfun->curr_properties;
cgraph_node::add_new_function (child_fn, true);
+#ifdef ENABLE_OFFLOADING
/* Add the new function to the offload table. */
vec_safe_push (offload_funcs, child_fn);
+#endif
/* Fix the callgraph edges for child_cfun. Those for cfun will be
fixed in a following pass. */
push_cfun (child_cfun);
cgraph_edge::rebuild_edges ();
+#ifdef ENABLE_OFFLOADING
/* Prevent IPA from removing child_fn as unreachable, since there are no
refs from the parent function to child_fn in offload LTO mode. */
- node = cgraph_node::get (child_fn);
+ struct cgraph_node *node = cgraph_node::get (child_fn);
node->mark_force_output ();
+#endif
/* Some EH regions might become dead, see PR34608. If
pass_cleanup_cfg isn't the first pass to happen with the
@@ -12241,8 +12243,7 @@ simd_clone_adjust (struct cgraph_node *node)
{
t = make_ssa_name (orig_arg, NULL);
g = gimple_build_assign_with_ops (NOP_EXPR, t,
- gimple_call_lhs (g),
- NULL_TREE);
+ gimple_call_lhs (g));
gimple_seq_add_stmt_without_update (&seq, g);
}
gsi_insert_seq_on_edge_immediate
@@ -12546,7 +12547,7 @@ omp_finish_file (void)
varpool_node::finalize_decl (vars_decl);
varpool_node::finalize_decl (funcs_decl);
- }
+ }
else
{
for (unsigned i = 0; i < num_funcs; i++)
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 8094c7584ac..022e36fe7c0 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -3105,43 +3105,42 @@ simplify_binary_operation_1 (enum rtx_code code, machine_mode mode,
&& ! side_effects_p (op1))
return op0;
/* Given:
- scalar modes M1, M2
- scalar constants c1, c2
- size (M2) > size (M1)
- c1 == size (M2) - size (M1)
- optimize:
- (ashiftrt:M1 (subreg:M1 (lshiftrt:M2 (reg:M2)
- (const_int <c1>))
- <low_part>)
- (const_int <c2>))
- to:
- (subreg:M1 (ashiftrt:M2 (reg:M2)
- (const_int <c1 + c2>))
- <low_part>). */
- if (!VECTOR_MODE_P (mode)
- && SUBREG_P (op0)
- && CONST_INT_P (op1)
- && (GET_CODE (SUBREG_REG (op0)) == LSHIFTRT)
- && !VECTOR_MODE_P (GET_MODE (SUBREG_REG (op0)))
- && CONST_INT_P (XEXP (SUBREG_REG (op0), 1))
- && (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0)))
- > GET_MODE_BITSIZE (mode))
- && (INTVAL (XEXP (SUBREG_REG (op0), 1))
- == (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0)))
- - GET_MODE_BITSIZE (mode)))
- && subreg_lowpart_p (op0))
- {
- rtx tmp = GEN_INT (INTVAL (XEXP (SUBREG_REG (op0), 1))
- + INTVAL (op1));
- machine_mode inner_mode = GET_MODE (SUBREG_REG (op0));
- tmp = simplify_gen_binary (ASHIFTRT,
- GET_MODE (SUBREG_REG (op0)),
- XEXP (SUBREG_REG (op0), 0),
- tmp);
- return simplify_gen_subreg (mode, tmp, inner_mode,
- subreg_lowpart_offset (mode,
- inner_mode));
- }
+ scalar modes M1, M2
+ scalar constants c1, c2
+ size (M2) > size (M1)
+ c1 == size (M2) - size (M1)
+ optimize:
+ (ashiftrt:M1 (subreg:M1 (lshiftrt:M2 (reg:M2) (const_int <c1>))
+ <low_part>)
+ (const_int <c2>))
+ to:
+ (subreg:M1 (ashiftrt:M2 (reg:M2) (const_int <c1 + c2>))
+ <low_part>). */
+ if (code == ASHIFTRT
+ && !VECTOR_MODE_P (mode)
+ && SUBREG_P (op0)
+ && CONST_INT_P (op1)
+ && GET_CODE (SUBREG_REG (op0)) == LSHIFTRT
+ && !VECTOR_MODE_P (GET_MODE (SUBREG_REG (op0)))
+ && CONST_INT_P (XEXP (SUBREG_REG (op0), 1))
+ && (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0)))
+ > GET_MODE_BITSIZE (mode))
+ && (INTVAL (XEXP (SUBREG_REG (op0), 1))
+ == (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0)))
+ - GET_MODE_BITSIZE (mode)))
+ && subreg_lowpart_p (op0))
+ {
+ rtx tmp = GEN_INT (INTVAL (XEXP (SUBREG_REG (op0), 1))
+ + INTVAL (op1));
+ machine_mode inner_mode = GET_MODE (SUBREG_REG (op0));
+ tmp = simplify_gen_binary (ASHIFTRT,
+ GET_MODE (SUBREG_REG (op0)),
+ XEXP (SUBREG_REG (op0), 0),
+ tmp);
+ return simplify_gen_subreg (mode, tmp, inner_mode,
+ subreg_lowpart_offset (mode,
+ inner_mode));
+ }
canonicalize_shift:
if (SHIFT_COUNT_TRUNCATED && CONST_INT_P (op1))
{
diff --git a/gcc/target.def b/gcc/target.def
index 3ccb028a61e..dc48ae6912e 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -3314,7 +3314,7 @@ the body of the memory operation.\n\
Returning true for higher values of @code{size} may also cause an increase\n\
in code size, for example where the number of insns emitted to perform a\n\
move would be greater than that of a library call.",
- bool, (unsigned int size, unsigned int alignment,
+ bool, (unsigned HOST_WIDE_INT size, unsigned int alignment,
enum by_pieces_operation op, bool speed_p),
default_use_by_pieces_infrastructure_p)
@@ -4516,8 +4516,8 @@ false for naked functions. The default implementation always returns true.",
bool, (void),
hook_bool_void_true)
-/* Return an rtx for the static chain for FNDECL. If INCOMING_P is true,
- then it should be for the callee; otherwise for the caller. */
+/* Return an rtx for the static chain for FNDECL_OR_TYPE. If INCOMING_P
+ is true, then it should be for the callee; otherwise for the caller. */
DEFHOOK
(static_chain,
"This hook replaces the use of @code{STATIC_CHAIN_REGNUM} et al for\n\
@@ -4539,7 +4539,7 @@ will be at an offset from the frame pointer.\n\
The variables @code{stack_pointer_rtx}, @code{frame_pointer_rtx}, and\n\
@code{arg_pointer_rtx} will have been initialized and should be used\n\
to refer to those items.",
- rtx, (const_tree fndecl, bool incoming_p),
+ rtx, (const_tree fndecl_or_type, bool incoming_p),
default_static_chain)
/* Fill in the trampoline at MEM with a call to FNDECL and a
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index 7b1b5dcfee4..42fd82e692b 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -841,11 +841,8 @@ default_internal_arg_pointer (void)
}
rtx
-default_static_chain (const_tree fndecl, bool incoming_p)
+default_static_chain (const_tree ARG_UNUSED (fndecl_or_type), bool incoming_p)
{
- if (!DECL_STATIC_CHAIN (fndecl))
- return NULL;
-
if (incoming_p)
{
#ifdef STATIC_CHAIN_INCOMING_REGNUM
@@ -1430,7 +1427,7 @@ get_move_ratio (bool speed_p ATTRIBUTE_UNUSED)
a call to memcpy emitted. */
bool
-default_use_by_pieces_infrastructure_p (unsigned int size,
+default_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
unsigned int alignment,
enum by_pieces_operation op,
bool speed_p)
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index faadd23c887..9734220dea2 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -181,7 +181,7 @@ extern int default_memory_move_cost (machine_mode, reg_class_t, bool);
extern int default_register_move_cost (machine_mode, reg_class_t,
reg_class_t);
-extern bool default_use_by_pieces_infrastructure_p (unsigned int,
+extern bool default_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT,
unsigned int,
enum by_pieces_operation,
bool);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 840faa9914a..f5fb9db873f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,83 @@
+2014-11-19 Renlin Li <Renlin.Li@arm.com>
+
+ PR middle-end/63762
+ * gcc.dg/pr63762.c: New test.
+
+2014-11-19 Marek Polacek <polacek@redhat.com>
+
+ PR sanitizer/63690
+ * gcc.dg/ubsan/pr63690.c: New test.
+
+2014-11-19 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ PR sanitizer/62132
+ * c-c++-common/asan/misalign-1.c: Pass -fno-omit-frame-pointer on
+ darwin, adjust dg-output.
+ * c-c++-common/asan/misalign-2.c: Likewise.
+
+2014-11-19 Richard Henderson <rth@redhat.com>
+
+ * gcc.dg/cwsc0.c: New test.
+ * gcc.dg/cwsc1.c: New test.
+
+2014-11-19 Marek Polacek <polacek@redhat.com>
+
+ PR sanitizer/63879
+ * c-c++-common/ubsan/pr63879-1.c: New test.
+ * c-c++-common/ubsan/pr63879-2.c: New test.
+
+2014-11-19 Tom de Vries <tom@codesourcery.com>
+
+ PR tree-optimization/62167
+ * gcc.dg/pr51879-12.c: Add xfails.
+ * gcc.dg/pr62167-run.c: New test.
+ * gcc.dg/pr62167.c: New test.
+
+2014-11-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/63915
+ * c-c++-common/gomp/pr60823-4.c: New test.
+
+ PR sanitizer/63520
+ * c-c++-common/ubsan/pr63520.c: New test.
+
+2014-11-19 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57654
+ * g++.dg/cpp0x/constexpr-ref7.C: New.
+
+2014-11-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR sanitizer/63913
+ * g++.dg/ubsan/pr63913.C: New test.
+
+2014-11-19 Andreas Schwab <schwab@suse.de>
+
+ * gcc.dg/pure-2.c: Update line numbers.
+
+2014-11-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/63843
+ * gcc.c-torture/execute/pr63843.c: New test.
+
+2014-11-18 James Greenhalgh <james.greenhalgh@arm.com>
+
+ PR target/63937
+ * gcc.dg/memset-2.c: New.
+
+2014-11-18 Jakub Jelinek <jakub@redhat.com>
+
+ PR sanitizer/63813
+ * g++.dg/ubsan/pr63813.C: New test.
+
+ PR tree-optimization/61042
+ * gcc.c-torture/compile/pr61042.c: New test.
+
+2014-11-18 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * gcc.dg/atomic/c11-atomic-exec-5.c (dg-timeout-factor): New
+ setting.
+
2014-11-18 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/55942
diff --git a/gcc/testsuite/c-c++-common/asan/misalign-1.c b/gcc/testsuite/c-c++-common/asan/misalign-1.c
index 0c5b6e0c754..cec87a8ce6f 100644
--- a/gcc/testsuite/c-c++-common/asan/misalign-1.c
+++ b/gcc/testsuite/c-c++-common/asan/misalign-1.c
@@ -1,5 +1,6 @@
/* { dg-do run { target { ilp32 || lp64 } } } */
/* { dg-options "-O2" } */
+/* { dg-additional-options "-fno-omit-frame-pointer" { target *-*-darwin* } } */
/* { dg-shouldfail "asan" } */
struct S { int i; } __attribute__ ((packed));
@@ -38,5 +39,5 @@ main ()
/* { dg-output "ERROR: AddressSanitizer:\[^\n\r]*on address\[^\n\r]*" } */
/* { dg-output "0x\[0-9a-f\]+ at pc 0x\[0-9a-f\]+ bp 0x\[0-9a-f\]+ sp 0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*READ of size 4 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output " #0 0x\[0-9a-f\]+ (in _*foo(\[^\n\r]*misalign-1.c:10|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output " #1 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*misalign-1.c:34|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */
+/* { dg-output " #0 0x\[0-9a-f\]+ (in _*foo(\[^\n\r]*misalign-1.c:1\[01]|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output " #1 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*misalign-1.c:3\[45]|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */
diff --git a/gcc/testsuite/c-c++-common/asan/misalign-2.c b/gcc/testsuite/c-c++-common/asan/misalign-2.c
index 7fbe299cc54..f99127edb27 100644
--- a/gcc/testsuite/c-c++-common/asan/misalign-2.c
+++ b/gcc/testsuite/c-c++-common/asan/misalign-2.c
@@ -1,5 +1,6 @@
/* { dg-do run { target { ilp32 || lp64 } } } */
/* { dg-options "-O2" } */
+/* { dg-additional-options "-fno-omit-frame-pointer" { target *-*-darwin* } } */
/* { dg-shouldfail "asan" } */
struct S { int i; } __attribute__ ((packed));
@@ -38,5 +39,5 @@ main ()
/* { dg-output "ERROR: AddressSanitizer:\[^\n\r]*on address\[^\n\r]*" } */
/* { dg-output "0x\[0-9a-f\]+ at pc 0x\[0-9a-f\]+ bp 0x\[0-9a-f\]+ sp 0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*READ of size 4 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output " #0 0x\[0-9a-f\]+ (in _*baz(\[^\n\r]*misalign-2.c:22|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output " #1 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*misalign-2.c:34|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */
+/* { dg-output " #0 0x\[0-9a-f\]+ (in _*baz(\[^\n\r]*misalign-2.c:2\[23]|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output " #1 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*misalign-2.c:3\[45]|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */
diff --git a/gcc/testsuite/c-c++-common/gomp/pr60823-4.c b/gcc/testsuite/c-c++-common/gomp/pr60823-4.c
new file mode 100644
index 00000000000..a9bc0fa2591
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/pr60823-4.c
@@ -0,0 +1,7 @@
+/* PR tree-optimization/63915 */
+/* { dg-do run } */
+/* { dg-require-effective-target vect_simd_clones } */
+/* { dg-options "-O2 -fopenmp-simd" } */
+/* { dg-additional-options "-fpic" { target fpic } } */
+
+#include "pr60823-2.c"
diff --git a/gcc/testsuite/c-c++-common/ubsan/pr63520.c b/gcc/testsuite/c-c++-common/ubsan/pr63520.c
new file mode 100644
index 00000000000..66da668dbb8
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/ubsan/pr63520.c
@@ -0,0 +1,16 @@
+/* PR sanitizer/63520 */
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=undefined" } */
+
+int a;
+
+void
+foo (void)
+{
+ while (1)
+ {
+ if (a == 1)
+ break;
+ a -= 1;
+ }
+}
diff --git a/gcc/testsuite/c-c++-common/ubsan/pr63879-1.c b/gcc/testsuite/c-c++-common/ubsan/pr63879-1.c
new file mode 100644
index 00000000000..2035849a8ce
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/ubsan/pr63879-1.c
@@ -0,0 +1,23 @@
+/* PR sanitizer/63879 */
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=undefined" } */
+
+struct A
+{
+ int inode;
+} * a;
+int b, c;
+void
+fn1 ()
+{
+ int d = 0;
+ while (b)
+ {
+ if (a->inode)
+ d++;
+ a = 0;
+ }
+ c = d - 1;
+ for (; c >= 0; c--)
+ ;
+}
diff --git a/gcc/testsuite/c-c++-common/ubsan/pr63879-2.c b/gcc/testsuite/c-c++-common/ubsan/pr63879-2.c
new file mode 100644
index 00000000000..34eb8e79d67
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/ubsan/pr63879-2.c
@@ -0,0 +1,13 @@
+/* PR sanitizer/63879 */
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=undefined" } */
+
+int a;
+void
+fn1 ()
+{
+ int b = 2;
+ for (; a;)
+ while (b >= 0)
+ b--;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-empty8.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-empty8.C
new file mode 100644
index 00000000000..8c1414af558
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-empty8.C
@@ -0,0 +1,7 @@
+// PR c++/63924
+// { dg-do compile { target c++11 } }
+
+struct A { };
+constexpr bool f(A a) { return true; }
+template <bool B> constexpr bool g() { return true; }
+constexpr bool g(A a) { return g<f(a)>(); }
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-ref7.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-ref7.C
new file mode 100644
index 00000000000..72c8d089d77
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-ref7.C
@@ -0,0 +1,11 @@
+// PR c++/57654
+// { dg-do compile { target c++11 } }
+
+int i;
+
+constexpr int & iref = i;
+constexpr int & irefref = iref;
+
+class A {
+ static constexpr int & irefref = iref;
+};
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-stmtexpr2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-stmtexpr2.C
new file mode 100644
index 00000000000..34ca9fa9974
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-stmtexpr2.C
@@ -0,0 +1,12 @@
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+#define SA(X) static_assert((X),#X)
+
+template <class T>
+constexpr T f (T t)
+{
+ return ({ t+1; });
+}
+
+SA(f(42) == 43);
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-incr1.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-incr1.C
index 2b099c821e0..ecd7c047c85 100644
--- a/gcc/testsuite/g++.dg/cpp1y/constexpr-incr1.C
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-incr1.C
@@ -1,4 +1,5 @@
// { dg-do compile { target c++14 } }
+#define SA(X) static_assert((X),#X)
constexpr int f (int i)
{
@@ -8,6 +9,15 @@ constexpr int f (int i)
return x;
}
+constexpr int* g (int* p)
+{
+ ++p;
+ return p;
+}
+
constexpr int i = f(42);
-#define SA(X) static_assert((X),#X)
SA(i==44);
+
+int array[4];
+constexpr int* p = g(array);
+SA(p == &array[1]);
diff --git a/gcc/testsuite/g++.dg/ubsan/pr63813.C b/gcc/testsuite/g++.dg/ubsan/pr63813.C
new file mode 100644
index 00000000000..6ca5b2d18c9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ubsan/pr63813.C
@@ -0,0 +1,12 @@
+// PR sanitizer/63813
+// { dg-do compile }
+// { dg-options "-fsanitize=undefined -O1" }
+
+struct A {};
+struct B { long foo () const; A &bar () const; };
+
+A &
+B::bar () const
+{
+ return *reinterpret_cast <A *> (foo ());
+}
diff --git a/gcc/testsuite/g++.dg/ubsan/pr63913.C b/gcc/testsuite/g++.dg/ubsan/pr63913.C
new file mode 100644
index 00000000000..34dceb4d844
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ubsan/pr63913.C
@@ -0,0 +1,12 @@
+// PR sanitizer/63913
+// { dg-do compile }
+// { dg-options "-fsanitize=bool -fnon-call-exceptions" }
+
+struct B { B (); ~B (); };
+
+double
+foo (bool *x)
+{
+ B b;
+ return *x;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr61042.c b/gcc/testsuite/gcc.c-torture/compile/pr61042.c
new file mode 100644
index 00000000000..43a4319096a
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr61042.c
@@ -0,0 +1,10 @@
+/* PR tree-optimization/61042 */
+
+int a, b, c[1], d, f;
+
+void
+foo ()
+{
+ for (; b; b++)
+ c[0] = c[f] && (d = a);
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr63843.c b/gcc/testsuite/gcc.c-torture/execute/pr63843.c
new file mode 100644
index 00000000000..9f6c7b06c39
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr63843.c
@@ -0,0 +1,31 @@
+/* PR rtl-optimization/63843 */
+
+static inline __attribute__ ((always_inline))
+unsigned short foo (unsigned short v)
+{
+ return (v << 8) | (v >> 8);
+}
+
+unsigned short __attribute__ ((noinline, noclone, hot))
+bar (unsigned char *x)
+{
+ unsigned int a;
+ unsigned short b;
+ __builtin_memcpy (&a, &x[0], sizeof (a));
+ a ^= 0x80808080U;
+ __builtin_memcpy (&x[0], &a, sizeof (a));
+ __builtin_memcpy (&b, &x[2], sizeof (b));
+ return foo (b);
+}
+
+int
+main ()
+{
+ unsigned char x[8] = { 0x01, 0x01, 0x01, 0x01 };
+ if (__CHAR_BIT__ == 8
+ && sizeof (short) == 2
+ && sizeof (int) == 4
+ && bar (x) != 0x8181U)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-5.c b/gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-5.c
index d8bddfd9961..c4c4842c524 100644
--- a/gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-5.c
+++ b/gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-5.c
@@ -9,6 +9,7 @@
/* { dg-additional-options "-D_XOPEN_SOURCE=600" { target *-*-solaris2.1[0-9]* } } */
/* { dg-require-effective-target fenv_exceptions } */
/* { dg-require-effective-target pthread } */
+/* { dg-timeout-factor 2 } */
#include <fenv.h>
#include <float.h>
diff --git a/gcc/testsuite/gcc.dg/cwsc0.c b/gcc/testsuite/gcc.dg/cwsc0.c
new file mode 100644
index 00000000000..3d92222bf9c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cwsc0.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+#include <stddef.h>
+
+void foo(void);
+void test(int (*f)(void), char *p)
+{
+ __builtin_call_with_static_chain(f(), p);
+ __builtin_call_with_static_chain(p, f()); /* { dg-error "must be a call" } */
+ __builtin_call_with_static_chain(f() + 1, p); /* { dg-error "must be a call" } */
+ __builtin_call_with_static_chain(f(), 0); /* { dg-error "must be a pointer" } */
+ __builtin_call_with_static_chain(f(), NULL);
+ __builtin_call_with_static_chain(foo, p); /* { dg-error "must be a call" } */
+ __builtin_call_with_static_chain(foo(), p);
+ __builtin_call_with_static_chain(foo(), foo);
+}
diff --git a/gcc/testsuite/gcc.dg/cwsc1.c b/gcc/testsuite/gcc.dg/cwsc1.c
new file mode 100644
index 00000000000..e793e26116a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cwsc1.c
@@ -0,0 +1,46 @@
+/* { dg-do run } */
+/* { dg-options "-O" } */
+
+#if defined(__x86_64__)
+# define CHAIN "%r10"
+#elif defined(__i386__)
+# define CHAIN "%ecx"
+#elif defined(__aarch64__)
+# define CHAIN "x18"
+#elif defined(__alpha__)
+# define CHAIN "$1"
+#elif defined(__arm__)
+# define CHAIN "ip"
+#elif defined(__powerpc__)
+# define CHAIN "11"
+#elif defined(__s390__)
+# define CHAIN "%r0"
+#elif defined(__sparc__)
+# ifdef __arch64__
+# define CHAIN "%g5"
+# else
+# define CHAIN "%g2"
+# endif
+#endif
+
+#ifdef CHAIN
+void *__attribute__((noinline, noclone)) foo(void)
+{
+ register void *chain __asm__(CHAIN);
+ return chain;
+}
+
+void * (*ptr)(void) = foo;
+extern void abort(void);
+
+int main()
+{
+ char c;
+ void *x = __builtin_call_with_static_chain(ptr(), &c);
+ if (x != &c)
+ abort();
+ return 0;
+}
+#else
+int main() { return 0; }
+#endif
diff --git a/gcc/testsuite/gcc.dg/memset-2.c b/gcc/testsuite/gcc.dg/memset-2.c
new file mode 100644
index 00000000000..fb4debc6d2c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/memset-2.c
@@ -0,0 +1,11 @@
+/* PR target/63937 */
+/* { dg-do compile { target lp64 } } */
+/* { dg-options "-O2" } */
+
+void
+foo (char *p)
+{
+ p = __builtin_assume_aligned (p, 64);
+ __builtin_memset (p, 0, 0x100000001ULL);
+}
+
diff --git a/gcc/testsuite/gcc.dg/pr51879-12.c b/gcc/testsuite/gcc.dg/pr51879-12.c
index 8126505f384..85e2687da17 100644
--- a/gcc/testsuite/gcc.dg/pr51879-12.c
+++ b/gcc/testsuite/gcc.dg/pr51879-12.c
@@ -24,6 +24,6 @@ foo (int y)
baz (a);
}
-/* { dg-final { scan-tree-dump-times "bar \\(" 1 "pre"} } */
-/* { dg-final { scan-tree-dump-times "bar2 \\(" 1 "pre"} } */
+/* { dg-final { scan-tree-dump-times "bar \\(" 1 "pre" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "bar2 \\(" 1 "pre" { xfail *-*-* } } } */
/* { dg-final { cleanup-tree-dump "pre" } } */
diff --git a/gcc/testsuite/gcc.dg/pr62167-run.c b/gcc/testsuite/gcc.dg/pr62167-run.c
new file mode 100644
index 00000000000..37214a3ecee
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr62167-run.c
@@ -0,0 +1,47 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -ftree-tail-merge" } */
+
+struct node
+{
+ struct node *next;
+ struct node *prev;
+};
+
+struct node node;
+
+struct head
+{
+ struct node *first;
+};
+
+struct head heads[5];
+
+int k = 2;
+
+struct head *head = &heads[2];
+
+int
+main ()
+{
+ struct node *p;
+
+ node.next = (void*)0;
+
+ node.prev = (void *)head;
+
+ head->first = &node;
+
+ struct node *n = head->first;
+
+ struct head *h = &heads[k];
+
+ heads[2].first = n->next;
+
+ if ((void*)n->prev == (void *)h)
+ p = h->first;
+ else
+ /* Dead tbaa-unsafe load from ((struct node *)&heads[2])->next. */
+ p = n->prev->next;
+
+ return !(p == (void*)0);
+}
diff --git a/gcc/testsuite/gcc.dg/pr62167.c b/gcc/testsuite/gcc.dg/pr62167.c
new file mode 100644
index 00000000000..f8c31a0792f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr62167.c
@@ -0,0 +1,50 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-tail-merge -fdump-tree-pre" } */
+
+struct node
+{
+ struct node *next;
+ struct node *prev;
+};
+
+struct node node;
+
+struct head
+{
+ struct node *first;
+};
+
+struct head heads[5];
+
+int k = 2;
+
+struct head *head = &heads[2];
+
+int
+main ()
+{
+ struct node *p;
+
+ node.next = (void*)0;
+
+ node.prev = (void *)head;
+
+ head->first = &node;
+
+ struct node *n = head->first;
+
+ struct head *h = &heads[k];
+
+ heads[2].first = n->next;
+
+ if ((void*)n->prev == (void *)h)
+ p = h->first;
+ else
+ /* Dead tbaa-unsafe load from ((struct node *)&heads[2])->next. */
+ p = n->prev->next;
+
+ return !(p == (void*)0);
+}
+
+/* { dg-final { scan-tree-dump-not "Removing basic block" "pre"} } */
+/* { dg-final { cleanup-tree-dump "pre" } } */
diff --git a/gcc/testsuite/gcc.dg/pr63762.c b/gcc/testsuite/gcc.dg/pr63762.c
new file mode 100644
index 00000000000..df110676eca
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr63762.c
@@ -0,0 +1,77 @@
+/* PR middle-end/63762 */
+/* { dg-do assemble } */
+/* { dg-options "-O2" } */
+
+#include <stdlib.h>
+
+void *astFree ();
+void *astMalloc ();
+void astNegate (void *);
+int astGetNegated (void *);
+void astGetRegionBounds (void *, double *, double *);
+int astResampleF (void *, ...);
+
+extern int astOK;
+
+int
+MaskF (int inside, int ndim, const int lbnd[], const int ubnd[],
+ float in[], float val)
+{
+
+ void *used_region;
+ float *c, *d, *out, *tmp_out;
+ double *lbndgd, *ubndgd;
+ int *lbndg, *ubndg, idim, ipix, nax, nin, nout, npix, npixg, result = 0;
+ if (!astOK) return result;
+ lbndg = astMalloc (sizeof (int)*(size_t) ndim);
+ ubndg = astMalloc (sizeof (int)*(size_t) ndim);
+ lbndgd = astMalloc (sizeof (double)*(size_t) ndim);
+ ubndgd = astMalloc (sizeof (double)*(size_t) ndim);
+ if (astOK)
+ {
+ astGetRegionBounds (used_region, lbndgd, ubndgd);
+ npix = 1;
+ npixg = 1;
+ for (idim = 0; idim < ndim; idim++)
+ {
+ lbndg[ idim ] = lbnd[ idim ];
+ ubndg[ idim ] = ubnd[ idim ];
+ npix *= (ubnd[ idim ] - lbnd[ idim ] + 1);
+ if (npixg >= 0) npixg *= (ubndg[ idim ] - lbndg[ idim ] + 1);
+ }
+ if (npixg <= 0 && astOK)
+ {
+ if ((inside != 0) == (astGetNegated( used_region ) != 0))
+ {
+ c = in;
+ for (ipix = 0; ipix < npix; ipix++) *(c++) = val;
+ result = npix;
+ }
+ }
+ else if (npixg > 0 && astOK)
+ {
+ if ((inside != 0) == (astGetNegated (used_region) != 0))
+ {
+ tmp_out = astMalloc (sizeof (float)*(size_t) npix);
+ if (tmp_out)
+ {
+ c = tmp_out;
+ for (ipix = 0; ipix < npix; ipix++) *(c++) = val;
+ result = npix - npixg;
+ }
+ out = tmp_out;
+ }
+ else
+ {
+ tmp_out = NULL;
+ out = in;
+ }
+ if (inside) astNegate (used_region);
+ result += astResampleF (used_region, ndim, lbnd, ubnd, in, NULL,
+ NULL, NULL, 0, 0.0, 100, val, ndim,
+ lbnd, ubnd, lbndg, ubndg, out, NULL);
+ if (inside) astNegate (used_region);
+ }
+ }
+ return result;
+}
diff --git a/gcc/testsuite/gcc.dg/pure-2.c b/gcc/testsuite/gcc.dg/pure-2.c
index 638bd7c550d..fe6e2bce695 100644
--- a/gcc/testsuite/gcc.dg/pure-2.c
+++ b/gcc/testsuite/gcc.dg/pure-2.c
@@ -8,14 +8,14 @@ extern int v;
/* Trivial. */
int
foo1(int a) /* { dg-bogus "normally" "detect pure candidate" } */
-{ /* { dg-warning "pure" "detect pure candidate" { target *-*-* } "9" } */
+{ /* { dg-warning "pure" "detect pure candidate" { target *-*-* } "10" } */
return v;
}
/* Loops known to be normally and extern const calls should be safe. */
int __attribute__ ((noinline))
foo2(int n) /* { dg-bogus "normally" "detect pure candidate" } */
-{ /* { dg-warning "pure" "detect pure candidate" { target *-*-* } "16" } */
+{ /* { dg-warning "pure" "detect pure candidate" { target *-*-* } "17" } */
int ret = 0;
int i;
for (i=0; i<n; i++)
@@ -53,6 +53,6 @@ foo4(int n) /* { dg-warning "pure\[^\n\]* normally" "detect pure candidate" } *
int
foo5(int n) /* { dg-bogus "normally" "detect pure candidate" } */
-{ /* { dg-warning "pure" "detect pure candidate" { target *-*-* } "54" } */
+{ /* { dg-warning "pure" "detect pure candidate" { target *-*-* } "55" } */
return foo2(n);
}
diff --git a/gcc/testsuite/gcc.dg/ubsan/pr63690.c b/gcc/testsuite/gcc.dg/ubsan/pr63690.c
new file mode 100644
index 00000000000..be8600f3fae
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ubsan/pr63690.c
@@ -0,0 +1,18 @@
+/* PR sanitizer/63690 */
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=undefined" } */
+
+void
+foo (void)
+{
+ (*"c")++;
+}
+/* PR sanitizer/63690 */
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=undefined" } */
+
+void
+foo (void)
+{
+ (*"c")++;
+}
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index a95749541b1..e78554f5721 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -3347,22 +3347,14 @@ verify_gimple_call (gcall *stmt)
return true;
}
- /* If there is a static chain argument, this should not be an indirect
- call, and the decl should have DECL_STATIC_CHAIN set. */
- if (gimple_call_chain (stmt))
+ /* If there is a static chain argument, the call should either be
+ indirect, or the decl should have DECL_STATIC_CHAIN set. */
+ if (gimple_call_chain (stmt)
+ && fndecl
+ && !DECL_STATIC_CHAIN (fndecl))
{
- if (!gimple_call_fndecl (stmt))
- {
- error ("static chain in indirect gimple call");
- return true;
- }
- fn = TREE_OPERAND (fn, 0);
-
- if (!DECL_STATIC_CHAIN (fn))
- {
- error ("static chain with function that doesn%'t use one");
- return true;
- }
+ error ("static chain with function that doesn%'t use one");
+ return true;
}
/* ??? The C frontend passes unpromoted arguments in case it
diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c
index 31ea04c3a0b..7aa7e31755b 100644
--- a/gcc/tree-loop-distribution.c
+++ b/gcc/tree-loop-distribution.c
@@ -822,9 +822,8 @@ generate_memset_builtin (struct loop *loop, partition_t partition)
val = fold_convert (integer_type_node, val);
else if (!useless_type_conversion_p (integer_type_node, TREE_TYPE (val)))
{
- gimple cstmt;
tree tem = make_ssa_name (integer_type_node, NULL);
- cstmt = gimple_build_assign_with_ops (NOP_EXPR, tem, val, NULL_TREE);
+ gimple cstmt = gimple_build_assign_with_ops (NOP_EXPR, tem, val);
gsi_insert_after (&gsi, cstmt, GSI_CONTINUE_LINKING);
val = tem;
}
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index 4f70b2e3148..43f4f2a05e0 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -757,10 +757,9 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs,
if (useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (new_def_rhs)))
gimple_assign_set_rhs_with_ops (use_stmt_gsi, TREE_CODE (new_def_rhs),
- new_def_rhs, NULL_TREE);
+ new_def_rhs);
else if (is_gimple_min_invariant (new_def_rhs))
- gimple_assign_set_rhs_with_ops (use_stmt_gsi, NOP_EXPR,
- new_def_rhs, NULL_TREE);
+ gimple_assign_set_rhs_with_ops (use_stmt_gsi, NOP_EXPR, new_def_rhs);
else
return false;
gcc_assert (gsi_stmt (*use_stmt_gsi) == use_stmt);
@@ -1725,8 +1724,7 @@ simplify_rotate (gimple_stmt_iterator *gsi)
{
g = gimple_build_assign_with_ops (NOP_EXPR,
make_ssa_name (TREE_TYPE (def_arg2[0]),
- NULL),
- rotcnt, NULL_TREE);
+ NULL), rotcnt);
gsi_insert_before (gsi, g, GSI_SAME_STMT);
rotcnt = gimple_assign_lhs (g);
}
@@ -1740,7 +1738,7 @@ simplify_rotate (gimple_stmt_iterator *gsi)
{
gsi_insert_before (gsi, g, GSI_SAME_STMT);
g = gimple_build_assign_with_ops (NOP_EXPR, gimple_assign_lhs (stmt),
- lhs, NULL_TREE);
+ lhs);
}
gsi_replace (gsi, g, false);
return true;
@@ -2055,7 +2053,7 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
for (i = 0; i < nelts; i++)
mask_elts[i] = build_int_cst (TREE_TYPE (mask_type), sel[i]);
op2 = build_vector (mask_type, mask_elts);
- gimple_assign_set_rhs_with_ops_1 (gsi, VEC_PERM_EXPR, orig, orig, op2);
+ gimple_assign_set_rhs_with_ops (gsi, VEC_PERM_EXPR, orig, orig, op2);
}
update_stmt (gsi_stmt (*gsi));
return true;
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index 6f64f4a801f..0e806f4b682 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -1217,7 +1217,7 @@ move_computations_dom_walker::before_dom_children (basic_block bb)
tree arg = PHI_ARG_DEF (stmt, 0);
new_stmt = gimple_build_assign_with_ops (TREE_CODE (arg),
gimple_phi_result (stmt),
- arg, NULL_TREE);
+ arg);
}
else
{
diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
index 219029084c5..f9c30bf72b6 100644
--- a/gcc/tree-ssa-math-opts.c
+++ b/gcc/tree-ssa-math-opts.c
@@ -1130,8 +1130,7 @@ build_and_insert_cast (gimple_stmt_iterator *gsi, location_t loc,
tree type, tree val)
{
tree result = make_ssa_name (type, NULL);
- gassign *stmt
- = gimple_build_assign_with_ops (NOP_EXPR, result, val, NULL_TREE);
+ gassign *stmt = gimple_build_assign_with_ops (NOP_EXPR, result, val);
gimple_set_location (stmt, loc);
gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
return result;
@@ -2261,13 +2260,11 @@ bswap_replace (gimple cur_stmt, gimple src_stmt, tree fndecl, tree bswap_type,
load_stmt = gimple_build_assign (val_tmp, val_expr);
gimple_set_vuse (load_stmt, n->vuse);
gsi_insert_before (&gsi, load_stmt, GSI_SAME_STMT);
- gimple_assign_set_rhs_with_ops_1 (&gsi, NOP_EXPR, val_tmp,
- NULL_TREE, NULL_TREE);
+ gimple_assign_set_rhs_with_ops (&gsi, NOP_EXPR, val_tmp);
}
else
{
- gimple_assign_set_rhs_with_ops_1 (&gsi, MEM_REF, val_expr,
- NULL_TREE, NULL_TREE);
+ gimple_assign_set_rhs_with_ops (&gsi, MEM_REF, val_expr);
gimple_set_vuse (cur_stmt, n->vuse);
}
update_stmt (cur_stmt);
@@ -2321,8 +2318,7 @@ bswap_replace (gimple cur_stmt, gimple src_stmt, tree fndecl, tree bswap_type,
{
gimple convert_stmt;
tmp = make_temp_ssa_name (bswap_type, NULL, "bswapsrc");
- convert_stmt = gimple_build_assign_with_ops (NOP_EXPR, tmp, src,
- NULL);
+ convert_stmt = gimple_build_assign_with_ops (NOP_EXPR, tmp, src);
gsi_insert_before (&gsi, convert_stmt, GSI_SAME_STMT);
}
@@ -2336,7 +2332,7 @@ bswap_replace (gimple cur_stmt, gimple src_stmt, tree fndecl, tree bswap_type,
{
gimple convert_stmt;
tmp = make_temp_ssa_name (bswap_type, NULL, "bswapdst");
- convert_stmt = gimple_build_assign_with_ops (NOP_EXPR, tgt, tmp, NULL);
+ convert_stmt = gimple_build_assign_with_ops (NOP_EXPR, tgt, tmp);
gsi_insert_after (&gsi, convert_stmt, GSI_SAME_STMT);
}
@@ -2975,8 +2971,8 @@ convert_plusminus_to_widen (gimple_stmt_iterator *gsi, gimple stmt,
if (TREE_CODE (mult_rhs2) == INTEGER_CST)
mult_rhs2 = fold_convert (type2, mult_rhs2);
- gimple_assign_set_rhs_with_ops_1 (gsi, wmult_code, mult_rhs1, mult_rhs2,
- add_rhs);
+ gimple_assign_set_rhs_with_ops (gsi, wmult_code, mult_rhs1, mult_rhs2,
+ add_rhs);
update_stmt (gsi_stmt (*gsi));
widen_mul_stats.maccs_inserted++;
return true;
@@ -3180,8 +3176,7 @@ convert_mult_to_fma (gimple mul_stmt, tree op1, tree op2)
fma_stmt = gimple_build_assign_with_ops (FMA_EXPR,
gimple_assign_lhs (use_stmt),
- mulop1, op2,
- addop);
+ mulop1, op2, addop);
gsi_replace (&gsi, fma_stmt, true);
widen_mul_stats.fmas_inserted++;
}
diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c
index 191845e0cdf..6ee2c39e618 100644
--- a/gcc/tree-ssa-phiopt.c
+++ b/gcc/tree-ssa-phiopt.c
@@ -538,7 +538,7 @@ conditional_replacement (basic_block cond_bb, basic_block middle_bb,
new_var2 = make_ssa_name (TREE_TYPE (result), NULL);
new_stmt = gimple_build_assign_with_ops (CONVERT_EXPR, new_var2,
- new_var, NULL);
+ new_var);
gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
new_var = new_var2;
@@ -1258,7 +1258,7 @@ abs_replacement (basic_block cond_bb, basic_block middle_bb,
lhs = result;
/* Build the modify expression with abs expression. */
- new_stmt = gimple_build_assign_with_ops (ABS_EXPR, lhs, rhs, NULL);
+ new_stmt = gimple_build_assign_with_ops (ABS_EXPR, lhs, rhs);
gsi = gsi_last_bb (cond_bb);
gsi_insert_before (&gsi, new_stmt, GSI_NEW_STMT);
@@ -1268,7 +1268,7 @@ abs_replacement (basic_block cond_bb, basic_block middle_bb,
/* Get the right GSI. We want to insert after the recently
added ABS_EXPR statement (which we know is the first statement
in the block. */
- new_stmt = gimple_build_assign_with_ops (NEGATE_EXPR, result, lhs, NULL);
+ new_stmt = gimple_build_assign_with_ops (NEGATE_EXPR, result, lhs);
gsi_insert_after (&gsi, new_stmt, GSI_NEW_STMT);
}
@@ -1392,12 +1392,12 @@ neg_replacement (basic_block cond_bb, basic_block middle_bb,
logical and arithmetic operations on it. */
tree cond_val_converted = make_ssa_name (TREE_TYPE (rhs), NULL);
new_stmt = gimple_build_assign_with_ops (NOP_EXPR, cond_val_converted,
- cond_val, NULL_TREE);
+ cond_val);
gsi_insert_after (&gsi, new_stmt, GSI_NEW_STMT);
tree neg_cond_val_converted = make_ssa_name (TREE_TYPE (rhs), NULL);
new_stmt = gimple_build_assign_with_ops (NEGATE_EXPR, neg_cond_val_converted,
- cond_val_converted, NULL_TREE);
+ cond_val_converted);
gsi_insert_after (&gsi, new_stmt, GSI_NEW_STMT);
tree tmp = make_ssa_name (TREE_TYPE (rhs), NULL);
diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c
index 76af82858f2..df99f0dea67 100644
--- a/gcc/tree-ssa-reassoc.c
+++ b/gcc/tree-ssa-reassoc.c
@@ -3307,7 +3307,7 @@ maybe_optimize_range_tests (gimple stmt)
}
else
g = gimple_build_assign_with_ops (rhs_code, new_lhs,
- new_op, NULL_TREE);
+ new_op);
gimple_stmt_iterator gsi = gsi_for_stmt (cast_stmt);
gimple_set_uid (g, gimple_uid (cast_stmt));
gimple_set_visited (g, true);
@@ -4217,10 +4217,11 @@ repropagate_negates (void)
tree b = gimple_assign_rhs2 (user);
gimple_stmt_iterator gsi = gsi_for_stmt (feed);
gimple_stmt_iterator gsi2 = gsi_for_stmt (user);
- tree x = make_ssa_name (TREE_TYPE (gimple_assign_lhs (feed)), NULL);
+ tree x = make_ssa_name (TREE_TYPE (gimple_assign_lhs (feed)),
+ NULL);
gimple g = gimple_build_assign_with_ops (PLUS_EXPR, x, a, b);
gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
- gimple_assign_set_rhs_with_ops (&gsi2, NEGATE_EXPR, x, NULL);
+ gimple_assign_set_rhs_with_ops (&gsi2, NEGATE_EXPR, x);
user = gsi_stmt (gsi2);
update_stmt (user);
reassoc_remove_stmt (&gsi);
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index 5bd6c7624b9..c02e6128aa7 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -1816,7 +1816,7 @@ handle_pointer_plus (gimple_stmt_iterator *gsi)
enum tree_code rhs_code
= useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (si->endptr))
? SSA_NAME : NOP_EXPR;
- gimple_assign_set_rhs_with_ops (gsi, rhs_code, si->endptr, NULL_TREE);
+ gimple_assign_set_rhs_with_ops (gsi, rhs_code, si->endptr);
gcc_assert (gsi_stmt (*gsi) == stmt);
update_stmt (stmt);
}
diff --git a/gcc/tree-ssa-tail-merge.c b/gcc/tree-ssa-tail-merge.c
index b294bf9f5ab..230a4223dbd 100644
--- a/gcc/tree-ssa-tail-merge.c
+++ b/gcc/tree-ssa-tail-merge.c
@@ -326,7 +326,8 @@ stmt_local_def (gimple stmt)
if (gimple_vdef (stmt) != NULL_TREE
|| gimple_has_side_effects (stmt)
- || gimple_could_trap_p_1 (stmt, false, false))
+ || gimple_could_trap_p_1 (stmt, false, false)
+ || gimple_vuse (stmt) != NULL_TREE)
return false;
def_p = SINGLE_SSA_DEF_OPERAND (stmt, SSA_OP_DEF);
@@ -1175,7 +1176,8 @@ gimple_equal_p (same_succ same_succ, gimple s1, gimple s2)
gimple_assign_rhs1 (s2)));
else if (TREE_CODE (lhs1) == SSA_NAME
&& TREE_CODE (lhs2) == SSA_NAME)
- return vn_valueize (lhs1) == vn_valueize (lhs2);
+ return operand_equal_p (gimple_assign_rhs1 (s1),
+ gimple_assign_rhs1 (s2), 0);
return false;
case GIMPLE_COND:
diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c
index cb76ade69d7..64ccaa3becf 100644
--- a/gcc/tree-vect-loop-manip.c
+++ b/gcc/tree-vect-loop-manip.c
@@ -2158,7 +2158,7 @@ vect_create_cond_for_align_checks (loop_vec_info loop_vinfo,
sprintf (tmp_name, "addr2int%d", i);
addr_tmp_name = make_temp_ssa_name (int_ptrsize_type, NULL, tmp_name);
addr_stmt = gimple_build_assign_with_ops (NOP_EXPR, addr_tmp_name,
- addr_base, NULL_TREE);
+ addr_base);
gimple_seq_add_stmt (cond_expr_stmt_list, addr_stmt);
/* The addresses are OR together. */
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index 41907facf8e..a4f9501b29e 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -2504,7 +2504,7 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi,
tree rhs = gimple_assign_rhs2 (def_stmt);
tree negrhs = make_ssa_name (TREE_TYPE (rhs), NULL);
gimple negate_stmt = gimple_build_assign_with_ops (NEGATE_EXPR, negrhs,
- rhs, NULL);
+ rhs);
gimple_stmt_iterator gsi = gsi_for_stmt (def_stmt);
set_vinfo_for_stmt (negate_stmt, new_stmt_vec_info (negate_stmt,
loop_info, NULL));
@@ -3383,7 +3383,7 @@ get_initial_def_for_induction (gimple iv_phi)
new_stmt = gimple_build_assign_with_ops
(VIEW_CONVERT_EXPR,
vect_get_new_vect_var (vectype, vect_simple_var, "vec_iv_"),
- build1 (VIEW_CONVERT_EXPR, vectype, vec_init), NULL_TREE);
+ build1 (VIEW_CONVERT_EXPR, vectype, vec_init));
vec_init = make_ssa_name (gimple_assign_lhs (new_stmt), new_stmt);
gimple_assign_set_lhs (new_stmt, vec_init);
new_bb = gsi_insert_on_edge_immediate (loop_preheader_edge (iv_loop),
@@ -3559,7 +3559,7 @@ get_initial_def_for_induction (gimple iv_phi)
vect_get_new_vect_var (resvectype, vect_simple_var,
"vec_iv_"),
build1 (VIEW_CONVERT_EXPR, resvectype,
- gimple_assign_lhs (new_stmt)), NULL_TREE);
+ gimple_assign_lhs (new_stmt)));
gimple_assign_set_lhs (new_stmt,
make_ssa_name
(gimple_assign_lhs (new_stmt), new_stmt));
@@ -3626,7 +3626,7 @@ get_initial_def_for_induction (gimple iv_phi)
new_stmt = gimple_build_assign_with_ops
(VIEW_CONVERT_EXPR,
vect_get_new_vect_var (resvectype, vect_simple_var, "vec_iv_"),
- build1 (VIEW_CONVERT_EXPR, resvectype, induc_def), NULL_TREE);
+ build1 (VIEW_CONVERT_EXPR, resvectype, induc_def));
induc_def = make_ssa_name (gimple_assign_lhs (new_stmt), new_stmt);
gimple_assign_set_lhs (new_stmt, induc_def);
si = gsi_after_labels (bb);
diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c
index aedfde0c191..f2bce3cbaa5 100644
--- a/gcc/tree-vect-patterns.c
+++ b/gcc/tree-vect-patterns.c
@@ -760,8 +760,7 @@ vect_handle_widen_op_by_const (gimple stmt, enum tree_code code,
/* Create a_T = (NEW_TYPE) a_t; */
*oprnd = gimple_assign_rhs1 (def_stmt);
new_oprnd = make_ssa_name (new_type, NULL);
- new_stmt = gimple_build_assign_with_ops (NOP_EXPR, new_oprnd, *oprnd,
- NULL_TREE);
+ new_stmt = gimple_build_assign_with_ops (NOP_EXPR, new_oprnd, *oprnd);
STMT_VINFO_RELATED_STMT (vinfo_for_stmt (def_stmt)) = new_stmt;
stmts->safe_push (def_stmt);
*oprnd = new_oprnd;
@@ -935,7 +934,7 @@ vect_recog_widen_mult_pattern (vec<gimple> *stmts,
tree old_oprnd = gimple_assign_rhs1 (def_stmt);
tree new_oprnd = make_ssa_name (half_type0, NULL);
new_stmt = gimple_build_assign_with_ops (NOP_EXPR, new_oprnd,
- old_oprnd, NULL_TREE);
+ old_oprnd);
*oprnd = new_oprnd;
}
@@ -1032,8 +1031,7 @@ vect_recog_widen_mult_pattern (vec<gimple> *stmts,
pattern_stmt
= gimple_build_assign_with_ops (NOP_EXPR,
vect_recog_temp_ssa_var (type, NULL),
- gimple_assign_lhs (pattern_stmt),
- NULL_TREE);
+ gimple_assign_lhs (pattern_stmt));
}
if (dump_enabled_p ())
@@ -1443,7 +1441,7 @@ vect_operation_fits_smaller_type (gimple stmt, tree def, tree *new_type,
oprnd = gimple_assign_rhs1 (def_stmt);
new_oprnd = make_ssa_name (interm_type, NULL);
new_stmt = gimple_build_assign_with_ops (NOP_EXPR, new_oprnd,
- oprnd, NULL_TREE);
+ oprnd);
STMT_VINFO_RELATED_STMT (vinfo_for_stmt (def_stmt)) = new_stmt;
stmts->safe_push (def_stmt);
oprnd = new_oprnd;
@@ -1462,7 +1460,7 @@ vect_operation_fits_smaller_type (gimple stmt, tree def, tree *new_type,
/* Create a type conversion HALF_TYPE->INTERM_TYPE. */
new_oprnd = make_ssa_name (interm_type, NULL);
new_stmt = gimple_build_assign_with_ops (NOP_EXPR, new_oprnd,
- oprnd, NULL_TREE);
+ oprnd);
oprnd = new_oprnd;
*new_def_stmt = new_stmt;
}
@@ -1594,7 +1592,7 @@ vect_recog_over_widening_pattern (vec<gimple> *stmts,
/* Create NEW_TYPE->USE_TYPE conversion. */
new_oprnd = make_ssa_name (use_type, NULL);
pattern_stmt = gimple_build_assign_with_ops (NOP_EXPR, new_oprnd,
- var, NULL_TREE);
+ var);
STMT_VINFO_RELATED_STMT (vinfo_for_stmt (use_stmt)) = pattern_stmt;
*type_in = get_vectype_for_scalar_type (new_type);
@@ -1946,8 +1944,7 @@ vect_recog_rotate_pattern (vec<gimple> *stmts, tree *type_in, tree *type_out)
if (def == NULL_TREE)
{
def = vect_recog_temp_ssa_var (type, NULL);
- def_stmt = gimple_build_assign_with_ops (NOP_EXPR, def, oprnd1,
- NULL_TREE);
+ def_stmt = gimple_build_assign_with_ops (NOP_EXPR, def, oprnd1);
if (ext_def)
{
basic_block new_bb
@@ -1977,8 +1974,7 @@ vect_recog_rotate_pattern (vec<gimple> *stmts, tree *type_in, tree *type_out)
if (vecstype == NULL_TREE)
return NULL;
def2 = vect_recog_temp_ssa_var (stype, NULL);
- def_stmt = gimple_build_assign_with_ops (NEGATE_EXPR, def2, def,
- NULL_TREE);
+ def_stmt = gimple_build_assign_with_ops (NEGATE_EXPR, def2, def);
if (ext_def)
{
basic_block new_bb
@@ -2151,8 +2147,7 @@ vect_recog_vector_vector_shift_pattern (vec<gimple> *stmts,
if (def == NULL_TREE)
{
def = vect_recog_temp_ssa_var (TREE_TYPE (oprnd0), NULL);
- def_stmt = gimple_build_assign_with_ops (NOP_EXPR, def, oprnd1,
- NULL_TREE);
+ def_stmt = gimple_build_assign_with_ops (NOP_EXPR, def, oprnd1);
new_pattern_def_seq (stmt_vinfo, def_stmt);
}
@@ -2350,8 +2345,7 @@ vect_recog_divmod_pattern (vec<gimple> *stmts,
append_pattern_def_seq (stmt_vinfo, def_stmt);
signmask = vect_recog_temp_ssa_var (itype, NULL);
def_stmt
- = gimple_build_assign_with_ops (NOP_EXPR, signmask, var,
- NULL_TREE);
+ = gimple_build_assign_with_ops (NOP_EXPR, signmask, var);
append_pattern_def_seq (stmt_vinfo, def_stmt);
}
def_stmt
@@ -2613,8 +2607,7 @@ vect_recog_divmod_pattern (vec<gimple> *stmts,
if (msb != 1)
def_stmt
= gimple_build_assign_with_ops (INTEGER_CST,
- t4, build_int_cst (itype, msb),
- NULL_TREE);
+ t4, build_int_cst (itype, msb));
else
def_stmt
= gimple_build_assign_with_ops (RSHIFT_EXPR, t4, oprnd0,
@@ -2809,7 +2802,7 @@ vect_recog_mixed_size_cond_pattern (vec<gimple> *stmts, tree *type_in,
pattern_stmt
= gimple_build_assign_with_ops (NOP_EXPR,
vect_recog_temp_ssa_var (type, NULL),
- gimple_assign_lhs (def_stmt), NULL_TREE);
+ gimple_assign_lhs (def_stmt));
new_pattern_def_seq (stmt_vinfo, def_stmt);
def_stmt_info = new_stmt_vec_info (def_stmt, loop_vinfo, bb_vinfo);
@@ -2923,8 +2916,7 @@ adjust_bool_pattern_cast (tree type, tree var)
cast_stmt
= gimple_build_assign_with_ops (NOP_EXPR,
vect_recog_temp_ssa_var (type, NULL),
- gimple_assign_lhs (pattern_stmt),
- NULL_TREE);
+ gimple_assign_lhs (pattern_stmt));
STMT_VINFO_RELATED_STMT (stmt_vinfo) = cast_stmt;
return gimple_assign_lhs (cast_stmt);
}
@@ -2961,7 +2953,7 @@ adjust_bool_pattern (tree var, tree out_type, tree trueval,
pattern_stmt
= gimple_build_assign_with_ops (SSA_NAME,
vect_recog_temp_ssa_var (itype, NULL),
- irhs1, NULL_TREE);
+ irhs1);
break;
case BIT_NOT_EXPR:
@@ -3209,10 +3201,10 @@ vect_recog_bool_pattern (vec<gimple> *stmts, tree *type_in,
lhs = vect_recog_temp_ssa_var (TREE_TYPE (lhs), NULL);
if (useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
pattern_stmt
- = gimple_build_assign_with_ops (SSA_NAME, lhs, rhs, NULL_TREE);
+ = gimple_build_assign_with_ops (SSA_NAME, lhs, rhs);
else
pattern_stmt
- = gimple_build_assign_with_ops (NOP_EXPR, lhs, rhs, NULL_TREE);
+ = gimple_build_assign_with_ops (NOP_EXPR, lhs, rhs);
*type_out = vectype;
*type_in = vectype;
stmts->safe_push (last_stmt);
@@ -3278,12 +3270,12 @@ vect_recog_bool_pattern (vec<gimple> *stmts, tree *type_in,
{
tree rhs2 = vect_recog_temp_ssa_var (TREE_TYPE (lhs), NULL);
gimple cast_stmt
- = gimple_build_assign_with_ops (NOP_EXPR, rhs2, rhs, NULL_TREE);
+ = gimple_build_assign_with_ops (NOP_EXPR, rhs2, rhs);
new_pattern_def_seq (stmt_vinfo, cast_stmt);
rhs = rhs2;
}
pattern_stmt
- = gimple_build_assign_with_ops (SSA_NAME, lhs, rhs, NULL_TREE);
+ = gimple_build_assign_with_ops (SSA_NAME, lhs, rhs);
pattern_stmt_info = new_stmt_vec_info (pattern_stmt, loop_vinfo,
bb_vinfo);
set_vinfo_for_stmt (pattern_stmt, pattern_stmt_info);
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index efb3b4c0fb3..829f74aaea8 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -2610,7 +2610,7 @@ vect_get_constant_vectors (tree op, slp_tree slp_node,
op);
init_stmt
= gimple_build_assign_with_ops (VIEW_CONVERT_EXPR,
- new_temp, op, NULL_TREE);
+ new_temp, op);
gimple_seq_add_stmt (&ctor_seq, init_stmt);
op = new_temp;
}
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index c153f422587..e80ac95a7fe 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -1333,8 +1333,7 @@ vect_init_vector (gimple stmt, tree val, tree type, gimple_stmt_iterator *gsi)
{
new_temp = make_ssa_name (TREE_TYPE (type), NULL);
init_stmt = gimple_build_assign_with_ops (NOP_EXPR,
- new_temp, val,
- NULL_TREE);
+ new_temp, val);
vect_init_vector_1 (stmt, init_stmt, gsi);
val = new_temp;
}
@@ -1970,8 +1969,7 @@ vectorizable_mask_load_store (gimple stmt, gimple_stmt_iterator *gsi,
var = make_ssa_name (var, NULL);
op = build1 (VIEW_CONVERT_EXPR, idxtype, op);
new_stmt
- = gimple_build_assign_with_ops (VIEW_CONVERT_EXPR, var,
- op, NULL_TREE);
+ = gimple_build_assign_with_ops (VIEW_CONVERT_EXPR, var, op);
vect_finish_stmt_generation (stmt, new_stmt, gsi);
op = var;
}
@@ -2001,7 +1999,7 @@ vectorizable_mask_load_store (gimple stmt, gimple_stmt_iterator *gsi,
mask_op = build1 (VIEW_CONVERT_EXPR, masktype, mask_op);
new_stmt
= gimple_build_assign_with_ops (VIEW_CONVERT_EXPR, var,
- mask_op, NULL_TREE);
+ mask_op);
vect_finish_stmt_generation (stmt, new_stmt, gsi);
mask_op = var;
}
@@ -2022,8 +2020,7 @@ vectorizable_mask_load_store (gimple stmt, gimple_stmt_iterator *gsi,
var = make_ssa_name (vec_dest, NULL);
op = build1 (VIEW_CONVERT_EXPR, vectype, op);
new_stmt
- = gimple_build_assign_with_ops (VIEW_CONVERT_EXPR, var, op,
- NULL_TREE);
+ = gimple_build_assign_with_ops (VIEW_CONVERT_EXPR, var, op);
}
else
{
@@ -3197,7 +3194,7 @@ vectorizable_simd_clone_call (gimple stmt, gimple_stmt_iterator *gsi,
set_vinfo_for_stmt (new_stmt, stmt_info);
set_vinfo_for_stmt (stmt, NULL);
STMT_VINFO_STMT (stmt_info) = new_stmt;
- gsi_replace (gsi, new_stmt, false);
+ gsi_replace (gsi, new_stmt, true);
unlink_stmt_vdef (stmt);
return true;
@@ -3792,7 +3789,7 @@ vectorizable_conversion (gimple stmt, gimple_stmt_iterator *gsi,
{
gcc_assert (TREE_CODE_LENGTH (code1) == unary_op);
new_stmt = gimple_build_assign_with_ops (code1, vec_dest,
- vop0, NULL);
+ vop0);
new_temp = make_ssa_name (vec_dest, new_stmt);
gimple_assign_set_lhs (new_stmt, new_temp);
}
@@ -3904,8 +3901,7 @@ vectorizable_conversion (gimple stmt, gimple_stmt_iterator *gsi,
gcc_assert (TREE_CODE_LENGTH (codecvt1) == unary_op);
new_temp = make_ssa_name (vec_dest, NULL);
new_stmt = gimple_build_assign_with_ops (codecvt1,
- new_temp,
- vop0, NULL);
+ new_temp, vop0);
}
vect_finish_stmt_generation (stmt, new_stmt, gsi);
@@ -3962,7 +3958,7 @@ vectorizable_conversion (gimple stmt, gimple_stmt_iterator *gsi,
gcc_assert (TREE_CODE_LENGTH (codecvt1) == unary_op);
new_temp = make_ssa_name (vec_dest, NULL);
new_stmt = gimple_build_assign_with_ops (codecvt1, new_temp,
- vop0, NULL);
+ vop0);
}
vect_finish_stmt_generation (stmt, new_stmt, gsi);
@@ -5960,8 +5956,7 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
var = make_ssa_name (var, NULL);
op = build1 (VIEW_CONVERT_EXPR, idxtype, op);
new_stmt
- = gimple_build_assign_with_ops (VIEW_CONVERT_EXPR, var,
- op, NULL_TREE);
+ = gimple_build_assign_with_ops (VIEW_CONVERT_EXPR, var, op);
vect_finish_stmt_generation (stmt, new_stmt, gsi);
op = var;
}
@@ -5980,8 +5975,7 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
var = make_ssa_name (vec_dest, NULL);
op = build1 (VIEW_CONVERT_EXPR, vectype, op);
new_stmt
- = gimple_build_assign_with_ops (VIEW_CONVERT_EXPR, var, op,
- NULL_TREE);
+ = gimple_build_assign_with_ops (VIEW_CONVERT_EXPR, var, op);
}
else
{
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 62ec3f24bcd..bcf4c2ba60c 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -8880,8 +8880,7 @@ simplify_truth_ops_using_ranges (gimple_stmt_iterator *gsi, gimple stmt)
if (integer_zerop (op1))
gimple_assign_set_rhs_with_ops (gsi,
need_conversion
- ? NOP_EXPR : TREE_CODE (op0),
- op0, NULL_TREE);
+ ? NOP_EXPR : TREE_CODE (op0), op0);
/* For A != B we substitute A ^ B. Either with conversion. */
else if (need_conversion)
{
@@ -8889,7 +8888,7 @@ simplify_truth_ops_using_ranges (gimple_stmt_iterator *gsi, gimple stmt)
gassign *newop
= gimple_build_assign_with_ops (BIT_XOR_EXPR, tem, op0, op1);
gsi_insert_before (gsi, newop, GSI_SAME_STMT);
- gimple_assign_set_rhs_with_ops (gsi, NOP_EXPR, tem, NULL_TREE);
+ gimple_assign_set_rhs_with_ops (gsi, NOP_EXPR, tem);
}
/* Or without. */
else
@@ -9109,7 +9108,7 @@ simplify_bit_ops_using_ranges (gimple_stmt_iterator *gsi, gimple stmt)
if (op == NULL_TREE)
return false;
- gimple_assign_set_rhs_with_ops (gsi, TREE_CODE (op), op, NULL);
+ gimple_assign_set_rhs_with_ops (gsi, TREE_CODE (op), op);
update_stmt (gsi_stmt (*gsi));
return true;
}
@@ -9613,7 +9612,7 @@ simplify_float_conversion_using_ranges (gimple_stmt_iterator *gsi, gimple stmt)
float conversion. */
tem = make_ssa_name (build_nonstandard_integer_type
(GET_MODE_PRECISION (mode), 0), NULL);
- conv = gimple_build_assign_with_ops (NOP_EXPR, tem, rhs1, NULL_TREE);
+ conv = gimple_build_assign_with_ops (NOP_EXPR, tem, rhs1);
gsi_insert_before (gsi, conv, GSI_SAME_STMT);
gimple_assign_set_rhs1 (stmt, tem);
update_stmt (stmt);
@@ -9687,8 +9686,7 @@ simplify_internal_call_using_ranges (gimple_stmt_iterator *gsi, gimple stmt)
else if (!useless_type_conversion_p (utype, TREE_TYPE (op0)))
{
g = gimple_build_assign_with_ops (NOP_EXPR,
- make_ssa_name (utype, NULL),
- op0, NULL_TREE);
+ make_ssa_name (utype, NULL), op0);
gimple_set_location (g, loc);
gsi_insert_before (gsi, g, GSI_SAME_STMT);
op0 = gimple_assign_lhs (g);
@@ -9698,8 +9696,7 @@ simplify_internal_call_using_ranges (gimple_stmt_iterator *gsi, gimple stmt)
else if (!useless_type_conversion_p (utype, TREE_TYPE (op1)))
{
g = gimple_build_assign_with_ops (NOP_EXPR,
- make_ssa_name (utype, NULL),
- op1, NULL_TREE);
+ make_ssa_name (utype, NULL), op1);
gimple_set_location (g, loc);
gsi_insert_before (gsi, g, GSI_SAME_STMT);
op1 = gimple_assign_lhs (g);
@@ -9712,7 +9709,7 @@ simplify_internal_call_using_ranges (gimple_stmt_iterator *gsi, gimple stmt)
{
g = gimple_build_assign_with_ops (NOP_EXPR,
make_ssa_name (type, NULL),
- gimple_assign_lhs (g), NULL_TREE);
+ gimple_assign_lhs (g));
gimple_set_location (g, loc);
gsi_insert_before (gsi, g, GSI_SAME_STMT);
}
diff --git a/gcc/tsan.c b/gcc/tsan.c
index 53f30a1b833..763f57383be 100644
--- a/gcc/tsan.c
+++ b/gcc/tsan.c
@@ -501,8 +501,7 @@ instrument_builtin_call (gimple_stmt_iterator *gsi)
TREE_TYPE (args[1])))
{
tree var = make_ssa_name (TREE_TYPE (lhs), NULL);
- g = gimple_build_assign_with_ops (NOP_EXPR, var,
- args[1], NULL_TREE);
+ g = gimple_build_assign_with_ops (NOP_EXPR, var, args[1]);
gsi_insert_after (gsi, g, GSI_NEW_STMT);
args[1] = var;
}
@@ -516,8 +515,7 @@ instrument_builtin_call (gimple_stmt_iterator *gsi)
gimple_call_lhs (stmt),
args[1]);
gsi_insert_after (gsi, g, GSI_NEW_STMT);
- g = gimple_build_assign_with_ops (BIT_NOT_EXPR, lhs, var,
- NULL_TREE);
+ g = gimple_build_assign_with_ops (BIT_NOT_EXPR, lhs, var);
}
else
g = gimple_build_assign_with_ops (tsan_atomic_table[i].code,
@@ -560,7 +558,7 @@ instrument_builtin_call (gimple_stmt_iterator *gsi)
g = gimple_build_assign_with_ops (NOP_EXPR,
make_ssa_name (TREE_TYPE (t),
NULL),
- args[1], NULL_TREE);
+ args[1]);
gsi_insert_before (gsi, g, GSI_SAME_STMT);
args[1] = gimple_assign_lhs (g);
}
diff --git a/gcc/ubsan.c b/gcc/ubsan.c
index db79d4b9e15..5da0b180928 100644
--- a/gcc/ubsan.c
+++ b/gcc/ubsan.c
@@ -67,6 +67,7 @@ along with GCC; see the file COPYING3. If not see
#include "dfp.h"
#include "builtins.h"
#include "tree-object-size.h"
+#include "tree-eh.h"
/* Map from a tree to a VAR_DECL tree. */
@@ -735,8 +736,7 @@ ubsan_expand_null_ifn (gimple_stmt_iterator *gsip)
if (compare_tree_int (align, ptralign) == 1)
{
check_align = make_ssa_name (pointer_sized_int_node, NULL);
- g = gimple_build_assign_with_ops (NOP_EXPR, check_align,
- ptr, NULL_TREE);
+ g = gimple_build_assign_with_ops (NOP_EXPR, check_align, ptr);
gimple_set_location (g, loc);
gsi_insert_before (&gsi, g, GSI_SAME_STMT);
}
@@ -933,7 +933,7 @@ ubsan_expand_objsize_ifn (gimple_stmt_iterator *gsi)
? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
: BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
tree p = make_ssa_name (pointer_sized_int_node, NULL);
- g = gimple_build_assign_with_ops (NOP_EXPR, p, ptr, NULL_TREE);
+ g = gimple_build_assign_with_ops (NOP_EXPR, p, ptr);
gimple_set_location (g, loc);
gsi_insert_before (gsi, g, GSI_SAME_STMT);
g = gimple_build_call (builtin_decl_explicit (bcode), 2, data, p);
@@ -1159,7 +1159,9 @@ instrument_bool_enum_load (gimple_stmt_iterator *gsi)
|| TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
return;
+ bool can_throw = stmt_could_throw_p (stmt);
location_t loc = gimple_location (stmt);
+ tree lhs = gimple_assign_lhs (stmt);
tree ptype = build_pointer_type (TREE_TYPE (rhs));
tree atype = reference_alias_ptr_type (rhs);
gimple g = gimple_build_assign (make_ssa_name (ptype, NULL),
@@ -1169,9 +1171,24 @@ instrument_bool_enum_load (gimple_stmt_iterator *gsi)
tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
build_int_cst (atype, 0));
tree urhs = make_ssa_name (utype, NULL);
- g = gimple_build_assign (urhs, mem);
- gimple_set_location (g, loc);
- gsi_insert_before (gsi, g, GSI_SAME_STMT);
+ if (can_throw)
+ {
+ gimple_assign_set_lhs (stmt, urhs);
+ g = gimple_build_assign_with_ops (NOP_EXPR, lhs, urhs);
+ gimple_set_location (g, loc);
+ edge e = find_fallthru_edge (gimple_bb (stmt)->succs);
+ gsi_insert_on_edge_immediate (e, g);
+ gimple_assign_set_rhs_from_tree (gsi, mem);
+ update_stmt (stmt);
+ *gsi = gsi_for_stmt (g);
+ g = stmt;
+ }
+ else
+ {
+ g = gimple_build_assign (urhs, mem);
+ gimple_set_location (g, loc);
+ gsi_insert_before (gsi, g, GSI_SAME_STMT);
+ }
minv = fold_convert (utype, minv);
maxv = fold_convert (utype, maxv);
if (!integer_zerop (minv))
@@ -1193,8 +1210,11 @@ instrument_bool_enum_load (gimple_stmt_iterator *gsi)
gimple_set_location (g, loc);
gsi_insert_after (gsi, g, GSI_NEW_STMT);
- gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs, NULL_TREE);
- update_stmt (stmt);
+ if (!can_throw)
+ {
+ gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs);
+ update_stmt (stmt);
+ }
gsi2 = gsi_after_labels (then_bb);
if (flag_sanitize_undefined_trap_on_error)
@@ -1518,7 +1538,13 @@ instrument_object_size (gimple_stmt_iterator *gsi, bool is_lhs)
return;
bool decl_p = DECL_P (inner);
- tree base = decl_p ? inner : TREE_OPERAND (inner, 0);
+ tree base;
+ if (decl_p)
+ base = inner;
+ else if (TREE_CODE (inner) == MEM_REF)
+ base = TREE_OPERAND (inner, 0);
+ else
+ return;
tree ptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
while (TREE_CODE (base) == SSA_NAME)
diff --git a/gcc/varpool.c b/gcc/varpool.c
index 80dd496a49a..50f2e6e755a 100644
--- a/gcc/varpool.c
+++ b/gcc/varpool.c
@@ -171,9 +171,11 @@ varpool_node::get_create (tree decl)
&& lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl)))
{
node->offloadable = 1;
+#ifdef ENABLE_OFFLOADING
g->have_offload = true;
if (!in_lto_p)
vec_safe_push (offload_vars, decl);
+#endif
}
node->register_symbol ();
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index 737cd2476b6..5e6d3bf29ea 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,3 +1,9 @@
+2014-11-19 Uros Bizjak <ubizjak@gmail.com>
+
+ * testsuite/libgomp.c/examples-4/e.53.5.c: Require
+ vect_simd_clones effective target.
+ * testsuite/libgomp.fortran/examples-4/e.53.5.f90: Ditto.
+
2014-11-14 Jakub Jelinek <jakub@redhat.com>
* libgomp.c/examples-4/e.54.2.c (main): Use N / 8 instead
diff --git a/libgomp/testsuite/libgomp.c/examples-4/e.53.5.c b/libgomp/testsuite/libgomp.c/examples-4/e.53.5.c
index 3bcd753dbbb..2b16dbed6b2 100644
--- a/libgomp/testsuite/libgomp.c/examples-4/e.53.5.c
+++ b/libgomp/testsuite/libgomp.c/examples-4/e.53.5.c
@@ -1,4 +1,4 @@
-/* { dg-do run } */
+/* { dg-do run { target vect_simd_clones } } */
/* { dg-options "-O2" } */
/* { dg-additional-options "-msse2" { target sse2_runtime } } */
/* { dg-additional-options "-mavx" { target avx_runtime } } */
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/e.53.5.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/e.53.5.f90
index 304c9fb2ada..06eae0a6992 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/e.53.5.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/e.53.5.f90
@@ -1,4 +1,4 @@
-! { dg-do run }
+! { dg-do run { target vect_simd_clones } }
! { dg-options "-O2" }
! { dg-additional-options "-msse2" { target sse2_runtime } }
! { dg-additional-options "-mavx" { target avx_runtime } }
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 857c05e163e..c0e17389558 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,12 @@
+2014-11-18 Marc Glisse <marc.glisse@inria.fr>
+
+ PR libstdc++/43622
+ * config/abi/pre/float128.ver: New file.
+ * configure.ac: Use float128.ver when relevant.
+ * configure: Regenerate.
+ * testsuite/util/testsuite_abi.cc (check_version): Accept new
+ CXXABI_FLOAT128 version.
+
2014-11-17 Jason Merrill <jason@redhat.com>
* include/backward/binders.h: Suppress -Wdeprecated-declarations.
diff --git a/libstdc++-v3/config/abi/pre/float128.ver b/libstdc++-v3/config/abi/pre/float128.ver
new file mode 100644
index 00000000000..26c62c70be0
--- /dev/null
+++ b/libstdc++-v3/config/abi/pre/float128.ver
@@ -0,0 +1,10 @@
+# Appended to version file.
+
+CXXABI_FLOAT128 {
+
+ # typeinfo and typeinfo name for __float128
+ _ZT[IS]g;
+ _ZT[IS]Pg;
+ _ZT[IS]PKg;
+
+};
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index 6a57537b87c..5fcb705b363 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -15710,6 +15710,9 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test "$enable_float128" = yes; then
+ port_specific_symbol_files="$port_specific_symbol_files \$(top_srcdir)/config/abi/pre/float128.ver"
+fi
# Checks for compiler support that doesn't require linking.
diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac
index eb826e4133f..135d536e1b2 100644
--- a/libstdc++-v3/configure.ac
+++ b/libstdc++-v3/configure.ac
@@ -153,6 +153,9 @@ GLIBCXX_ENABLE_THREADS
GLIBCXX_ENABLE_ATOMIC_BUILTINS
GLIBCXX_ENABLE_DECIMAL_FLOAT
GLIBCXX_ENABLE_INT128_FLOAT128
+if test "$enable_float128" = yes; then
+ port_specific_symbol_files="$port_specific_symbol_files \$(top_srcdir)/config/abi/pre/float128.ver"
+fi
# Checks for compiler support that doesn't require linking.
GLIBCXX_CHECK_COMPILER_FEATURES
diff --git a/libstdc++-v3/testsuite/util/testsuite_abi.cc b/libstdc++-v3/testsuite/util/testsuite_abi.cc
index 06991144dc1..15b05dcb957 100644
--- a/libstdc++-v3/testsuite/util/testsuite_abi.cc
+++ b/libstdc++-v3/testsuite/util/testsuite_abi.cc
@@ -213,6 +213,7 @@ check_version(symbol& test, bool added)
known_versions.push_back("CXXABI_1.3.8");
known_versions.push_back("CXXABI_1.3.9");
known_versions.push_back("CXXABI_TM_1");
+ known_versions.push_back("CXXABI_FLOAT128");
}
compat_list::iterator begin = known_versions.begin();
compat_list::iterator end = known_versions.end();
@@ -230,16 +231,18 @@ check_version(symbol& test, bool added)
// Check that added symbols are added in the latest pre-release version.
bool latestp = (test.version_name == "GLIBCXX_3.4.21"
|| test.version_name == "CXXABI_1.3.9"
+ || test.version_name == "CXXABI_FLOAT128"
|| test.version_name == "CXXABI_TM_1");
if (added && !latestp)
test.version_status = symbol::incompatible;
// Check that long double compatibility symbols demangled as
- // __float128 are put into some _LDBL_ version name.
+ // __float128 and regular __float128 symbols are put into some _LDBL_
+ // or _FLOAT128 version name.
if (added && test.demangled_name.find("__float128") != std::string::npos)
{
- // Has to be in _LDBL_ version name.
- if (test.version_name.find("_LDBL_") == std::string::npos)
+ if (test.version_name.find("_LDBL_") == std::string::npos
+ && test.version_name.find("_FLOAT128") == std::string::npos)
test.version_status = symbol::incompatible;
}