aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2021-08-19 12:03:21 +0200
committerMartin Liska <mliska@suse.cz>2021-08-19 12:03:21 +0200
commit0b6c24dd10ff426108f737551067085d0af42ca8 (patch)
tree50bc9dfc7aaf11d1325281485908fb5bf0bcb54b
parent60ae041aae40e239fda5fbf6f4c4ec047ce50962 (diff)
parent301dc6011cbceb7ea9debd86aaec7cadb37213c8 (diff)
downloadgcc-0b6c24dd10ff426108f737551067085d0af42ca8.zip
gcc-0b6c24dd10ff426108f737551067085d0af42ca8.tar.gz
gcc-0b6c24dd10ff426108f737551067085d0af42ca8.tar.bz2
Merge branch 'master' into devel/sphinx
-rw-r--r--ChangeLog6
-rw-r--r--Makefile.in3
-rw-r--r--Makefile.tpl3
-rw-r--r--config/ChangeLog5
-rw-r--r--config/mh-darwin8
-rw-r--r--contrib/ChangeLog6
-rw-r--r--gcc/ChangeLog51
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/ada/ChangeLog5
-rw-r--r--gcc/analyzer/ChangeLog51
-rw-r--r--gcc/analyzer/analysis-plan.cc4
-rw-r--r--gcc/analyzer/checker-path.cc28
-rw-r--r--gcc/analyzer/checker-path.h6
-rw-r--r--gcc/analyzer/diagnostic-manager.cc23
-rw-r--r--gcc/analyzer/engine.cc183
-rw-r--r--gcc/analyzer/exploded-graph.h39
-rw-r--r--gcc/analyzer/program-point.cc18
-rw-r--r--gcc/analyzer/program-point.h3
-rw-r--r--gcc/analyzer/program-state.cc44
-rw-r--r--gcc/analyzer/program-state.h11
-rw-r--r--gcc/analyzer/region-model.cc49
-rw-r--r--gcc/analyzer/region-model.h6
-rw-r--r--gcc/analyzer/state-purge.cc35
-rw-r--r--gcc/analyzer/supergraph.cc43
-rw-r--r--gcc/analyzer/supergraph.h7
-rw-r--r--gcc/c-family/ChangeLog6
-rw-r--r--gcc/c/ChangeLog29
-rw-r--r--gcc/c/c-parser.c15
-rw-r--r--gcc/config.gcc2
-rw-r--r--gcc/config/aarch64/arm_neon.h8
-rw-r--r--gcc/config/darwin.h3
-rw-r--r--gcc/config/i386/i386.c6
-rw-r--r--gcc/config/i386/i386.h1
-rw-r--r--gcc/config/i386/x86-tune-costs.h26
-rw-r--r--gcc/cp/ChangeLog39
-rw-r--r--gcc/cp/parser.c17
-rw-r--r--gcc/fortran/ChangeLog6
-rw-r--r--gcc/hash-map-tests.c17
-rw-r--r--gcc/jit/ChangeLog5
-rw-r--r--gcc/jit/Make-lang.in63
-rw-r--r--gcc/jit/docs/examples/tut04-toyvm/toyvm.c2
-rw-r--r--gcc/jit/docs/examples/tut04-toyvm/toyvm.cc2
-rw-r--r--gcc/jit/jit-dejagnu.h338
-rw-r--r--gcc/objc/ChangeLog10
-rw-r--r--gcc/objc/objc-act.c16
-rw-r--r--gcc/objc/objc-next-runtime-abi-02.c22
-rw-r--r--gcc/optabs.c79
-rw-r--r--gcc/testsuite/ChangeLog74
-rw-r--r--gcc/testsuite/c-c++-common/gomp/nothing-2.c2
-rw-r--r--gcc/testsuite/c-c++-common/gomp/requires-3.c2
-rw-r--r--gcc/testsuite/g++.dg/analyzer/vfunc-2.C44
-rw-r--r--gcc/testsuite/g++.dg/analyzer/vfunc-3.C32
-rw-r--r--gcc/testsuite/g++.dg/analyzer/vfunc-4.C28
-rw-r--r--gcc/testsuite/g++.dg/analyzer/vfunc-5.C103
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/function-ptr-4.c24
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr100546.c17
-rw-r--r--gcc/testsuite/gcc.dg/pr78213.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/pr101950-1.c20
-rw-r--r--gcc/testsuite/gcc.target/i386/pr101950-2.c19
-rw-r--r--gcc/testsuite/gcc.target/i386/pr99881.c2
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/nothing-1.f90 (renamed from gcc/testsuite/gfortran.dg/nothing-1.f90)0
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/nothing-2.f90 (renamed from gcc/testsuite/gfortran.dg/nothing-2.f90)2
-rw-r--r--gcc/testsuite/jit.dg/harness.h2
-rw-r--r--gcc/testsuite/jit.dg/jit.exp7
-rw-r--r--gcc/testsuite/jit.dg/test-asm.c13
-rw-r--r--gcc/testsuite/jit.dg/test-asm.cc12
-rw-r--r--gcc/testsuite/obj-c++.dg/pr101666-0.mm7
-rw-r--r--gcc/testsuite/obj-c++.dg/pr101666-1.mm10
-rw-r--r--gcc/testsuite/obj-c++.dg/pr101666.inc29
-rw-r--r--gcc/testsuite/objc.dg/pr101666-0.m7
-rw-r--r--gcc/testsuite/objc.dg/pr101666-1.m10
-rw-r--r--gcc/testsuite/objc.dg/pr101666.inc29
-rw-r--r--libgomp/ChangeLog20
-rw-r--r--libiberty/ChangeLog5
-rw-r--r--libiberty/simple-object-mach-o.c5
-rw-r--r--libstdc++-v3/ChangeLog62
-rw-r--r--libstdc++-v3/doc/doxygen/user.cfg.in20
-rw-r--r--libstdc++-v3/include/bits/stl_algo.h86
-rw-r--r--libstdc++-v3/include/bits/stl_function.h134
-rw-r--r--libstdc++-v3/include/bits/unique_ptr.h84
-rw-r--r--libstdc++-v3/include/debug/deque7
-rw-r--r--libstdc++-v3/include/debug/forward_list7
-rw-r--r--libstdc++-v3/include/debug/list7
-rw-r--r--libstdc++-v3/include/debug/vector7
-rw-r--r--libstdc++-v3/include/ext/type_traits.h16
-rw-r--r--libstdc++-v3/include/std/complex29
-rw-r--r--libstdc++-v3/include/std/type_traits55
-rw-r--r--libstdc++-v3/python/libstdcxx/v6/printers.py10
-rw-r--r--libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc14
-rw-r--r--libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc14
90 files changed, 2120 insertions, 311 deletions
diff --git a/ChangeLog b/ChangeLog
index bd56aa2..4fe1423 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2021-08-18 Iain Sandoe <iain@sandoe.co.uk>
+
+ * Makefile.in: Regenerate.
+ * Makefile.tpl: Make the state of the configured host
+ shared flag available to makefile fragements.
+
2021-08-09 Hongyu Wang <hongyu.wang@intel.com>
* MAINTAINERS (Write After Approval): Add myself.
diff --git a/Makefile.in b/Makefile.in
index 3809d17..5c85fcc 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -109,6 +109,9 @@ RPATH_ENVVAR = @RPATH_ENVVAR@
# executables in PATH.
GCC_SHLIB_SUBDIR = @GCC_SHLIB_SUBDIR@
+# If the build should make suitable code for shared host resources.
+host_shared = @host_shared@
+
# Build programs are put under this directory.
BUILD_SUBDIR = @build_subdir@
# This is set by the configure script to the arguments to use when configuring
diff --git a/Makefile.tpl b/Makefile.tpl
index bffd85b..9adf4f9 100644
--- a/Makefile.tpl
+++ b/Makefile.tpl
@@ -112,6 +112,9 @@ RPATH_ENVVAR = @RPATH_ENVVAR@
# executables in PATH.
GCC_SHLIB_SUBDIR = @GCC_SHLIB_SUBDIR@
+# If the build should make suitable code for shared host resources.
+host_shared = @host_shared@
+
# Build programs are put under this directory.
BUILD_SUBDIR = @build_subdir@
# This is set by the configure script to the arguments to use when configuring
diff --git a/config/ChangeLog b/config/ChangeLog
index 19fb8d1..6c3add8 100644
--- a/config/ChangeLog
+++ b/config/ChangeLog
@@ -1,3 +1,8 @@
+2021-08-18 Iain Sandoe <iain@sandoe.co.uk>
+
+ * mh-darwin: Require a non-shared host configuration to
+ enable mdynamic-no-pic where that is supported.
+
2021-07-09 Iain Sandoe <iain@sandoe.co.uk>
* mh-darwin: Make this specific to handling the
diff --git a/config/mh-darwin b/config/mh-darwin
index fb2bb5a..b72835a 100644
--- a/config/mh-darwin
+++ b/config/mh-darwin
@@ -11,9 +11,15 @@
# non-bootstrapped compiler), later stages will be built by GCC which supports
# the required flags.
+# We cannot use mdynamic-no-pic when building shared host resources.
+
+ifeq (${host_shared},no)
BOOTSTRAP_TOOL_CAN_USE_MDYNAMIC_NO_PIC := $(shell \
$(CC) -S -xc /dev/null -o /dev/null -Werror -mno-dynamic-no-pic 2>/dev/null \
&& echo true)
+else
+BOOTSTRAP_TOOL_CAN_USE_MDYNAMIC_NO_PIC := false
+endif
@if gcc-bootstrap
ifeq (${BOOTSTRAP_TOOL_CAN_USE_MDYNAMIC_NO_PIC},true)
@@ -21,8 +27,10 @@ STAGE1_CFLAGS += -mdynamic-no-pic
else
STAGE1_CFLAGS += -fPIC
endif
+ifeq (${host_shared},no)
# Add -mdynamic-no-pic to later stages when we know it is built with GCC.
BOOT_CFLAGS += -mdynamic-no-pic
+endif
@endif gcc-bootstrap
@unless gcc-bootstrap
diff --git a/contrib/ChangeLog b/contrib/ChangeLog
index 4bcb310..d4aa96f 100644
--- a/contrib/ChangeLog
+++ b/contrib/ChangeLog
@@ -1,3 +1,9 @@
+2021-08-18 Martin Liska <mliska@suse.cz>
+
+ * gcc-git-customization.sh: Wrap $@ in quotes.
+ * git-commit-mklog.py: Add new argument --co.
+ * mklog.py: Skip the Co-Authored-By lines.
+
2021-08-10 Martin Liska <mliska@suse.cz>
* mklog.py: Support additional PRs without PR prefix.
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b26f256..4fd8ff7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,54 @@
+2021-08-18 Iain Sandoe <iain@sandoe.co.uk>
+
+ * config.gcc: Include rpath.opt for Darwin.
+ * config/darwin.h (DRIVER_SELF_SPECS): Handle -rpath.
+
+2021-08-18 Thomas Schwinge <thomas@codesourcery.com>
+
+ PR bootstrap/101959
+ * hash-map-tests.c (test_map_of_type_with_ctor_and_dtor_expand):
+ Use an 'int_hash'.
+
+2021-08-18 Jonathan Wright <jonathan.wright@arm.com>
+
+ * config/aarch64/arm_neon.h (vld3_lane_f64): Use float RTL
+ pattern and type cast.
+ (vld4_lane_f32): Use float RTL pattern.
+ (vld4q_lane_f64): Use float type cast.
+
+2021-08-18 Jan Hubicka <hubicka@ucw.cz>
+
+ * tree-ssa-uninit.c (maybe_warn_pass_by_reference): Check also
+ EAF_NOREAD.
+
+2021-08-18 Thomas Schwinge <thomas@codesourcery.com>
+
+ * hash-map-tests.c (test_map_of_type_with_ctor_and_dtor): Extend.
+ (test_map_of_type_with_ctor_and_dtor_expand): Add function.
+ (hash_map_tests_c_tests): Call it.
+
+2021-08-18 Thomas Schwinge <thomas@codesourcery.com>
+
+ * ggc.h (enum ggc_collect): New.
+ (ggc_collect): Use it.
+ * ggc-page.c: Adjust.
+ * ggc-common.c: Likewise.
+ * ggc-tests.c: Likewise.
+ * read-rtl-function.c: Likewise.
+ * selftest-run-tests.c: Likewise.
+ * doc/gty.texi (Invoking the garbage collector): Likewise.
+
+2021-08-18 liuhongt <hongtao.liu@intel.com>
+
+ PR target/97147
+ * config/i386/i386.h (TARGET_V2DF_REDUCTION_PREFER_HADDPD):
+ New macro.
+ * config/i386/sse.md (*sse3_haddv2df3_low): Add
+ TARGET_V2DF_REDUCTION_PREFER_HADDPD.
+ (*sse3_hsubv2df3_low): Ditto.
+ * config/i386/x86-tune.def
+ (X86_TUNE_V2DF_REDUCTION_PREFER_HADDPD): New tune.
+
2021-08-17 Andrew MacLeod <amacleod@redhat.com>
* gimple-range-gori.cc (gori_compute::gori_compute): Enable tracing.
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 70b09db..30a51b9 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20210818
+20210819
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 8e19ca4..63a04b1 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,8 @@
+2021-08-18 Eric Botcazou <ebotcazou@gcc.gnu.org>
+
+ * gcc-interface/decl.c (gnat_to_gnu_entity) <discrete_type>: Fix
+ thinko in latest change.
+
2021-08-11 Bernd Edlinger <bernd.edlinger@hotmail.de>
PR debug/101598
diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog
index 43e3c63..0b483cc 100644
--- a/gcc/analyzer/ChangeLog
+++ b/gcc/analyzer/ChangeLog
@@ -1,3 +1,54 @@
+2021-08-18 Ankur Saini <arsenic@sourceware.org>
+
+ PR analyzer/97114
+ * region-model.cc (region_model::get_rvalue_1): Add case for
+ OBJ_TYPE_REF.
+
+2021-08-18 Ankur Saini <arsenic@sourceware.org>
+
+ PR analyzer/100546
+ * analysis-plan.cc (analysis_plan::use_summary_p): Don't use call
+ summaries if there is no callgraph edge
+ * checker-path.cc (call_event::call_event): Handle calls events that
+ are not represented by a supergraph call edge
+ (return_event::return_event): Likewise.
+ (call_event::get_desc): Work with new call_event structure.
+ (return_event::get_desc): Likeise.
+ * checker-path.h (call_event::m_src_snode): New field.
+ (call_event::m_dest_snode): New field.
+ (return_event::m_src_snode): New field.
+ (return_event::m_dest_snode): New field.
+ * diagnostic-manager.cc
+ (diagnostic_manager::prune_for_sm_diagnostic)<case EK_CALL_EDGE>:
+ Refactor to work with edges without callgraph edge.
+ (diagnostic_manager::prune_for_sm_diagnostic)<case EK_RETURN_EDGE>:
+ Likewise.
+ * engine.cc (dynamic_call_info_t::update_model): New function.
+ (dynamic_call_info_t::add_events_to_path): New function.
+ (exploded_graph::create_dynamic_call): New function.
+ (exploded_graph::process_node): Work with dynamically discovered calls.
+ * exploded-graph.h (class dynamic_call_info_t): New class.
+ (exploded_graph::create_dynamic_call): New decl.
+ * program-point.cc (program_point::push_to_call_stack): New function.
+ (program_point::pop_from_call_stack): New function.
+ * program-point.h (program_point::push_to_call_stack): New decl.
+ (program_point::pop_from_call_stack): New decl.
+ * program-state.cc (program_state::push_call): New function.
+ (program_state::returning_call): New function.
+ * program-state.h (program_state::push_call): New decl.
+ (program_state::returning_call): New decl.
+ * region-model.cc (region_model::update_for_gcall) New function.
+ (region_model::update_for_return_gcall): New function.
+ (egion_model::update_for_call_superedge): Get the underlying gcall and
+ update for gcall.
+ (region_model::update_for_return_superedge): Likewise.
+ * region-model.h (region_model::update_for_gcall): New decl.
+ (region_model::update_for_return_gcall): New decl.
+ * state-purge.cc (state_purge_per_ssa_name::process_point): Update to
+ work with calls without underlying cgraph edge.
+ * supergraph.cc (supergraph::supergraph) Split snodes at every callsite.
+ * supergraph.h (supernode::get_returning_call) New accessor.
+
2021-08-04 David Malcolm <dmalcolm@redhat.com>
PR analyzer/101570
diff --git a/gcc/analyzer/analysis-plan.cc b/gcc/analyzer/analysis-plan.cc
index 7dfc48e..57a6dcb 100644
--- a/gcc/analyzer/analysis-plan.cc
+++ b/gcc/analyzer/analysis-plan.cc
@@ -109,6 +109,10 @@ analysis_plan::use_summary_p (const cgraph_edge *edge) const
if (!flag_analyzer_call_summaries)
return false;
+ /* Don't use call summaries if there is no callgraph edge */
+ if (!edge || !edge->callee)
+ return false;
+
/* TODO: don't count callsites each time. */
int num_call_sites = 0;
const cgraph_node *callee = edge->callee;
diff --git a/gcc/analyzer/checker-path.cc b/gcc/analyzer/checker-path.cc
index e10c8e2..e132f00 100644
--- a/gcc/analyzer/checker-path.cc
+++ b/gcc/analyzer/checker-path.cc
@@ -614,7 +614,11 @@ call_event::call_event (const exploded_edge &eedge,
location_t loc, tree fndecl, int depth)
: superedge_event (EK_CALL_EDGE, eedge, loc, fndecl, depth)
{
- gcc_assert (eedge.m_sedge->m_kind == SUPEREDGE_CALL);
+ if (eedge.m_sedge)
+ gcc_assert (eedge.m_sedge->m_kind == SUPEREDGE_CALL);
+
+ m_src_snode = eedge.m_src->get_supernode ();
+ m_dest_snode = eedge.m_dest->get_supernode ();
}
/* Implementation of diagnostic_event::get_desc vfunc for
@@ -638,8 +642,8 @@ call_event::get_desc (bool can_colorize) const
label_text custom_desc
= m_pending_diagnostic->describe_call_with_state
(evdesc::call_with_state (can_colorize,
- m_sedge->m_src->m_fun->decl,
- m_sedge->m_dest->m_fun->decl,
+ m_src_snode->m_fun->decl,
+ m_dest_snode->m_fun->decl,
var,
m_critical_state));
if (custom_desc.m_buffer)
@@ -648,8 +652,8 @@ call_event::get_desc (bool can_colorize) const
return make_label_text (can_colorize,
"calling %qE from %qE",
- m_sedge->m_dest->m_fun->decl,
- m_sedge->m_src->m_fun->decl);
+ m_dest_snode->m_fun->decl,
+ m_src_snode->m_fun->decl);
}
/* Override of checker_event::is_call_p for calls. */
@@ -668,7 +672,11 @@ return_event::return_event (const exploded_edge &eedge,
location_t loc, tree fndecl, int depth)
: superedge_event (EK_RETURN_EDGE, eedge, loc, fndecl, depth)
{
- gcc_assert (eedge.m_sedge->m_kind == SUPEREDGE_RETURN);
+ if (eedge.m_sedge)
+ gcc_assert (eedge.m_sedge->m_kind == SUPEREDGE_RETURN);
+
+ m_src_snode = eedge.m_src->get_supernode ();
+ m_dest_snode = eedge.m_dest->get_supernode ();
}
/* Implementation of diagnostic_event::get_desc vfunc for
@@ -694,16 +702,16 @@ return_event::get_desc (bool can_colorize) const
label_text custom_desc
= m_pending_diagnostic->describe_return_of_state
(evdesc::return_of_state (can_colorize,
- m_sedge->m_dest->m_fun->decl,
- m_sedge->m_src->m_fun->decl,
+ m_dest_snode->m_fun->decl,
+ m_src_snode->m_fun->decl,
m_critical_state));
if (custom_desc.m_buffer)
return custom_desc;
}
return make_label_text (can_colorize,
"returning to %qE from %qE",
- m_sedge->m_dest->m_fun->decl,
- m_sedge->m_src->m_fun->decl);
+ m_dest_snode->m_fun->decl,
+ m_src_snode->m_fun->decl);
}
/* Override of checker_event::is_return_p for returns. */
diff --git a/gcc/analyzer/checker-path.h b/gcc/analyzer/checker-path.h
index 1843c4b..27634c2 100644
--- a/gcc/analyzer/checker-path.h
+++ b/gcc/analyzer/checker-path.h
@@ -338,6 +338,9 @@ public:
label_text get_desc (bool can_colorize) const FINAL OVERRIDE;
bool is_call_p () const FINAL OVERRIDE;
+
+ const supernode *m_src_snode;
+ const supernode *m_dest_snode;
};
/* A concrete event subclass for an interprocedural return. */
@@ -351,6 +354,9 @@ public:
label_text get_desc (bool can_colorize) const FINAL OVERRIDE;
bool is_return_p () const FINAL OVERRIDE;
+
+ const supernode *m_src_snode;
+ const supernode *m_dest_snode;
};
/* A concrete event subclass for the start of a consolidated run of CFG
diff --git a/gcc/analyzer/diagnostic-manager.cc b/gcc/analyzer/diagnostic-manager.cc
index ef3df32..06e7510 100644
--- a/gcc/analyzer/diagnostic-manager.cc
+++ b/gcc/analyzer/diagnostic-manager.cc
@@ -2093,18 +2093,13 @@ diagnostic_manager::prune_for_sm_diagnostic (checker_path *path,
case EK_CALL_EDGE:
{
call_event *event = (call_event *)base_event;
- const callgraph_superedge& cg_superedge
- = event->get_callgraph_superedge ();
const region_model *callee_model
= event->m_eedge.m_dest->get_state ().m_region_model;
+ const region_model *caller_model
+ = event->m_eedge.m_src->get_state ().m_region_model;
tree callee_var = callee_model->get_representative_tree (sval);
- /* We could just use caller_model->get_representative_tree (sval);
- to get the caller_var, but for now use
- map_expr_from_callee_to_caller so as to only record critical
- state for parms and the like. */
callsite_expr expr;
- tree caller_var
- = cg_superedge.map_expr_from_callee_to_caller (callee_var, &expr);
+ tree caller_var = caller_model->get_representative_tree (sval);
if (caller_var)
{
if (get_logger ())
@@ -2126,15 +2121,11 @@ diagnostic_manager::prune_for_sm_diagnostic (checker_path *path,
if (sval)
{
return_event *event = (return_event *)base_event;
- const callgraph_superedge& cg_superedge
- = event->get_callgraph_superedge ();
- const region_model *caller_model
- = event->m_eedge.m_dest->get_state ().m_region_model;
- tree caller_var = caller_model->get_representative_tree (sval);
callsite_expr expr;
- tree callee_var
- = cg_superedge.map_expr_from_caller_to_callee (caller_var,
- &expr);
+
+ const region_model *callee_model
+ = event->m_eedge.m_src->get_state ().m_region_model;
+ tree callee_var = callee_model->get_representative_tree (sval);
if (callee_var)
{
if (get_logger ())
diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index ecd4265..461de9c 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -1627,6 +1627,50 @@ exploded_node::dump_succs_and_preds (FILE *outf) const
}
}
+/* class dynamic_call_info_t : public exploded_edge::custom_info_t. */
+
+/* Implementation of exploded_edge::custom_info_t::update_model vfunc
+ for dynamic_call_info_t.
+
+ Update state for the dynamically discorverd calls */
+
+void
+dynamic_call_info_t::update_model (region_model *model,
+ const exploded_edge &eedge)
+{
+ const program_state &dest_state = eedge.m_dest->get_state ();
+ *model = *dest_state.m_region_model;
+}
+
+/* Implementation of exploded_edge::custom_info_t::add_events_to_path vfunc
+ for dynamic_call_info_t. */
+
+void
+dynamic_call_info_t::add_events_to_path (checker_path *emission_path,
+ const exploded_edge &eedge)
+{
+ const exploded_node *src_node = eedge.m_src;
+ const program_point &src_point = src_node->get_point ();
+ const int src_stack_depth = src_point.get_stack_depth ();
+ const exploded_node *dest_node = eedge.m_dest;
+ const program_point &dest_point = dest_node->get_point ();
+ const int dest_stack_depth = dest_point.get_stack_depth ();
+
+ if (m_is_returning_call)
+ emission_path->add_event (new return_event (eedge, (m_dynamic_call
+ ? m_dynamic_call->location
+ : UNKNOWN_LOCATION),
+ dest_point.get_fndecl (),
+ dest_stack_depth));
+ else
+ emission_path->add_event (new call_event (eedge, (m_dynamic_call
+ ? m_dynamic_call->location
+ : UNKNOWN_LOCATION),
+ src_point.get_fndecl (),
+ src_stack_depth));
+
+}
+
/* class rewind_info_t : public exploded_edge::custom_info_t. */
/* Implementation of exploded_edge::custom_info_t::update_model vfunc
@@ -2980,6 +3024,61 @@ state_change_requires_new_enode_p (const program_state &old_state,
return false;
}
+/* Create enodes and eedges for the function calls that doesn't have an
+ underlying call superedge.
+
+ Such case occurs when GCC's middle end didn't know which function to
+ call but the analyzer does (with the help of current state).
+
+ Some example such calls are dynamically dispatched calls to virtual
+ functions or calls that happen via function pointer. */
+
+void
+exploded_graph::create_dynamic_call (const gcall *call,
+ tree fn_decl,
+ exploded_node *node,
+ program_state next_state,
+ program_point &next_point,
+ uncertainty_t *uncertainty,
+ logger *logger)
+{
+ LOG_FUNC (logger);
+
+ const program_point *this_point = &node->get_point ();
+ function *fun = DECL_STRUCT_FUNCTION (fn_decl);
+ if (fun)
+ {
+ const supergraph &sg = this->get_supergraph ();
+ supernode * sn_entry = sg.get_node_for_function_entry (fun);
+ supernode * sn_exit = sg.get_node_for_function_exit (fun);
+
+ program_point new_point
+ = program_point::before_supernode (sn_entry,
+ NULL,
+ this_point->get_call_string ());
+
+ new_point.push_to_call_stack (sn_exit,
+ next_point.get_supernode());
+ next_state.push_call (*this, node, call, uncertainty);
+
+ if (next_state.m_valid)
+ {
+ if (logger)
+ logger->log ("Discovered call to %s [SN: %i -> SN: %i]",
+ function_name(fun),
+ this_point->get_supernode ()->m_index,
+ sn_entry->m_index);
+
+ exploded_node *enode = get_or_create_node (new_point,
+ next_state,
+ node);
+ if (enode)
+ add_edge (node,enode, NULL,
+ new dynamic_call_info_t (call));
+ }
+ }
+}
+
/* The core of exploded_graph::process_worklist (the main analysis loop),
handling one node in the worklist.
@@ -3174,10 +3273,13 @@ exploded_graph::process_node (exploded_node *node)
break;
case PK_AFTER_SUPERNODE:
{
+ bool found_a_superedge = false;
+ bool is_an_exit_block = false;
/* If this is an EXIT BB, detect leaks, and potentially
create a function summary. */
if (point.get_supernode ()->return_p ())
{
+ is_an_exit_block = true;
node->detect_leaks (*this);
if (flag_analyzer_call_summaries
&& point.get_call_string ().empty_p ())
@@ -3205,6 +3307,7 @@ exploded_graph::process_node (exploded_node *node)
superedge *succ;
FOR_EACH_VEC_ELT (point.get_supernode ()->m_succs, i, succ)
{
+ found_a_superedge = true;
if (logger)
logger->log ("considering SN: %i -> SN: %i",
succ->m_src->m_index, succ->m_dest->m_index);
@@ -3214,6 +3317,54 @@ exploded_graph::process_node (exploded_node *node)
point.get_call_string ());
program_state next_state (state);
uncertainty_t uncertainty;
+
+ /* Make use the current state and try to discover and analyse
+ indirect function calls (a call that doesn't have an underlying
+ cgraph edge representing call).
+
+ Some examples of such calls are virtual function calls
+ and calls that happen via a function pointer. */
+ if (succ->m_kind == SUPEREDGE_INTRAPROCEDURAL_CALL
+ && !(succ->get_any_callgraph_edge ()))
+ {
+ const gcall *call
+ = point.get_supernode ()->get_final_call ();
+
+ impl_region_model_context ctxt (*this,
+ node,
+ &state,
+ &next_state,
+ &uncertainty,
+ point.get_stmt());
+
+ region_model *model = state.m_region_model;
+
+ if (tree fn_decl = model->get_fndecl_for_call(call,&ctxt))
+ create_dynamic_call (call,
+ fn_decl,
+ node,
+ next_state,
+ next_point,
+ &uncertainty,
+ logger);
+ else
+ {
+ /* An unknown function was called at this point, in such
+ case, don't terminate the analysis of the current
+ function.
+
+ The analyzer handles calls to unknown functions while
+ analysing the stmt itself, so the the function call
+ must have been handled by the anlyzer till now. */
+ exploded_node *next
+ = get_or_create_node (next_point,
+ next_state,
+ node);
+ if (next)
+ add_edge (node, next, succ);
+ }
+ }
+
if (!node->on_edge (*this, succ, &next_point, &next_state,
&uncertainty))
{
@@ -3227,6 +3378,38 @@ exploded_graph::process_node (exploded_node *node)
if (next)
add_edge (node, next, succ);
}
+
+ /* Return from the calls which doesn't have a return superedge.
+ Such case occurs when GCC's middle end didn't knew which function to
+ call but analyzer did. */
+ if((is_an_exit_block && !found_a_superedge)
+ && (!point.get_call_string ().empty_p ()))
+ {
+ const call_string cs = point.get_call_string ();
+ program_point next_point
+ = program_point::before_supernode (cs.get_caller_node (),
+ NULL,
+ cs);
+ program_state next_state (state);
+ uncertainty_t uncertainty;
+
+ const gcall *call
+ = next_point.get_supernode ()->get_returning_call ();
+
+ if(call)
+ next_state.returning_call (*this, node, call, &uncertainty);
+
+ if (next_state.m_valid)
+ {
+ next_point.pop_from_call_stack ();
+ exploded_node *enode = get_or_create_node (next_point,
+ next_state,
+ node);
+ if (enode)
+ add_edge (node, enode, NULL,
+ new dynamic_call_info_t (call, true));
+ }
+ }
}
break;
}
diff --git a/gcc/analyzer/exploded-graph.h b/gcc/analyzer/exploded-graph.h
index 8f48d8a..192a4b3 100644
--- a/gcc/analyzer/exploded-graph.h
+++ b/gcc/analyzer/exploded-graph.h
@@ -362,6 +362,37 @@ private:
DISABLE_COPY_AND_ASSIGN (exploded_edge);
};
+/* Extra data for an exploded_edge that represents dynamic call info ( calls
+ that doesn't have an underlying superedge representing the call ). */
+
+class dynamic_call_info_t : public exploded_edge::custom_info_t
+{
+public:
+ dynamic_call_info_t (const gcall *dynamic_call,
+ const bool is_returning_call = false)
+ : m_dynamic_call (dynamic_call),
+ m_is_returning_call (is_returning_call)
+ {}
+
+ void print (pretty_printer *pp) FINAL OVERRIDE
+ {
+ if (m_is_returning_call)
+ pp_string (pp, "dynamic_return");
+ else
+ pp_string (pp, "dynamic_call");
+ }
+
+ void update_model (region_model *model,
+ const exploded_edge &eedge) FINAL OVERRIDE;
+
+ void add_events_to_path (checker_path *emission_path,
+ const exploded_edge &eedge) FINAL OVERRIDE;
+private:
+ const gcall *m_dynamic_call;
+ const bool m_is_returning_call;
+};
+
+
/* Extra data for an exploded_edge that represents a rewind from a
longjmp to a setjmp (or from a siglongjmp to a sigsetjmp). */
@@ -785,6 +816,14 @@ public:
bool maybe_process_run_of_before_supernode_enodes (exploded_node *node);
void process_node (exploded_node *node);
+ void create_dynamic_call (const gcall *call,
+ tree fn_decl,
+ exploded_node *node,
+ program_state next_state,
+ program_point &next_point,
+ uncertainty_t *uncertainty,
+ logger *logger);
+
exploded_node *get_or_create_node (const program_point &point,
const program_state &state,
exploded_node *enode_for_diag);
diff --git a/gcc/analyzer/program-point.cc b/gcc/analyzer/program-point.cc
index d9f50da..25d56af 100644
--- a/gcc/analyzer/program-point.cc
+++ b/gcc/analyzer/program-point.cc
@@ -330,6 +330,24 @@ program_point::to_json () const
return point_obj;
}
+/* Update the callstack to represent a call from caller to callee.
+
+ Generally used to push a custom call to a perticular program point
+ where we don't have a superedge representing the call. */
+void
+program_point::push_to_call_stack (const supernode *caller,
+ const supernode *callee)
+{
+ m_call_string.push_call (callee, caller);
+}
+
+/* Pop the topmost call from the current callstack. */
+void
+program_point::pop_from_call_stack ()
+{
+ m_call_string.pop ();
+}
+
/* Generate a hash value for this program_point. */
hashval_t
diff --git a/gcc/analyzer/program-point.h b/gcc/analyzer/program-point.h
index 5f86745..6bae29b 100644
--- a/gcc/analyzer/program-point.h
+++ b/gcc/analyzer/program-point.h
@@ -293,7 +293,8 @@ public:
}
bool on_edge (exploded_graph &eg, const superedge *succ);
-
+ void push_to_call_stack (const supernode *caller, const supernode *callee);
+ void pop_from_call_stack ();
void validate () const;
/* For before_stmt, go to next stmt. */
diff --git a/gcc/analyzer/program-state.cc b/gcc/analyzer/program-state.cc
index 5bb8676..ea53c61 100644
--- a/gcc/analyzer/program-state.cc
+++ b/gcc/analyzer/program-state.cc
@@ -1034,6 +1034,50 @@ program_state::on_edge (exploded_graph &eg,
return true;
}
+/* Update this program_state to reflect a call to function
+ represented by CALL_STMT.
+ currently used only when the call doesn't have a superedge representing
+ the call ( like call via a function pointer ) */
+void
+program_state::push_call (exploded_graph &eg,
+ exploded_node *enode,
+ const gcall *call_stmt,
+ uncertainty_t *uncertainty)
+{
+ /* Update state. */
+ const program_point &point = enode->get_point ();
+ const gimple *last_stmt = point.get_supernode ()->get_last_stmt ();
+
+ impl_region_model_context ctxt (eg, enode,
+ &enode->get_state (),
+ this,
+ uncertainty,
+ last_stmt);
+ m_region_model->update_for_gcall (call_stmt, &ctxt);
+}
+
+/* Update this program_state to reflect a return from function
+ call to which is represented by CALL_STMT.
+ currently used only when the call doesn't have a superedge representing
+ the return */
+void
+program_state::returning_call (exploded_graph &eg,
+ exploded_node *enode,
+ const gcall *call_stmt,
+ uncertainty_t *uncertainty)
+{
+ /* Update state. */
+ const program_point &point = enode->get_point ();
+ const gimple *last_stmt = point.get_supernode ()->get_last_stmt ();
+
+ impl_region_model_context ctxt (eg, enode,
+ &enode->get_state (),
+ this,
+ uncertainty,
+ last_stmt);
+ m_region_model->update_for_return_gcall (call_stmt, &ctxt);
+}
+
/* Generate a simpler version of THIS, discarding state that's no longer
relevant at POINT.
The idea is that we're more likely to be able to consolidate
diff --git a/gcc/analyzer/program-state.h b/gcc/analyzer/program-state.h
index 8dee930..eb49006 100644
--- a/gcc/analyzer/program-state.h
+++ b/gcc/analyzer/program-state.h
@@ -218,6 +218,17 @@ public:
void push_frame (const extrinsic_state &ext_state, function *fun);
function * get_current_function () const;
+ void push_call (exploded_graph &eg,
+ exploded_node *enode,
+ const gcall *call_stmt,
+ uncertainty_t *uncertainty);
+
+ void returning_call (exploded_graph &eg,
+ exploded_node *enode,
+ const gcall *call_stmt,
+ uncertainty_t *uncertainty);
+
+
bool on_edge (exploded_graph &eg,
exploded_node *enode,
const superedge *succ,
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index 58da7e3..822e893 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -1841,6 +1841,11 @@ region_model::get_rvalue_1 (path_var pv, region_model_context *ctxt) const
const region *ref_reg = get_lvalue (pv, ctxt);
return get_store_value (ref_reg, ctxt);
}
+ case OBJ_TYPE_REF:
+ {
+ tree expr = OBJ_TYPE_REF_EXPR (pv.m_tree);
+ return get_rvalue (expr, ctxt);
+ }
}
}
@@ -3172,12 +3177,11 @@ region_model::maybe_update_for_edge (const superedge &edge,
caller's frame. */
void
-region_model::update_for_call_superedge (const call_superedge &call_edge,
- region_model_context *ctxt)
+region_model::update_for_gcall (const gcall *call_stmt,
+ region_model_context *ctxt)
{
/* Build a vec of argument svalues, using the current top
frame for resolving tree expressions. */
- const gcall *call_stmt = call_edge.get_call_stmt ();
auto_vec<const svalue *> arg_svals (gimple_call_num_args (call_stmt));
for (unsigned i = 0; i < gimple_call_num_args (call_stmt); i++)
@@ -3186,33 +3190,58 @@ region_model::update_for_call_superedge (const call_superedge &call_edge,
arg_svals.quick_push (get_rvalue (arg, ctxt));
}
- push_frame (call_edge.get_callee_function (), &arg_svals, ctxt);
+ /* Get the function * from the call. */
+ tree fn_decl = get_fndecl_for_call (call_stmt,ctxt);
+ function *fun = DECL_STRUCT_FUNCTION (fn_decl);
+ push_frame (fun, &arg_svals, ctxt);
}
/* Pop the top-most frame_region from the stack, and copy the return
region's values (if any) into the region for the lvalue of the LHS of
the call (if any). */
+
void
-region_model::update_for_return_superedge (const return_superedge &return_edge,
- region_model_context *ctxt)
+region_model::update_for_return_gcall (const gcall *call_stmt,
+ region_model_context *ctxt)
{
/* Get the region for the result of the call, within the caller frame. */
const region *result_dst_reg = NULL;
- const gcall *call_stmt = return_edge.get_call_stmt ();
tree lhs = gimple_call_lhs (call_stmt);
if (lhs)
{
/* Normally we access the top-level frame, which is:
- path_var (expr, get_stack_depth () - 1)
- whereas here we need the caller frame, hence "- 2" here. */
+ path_var (expr, get_stack_depth () - 1)
+ whereas here we need the caller frame, hence "- 2" here. */
gcc_assert (get_stack_depth () >= 2);
result_dst_reg = get_lvalue (path_var (lhs, get_stack_depth () - 2),
- ctxt);
+ ctxt);
}
pop_frame (result_dst_reg, NULL, ctxt);
}
+/* Extract calling information from the superedge and update the model for the
+ call */
+
+void
+region_model::update_for_call_superedge (const call_superedge &call_edge,
+ region_model_context *ctxt)
+{
+ const gcall *call_stmt = call_edge.get_call_stmt ();
+ update_for_gcall (call_stmt,ctxt);
+}
+
+/* Extract calling information from the return superedge and update the model
+ for the returning call */
+
+void
+region_model::update_for_return_superedge (const return_superedge &return_edge,
+ region_model_context *ctxt)
+{
+ const gcall *call_stmt = return_edge.get_call_stmt ();
+ update_for_return_gcall (call_stmt, ctxt);
+}
+
/* Update this region_model with a summary of the effect of calling
and returning from CG_SEDGE.
diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h
index 30f02a0..e40264e 100644
--- a/gcc/analyzer/region-model.h
+++ b/gcc/analyzer/region-model.h
@@ -608,6 +608,12 @@ class region_model
region_model_context *ctxt,
rejected_constraint **out);
+ void update_for_gcall (const gcall *call_stmt,
+ region_model_context *ctxt);
+
+ void update_for_return_gcall (const gcall *call_stmt,
+ region_model_context *ctxt);
+
const region *push_frame (function *fun, const vec<const svalue *> *arg_sids,
region_model_context *ctxt);
const frame_region *get_current_frame () const { return m_current_frame; }
diff --git a/gcc/analyzer/state-purge.cc b/gcc/analyzer/state-purge.cc
index bfa48a9..8800570 100644
--- a/gcc/analyzer/state-purge.cc
+++ b/gcc/analyzer/state-purge.cc
@@ -383,18 +383,31 @@ state_purge_per_ssa_name::process_point (const function_point &point,
{
/* Add any intraprocedually edge for a call. */
if (snode->m_returning_call)
- {
- cgraph_edge *cedge
+ {
+ gcall *returning_call = snode->m_returning_call;
+ cgraph_edge *cedge
= supergraph_call_edge (snode->m_fun,
- snode->m_returning_call);
- gcc_assert (cedge);
- superedge *sedge
- = map.get_sg ().get_intraprocedural_edge_for_call (cedge);
- gcc_assert (sedge);
- add_to_worklist
- (function_point::after_supernode (sedge->m_src),
- worklist, logger);
- }
+ returning_call);
+ if(cedge)
+ {
+ superedge *sedge
+ = map.get_sg ().get_intraprocedural_edge_for_call (cedge);
+ gcc_assert (sedge);
+ add_to_worklist
+ (function_point::after_supernode (sedge->m_src),
+ worklist, logger);
+ }
+ else
+ {
+ supernode *callernode
+ = map.get_sg ().get_supernode_for_stmt (returning_call);
+
+ gcc_assert (callernode);
+ add_to_worklist
+ (function_point::after_supernode (callernode),
+ worklist, logger);
+ }
+ }
}
}
break;
diff --git a/gcc/analyzer/supergraph.cc b/gcc/analyzer/supergraph.cc
index 1eb2543..66ef765 100644
--- a/gcc/analyzer/supergraph.cc
+++ b/gcc/analyzer/supergraph.cc
@@ -183,11 +183,33 @@ supergraph::supergraph (logger *logger)
m_stmt_to_node_t.put (stmt, node_for_stmts);
m_stmt_uids.make_uid_unique (stmt);
if (cgraph_edge *edge = supergraph_call_edge (fun, stmt))
- {
- m_cgraph_edge_to_caller_prev_node.put(edge, node_for_stmts);
- node_for_stmts = add_node (fun, bb, as_a <gcall *> (stmt), NULL);
- m_cgraph_edge_to_caller_next_node.put (edge, node_for_stmts);
- }
+ {
+ m_cgraph_edge_to_caller_prev_node.put(edge, node_for_stmts);
+ node_for_stmts = add_node (fun, bb, as_a <gcall *> (stmt),
+ NULL);
+ m_cgraph_edge_to_caller_next_node.put (edge, node_for_stmts);
+ }
+ else
+ {
+ // maybe call is via a function pointer
+ if (gcall *call = dyn_cast<gcall *> (stmt))
+ {
+ cgraph_edge *edge
+ = cgraph_node::get (fun->decl)->get_edge (stmt);
+ if (!edge || !edge->callee)
+ {
+ supernode *old_node_for_stmts = node_for_stmts;
+ node_for_stmts = add_node (fun, bb, call, NULL);
+
+ superedge *sedge
+ = new callgraph_superedge (old_node_for_stmts,
+ node_for_stmts,
+ SUPEREDGE_INTRAPROCEDURAL_CALL,
+ NULL);
+ add_edge (sedge);
+ }
+ }
+ }
}
m_bb_to_final_node.put (bb, node_for_stmts);
@@ -1139,6 +1161,17 @@ callgraph_superedge::get_callee_decl () const
return get_callee_function ()->decl;
}
+/* Get the gcall * of this interprocedural call/return edge. */
+
+gcall *
+callgraph_superedge::get_call_stmt () const
+{
+ if (m_cedge)
+ return m_cedge->call_stmt;
+
+ return m_src->get_final_call ();
+}
+
/* Get the calling fndecl at this interprocedural call/return edge. */
tree
diff --git a/gcc/analyzer/supergraph.h b/gcc/analyzer/supergraph.h
index 877958f..335f513 100644
--- a/gcc/analyzer/supergraph.h
+++ b/gcc/analyzer/supergraph.h
@@ -268,6 +268,11 @@ class supernode : public dnode<supergraph_traits>
return i;
}
+ gcall *get_returning_call () const
+ {
+ return m_returning_call;
+ }
+
gimple *get_last_stmt () const
{
if (m_stmts.length () == 0)
@@ -400,7 +405,7 @@ class callgraph_superedge : public superedge
function *get_caller_function () const;
tree get_callee_decl () const;
tree get_caller_decl () const;
- gcall *get_call_stmt () const { return m_cedge->call_stmt; }
+ gcall *get_call_stmt () const;
tree get_arg_for_parm (tree parm, callsite_expr *out) const;
tree get_parm_for_arg (tree arg, callsite_expr *out) const;
tree map_expr_from_caller_to_callee (tree caller_expr,
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 5595994..ab566ba 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,9 @@
+2021-08-18 Jakub Jelinek <jakub@redhat.com>
+
+ * c-pragma.h (enum pragma_kind): Add PRAGMA_OMP_NOTHING.
+ * c-pragma.c (omp_pragmas): Add nothing directive.
+ * c-omp.c (omp_directives): Uncomment nothing directive entry.
+
2021-08-17 Jakub Jelinek <jakub@redhat.com>
PR c++/101539
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index caeac5b..53abd1a 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,32 @@
+2021-08-18 Jakub Jelinek <jakub@redhat.com>
+
+ * c-parser.c (c_parser_omp_nothing): New function.
+ (c_parser_pragma): Handle PRAGMA_OMP_NOTHING.
+
+2021-08-18 Jakub Jelinek <jakub@redhat.com>
+
+ * c-parser.c (c_parser_statement_after_labels): Add restart label
+ near the start of the function. If c_parser_pragma returns false,
+ goto restart.
+ (c_parser_pragma): For PRAGMA_OMP_CANCELLATION_POINT return what
+ c_parser_omp_cancellation_point returned. For PRAGMA_OMP_DECLARE
+ return what c_parser_omp_declare returned. Return true instead of
+ false after emitting errors that the directive is not allowed in
+ pragma_stmt context.
+ (c_parser_omp_ordered): Return true instead of
+ false after emitting errors that the directive is not allowed in
+ pragma_stmt context.
+ (c_parser_omp_target_update): Likewise.
+ (c_parser_omp_target_enter_data, c_parser_omp_target_exit_data):
+ Change return type from tree to bool, return false if the
+ directive should be ignored in pragma_stmt contexts.
+ (c_parser_omp_target): Adjust callers of c_parser_omp_target_*_data,
+ return their result directly.
+ (c_parser_omp_cancellation_point): Change return type from void to
+ bool, return false if the directive should be ignored in pragma_stmt
+ contexts.
+ (c_parser_omp_declare): Likewise.
+
2021-08-17 Jakub Jelinek <jakub@redhat.com>
* c-parser.c (OMP_SCOPE_CLAUSE_MASK): Define.
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index d5f51b1..407f279 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -21710,9 +21710,18 @@ c_parser_omp_requires (c_parser *parser)
error_at (c_parser_peek_token (parser)->location,
"expected %<seq_cst%>, %<relaxed%> or "
"%<acq_rel%>");
- if (c_parser_peek_2nd_token (parser)->type
- == CPP_CLOSE_PAREN)
- c_parser_consume_token (parser);
+ switch (c_parser_peek_token (parser)->type)
+ {
+ case CPP_EOF:
+ case CPP_PRAGMA_EOL:
+ case CPP_CLOSE_PAREN:
+ break;
+ default:
+ if (c_parser_peek_2nd_token (parser)->type
+ == CPP_CLOSE_PAREN)
+ c_parser_consume_token (parser);
+ break;
+ }
}
else
c_parser_consume_token (parser);
diff --git a/gcc/config.gcc b/gcc/config.gcc
index d9bfbfd..eb232df 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -700,7 +700,7 @@ case ${target} in
tm_file="${tm_file} ${cpu_type}/darwin.h"
tm_p_file="${tm_p_file} darwin-protos.h"
target_gtfiles="$target_gtfiles \$(srcdir)/config/darwin.c"
- extra_options="${extra_options} darwin.opt"
+ extra_options="${extra_options} rpath.opt darwin.opt"
c_target_objs="${c_target_objs} darwin-c.o"
cxx_target_objs="${cxx_target_objs} darwin-c.o"
d_target_objs="${d_target_objs} darwin-d.o"
diff --git a/gcc/config/aarch64/arm_neon.h b/gcc/config/aarch64/arm_neon.h
index d8b2970..635a223 100644
--- a/gcc/config/aarch64/arm_neon.h
+++ b/gcc/config/aarch64/arm_neon.h
@@ -20546,8 +20546,8 @@ vld3_lane_f64 (const float64_t * __ptr, float64x1x3_t __b, const int __c)
__o = __builtin_aarch64_set_qregciv2df (__o, (float64x2_t) __temp.val[0], 0);
__o = __builtin_aarch64_set_qregciv2df (__o, (float64x2_t) __temp.val[1], 1);
__o = __builtin_aarch64_set_qregciv2df (__o, (float64x2_t) __temp.val[2], 2);
- __o = __builtin_aarch64_ld3_lanedi (
- (__builtin_aarch64_simd_di *) __ptr, __o, __c);
+ __o = __builtin_aarch64_ld3_lanedf (
+ (__builtin_aarch64_simd_df *) __ptr, __o, __c);
__b.val[0] = (float64x1_t) __builtin_aarch64_get_dregcidi (__o, 0);
__b.val[1] = (float64x1_t) __builtin_aarch64_get_dregcidi (__o, 1);
__b.val[2] = (float64x1_t) __builtin_aarch64_get_dregcidi (__o, 2);
@@ -21077,7 +21077,7 @@ vld4_lane_f32 (const float32_t * __ptr, float32x2x4_t __b, const int __c)
__o = __builtin_aarch64_set_qregxiv4sf (__o, (float32x4_t) __temp.val[1], 1);
__o = __builtin_aarch64_set_qregxiv4sf (__o, (float32x4_t) __temp.val[2], 2);
__o = __builtin_aarch64_set_qregxiv4sf (__o, (float32x4_t) __temp.val[3], 3);
- __o = __builtin_aarch64_ld4_lanev2si (
+ __o = __builtin_aarch64_ld4_lanev2sf (
(__builtin_aarch64_simd_sf *) __ptr, __o, __c);
__b.val[0] = (float32x2_t) __builtin_aarch64_get_dregxidi (__o, 0);
__b.val[1] = (float32x2_t) __builtin_aarch64_get_dregxidi (__o, 1);
@@ -21381,7 +21381,7 @@ vld4q_lane_f64 (const float64_t * __ptr, float64x2x4_t __b, const int __c)
__o = __builtin_aarch64_set_qregxiv4si (__o, (int32x4_t) __b.val[2], 2);
__o = __builtin_aarch64_set_qregxiv4si (__o, (int32x4_t) __b.val[3], 3);
__o = __builtin_aarch64_ld4_lanev2df (
- (__builtin_aarch64_simd_di *) __ptr, __o, __c);
+ (__builtin_aarch64_simd_df *) __ptr, __o, __c);
ret.val[0] = (float64x2_t) __builtin_aarch64_get_qregxiv4si (__o, 0);
ret.val[1] = (float64x2_t) __builtin_aarch64_get_qregxiv4si (__o, 1);
ret.val[2] = (float64x2_t) __builtin_aarch64_get_qregxiv4si (__o, 2);
diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
index 20d6b1e..b1be561 100644
--- a/gcc/config/darwin.h
+++ b/gcc/config/darwin.h
@@ -132,6 +132,7 @@ extern GTY(()) int darwin_ms_struct;
"%{gsplit-dwarf:%ngsplit-dwarf is not supported on this platform} \
%<gsplit-dwarf", \
"%{gused:-g -feliminate-unused-debug-symbols} %<gused", \
+"%{rpath*: -Xlinker -rpath -Xlinker %*}", \
"%{shared:-Zdynamiclib} %<shared", \
"%{static:%{Zdynamic:%e conflicting code gen style switches are used}}",\
"%{y*:%nthe y option is obsolete and ignored} %<y*", \
@@ -238,7 +239,7 @@ extern GTY(()) int darwin_ms_struct;
DARWIN_NOPIE_SPEC \
DARWIN_RDYNAMIC \
DARWIN_NOCOMPACT_UNWIND \
- "}}}}}}} %<pie %<no-pie %<rdynamic %<X "
+ "}}}}}}} %<pie %<no-pie %<rdynamic %<X %<rpath "
/* Spec that controls whether the debug linker is run automatically for
a link step. This needs to be done if there is a source file on the
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 4d4ab6a..46844fa 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -22203,11 +22203,7 @@ ix86_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
case vec_construct:
{
/* N element inserts into SSE vectors. */
- int cost
- = TYPE_VECTOR_SUBPARTS (vectype) * (fp ?
- ix86_cost->sse_op
- : ix86_cost->integer_to_sse);
-
+ int cost = TYPE_VECTOR_SUBPARTS (vectype) * ix86_cost->sse_op;
/* One vinserti128 for combining two SSE vectors for AVX256. */
if (GET_MODE_BITSIZE (mode) == 256)
cost += ix86_vec_cost (mode, ix86_cost->addss);
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index b3e57a8..8aba86d 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -165,7 +165,6 @@ struct processor_costs {
const int xmm_move, ymm_move, /* cost of moving XMM and YMM register. */
zmm_move;
const int sse_to_integer; /* cost of moving SSE register to integer. */
- const int integer_to_sse; /* cost of moving integer to SSE register. */
const int gather_static, gather_per_elt; /* Cost of gather load is computed
as static + per_item * nelts. */
const int scatter_static, scatter_per_elt; /* Cost of gather store is
diff --git a/gcc/config/i386/x86-tune-costs.h b/gcc/config/i386/x86-tune-costs.h
index 67cfa00..ffe810f 100644
--- a/gcc/config/i386/x86-tune-costs.h
+++ b/gcc/config/i386/x86-tune-costs.h
@@ -102,7 +102,6 @@ struct processor_costs ix86_size_cost = {/* costs for tuning for size */
in 128bit, 256bit and 512bit */
3, 3, 3, /* cost of moving XMM,YMM,ZMM register */
3, /* cost of moving SSE register to integer. */
- COSTS_N_BYTES (2), /* cost of moving integer to sse register. */
5, 0, /* Gather load static, per_elt. */
5, 0, /* Gather store static, per_elt. */
0, /* size of l1 cache */
@@ -212,7 +211,6 @@ struct processor_costs i386_cost = { /* 386 specific costs */
{4, 8, 16, 32, 64}, /* cost of unaligned stores. */
2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
3, /* cost of moving SSE register to integer. */
- COSTS_N_INSNS (1), /* cost of moving integer to sse register. */
4, 4, /* Gather load static, per_elt. */
4, 4, /* Gather store static, per_elt. */
0, /* size of l1 cache */
@@ -321,7 +319,6 @@ struct processor_costs i486_cost = { /* 486 specific costs */
{4, 8, 16, 32, 64}, /* cost of unaligned stores. */
2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
3, /* cost of moving SSE register to integer. */
- COSTS_N_INSNS (1), /* cost of moving integer to sse register. */
4, 4, /* Gather load static, per_elt. */
4, 4, /* Gather store static, per_elt. */
4, /* size of l1 cache. 486 has 8kB cache
@@ -432,7 +429,6 @@ struct processor_costs pentium_cost = {
{4, 8, 16, 32, 64}, /* cost of unaligned stores. */
2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
3, /* cost of moving SSE register to integer. */
- COSTS_N_INSNS (1), /* cost of moving integer to sse register. */
4, 4, /* Gather load static, per_elt. */
4, 4, /* Gather store static, per_elt. */
8, /* size of l1 cache. */
@@ -534,7 +530,6 @@ struct processor_costs lakemont_cost = {
{4, 8, 16, 32, 64}, /* cost of unaligned stores. */
2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
3, /* cost of moving SSE register to integer. */
- COSTS_N_INSNS (1), /* cost of moving integer to sse register. */
4, 4, /* Gather load static, per_elt. */
4, 4, /* Gather store static, per_elt. */
8, /* size of l1 cache. */
@@ -651,7 +646,6 @@ struct processor_costs pentiumpro_cost = {
{4, 8, 16, 32, 64}, /* cost of unaligned stores. */
2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
3, /* cost of moving SSE register to integer. */
- COSTS_N_INSNS (1), /* cost of moving integer to sse register. */
4, 4, /* Gather load static, per_elt. */
4, 4, /* Gather store static, per_elt. */
8, /* size of l1 cache. */
@@ -759,7 +753,6 @@ struct processor_costs geode_cost = {
{2, 2, 8, 16, 32}, /* cost of unaligned stores. */
2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
6, /* cost of moving SSE register to integer. */
- COSTS_N_INSNS (1), /* cost of moving integer to sse register. */
2, 2, /* Gather load static, per_elt. */
2, 2, /* Gather store static, per_elt. */
64, /* size of l1 cache. */
@@ -867,7 +860,6 @@ struct processor_costs k6_cost = {
{2, 2, 8, 16, 32}, /* cost of unaligned stores. */
2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
6, /* cost of moving SSE register to integer. */
- COSTS_N_INSNS (1), /* cost of moving integer to sse register. */
2, 2, /* Gather load static, per_elt. */
2, 2, /* Gather store static, per_elt. */
32, /* size of l1 cache. */
@@ -981,7 +973,6 @@ struct processor_costs athlon_cost = {
{4, 4, 10, 10, 20}, /* cost of unaligned stores. */
2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
5, /* cost of moving SSE register to integer. */
- COSTS_N_INSNS (2), /* cost of moving integer to sse register. */
4, 4, /* Gather load static, per_elt. */
4, 4, /* Gather store static, per_elt. */
64, /* size of l1 cache. */
@@ -1097,7 +1088,6 @@ struct processor_costs k8_cost = {
{4, 4, 10, 10, 20}, /* cost of unaligned stores. */
2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
5, /* cost of moving SSE register to integer. */
- COSTS_N_INSNS (2), /* cost of moving integer to sse register. */
4, 4, /* Gather load static, per_elt. */
4, 4, /* Gather store static, per_elt. */
64, /* size of l1 cache. */
@@ -1226,7 +1216,6 @@ struct processor_costs amdfam10_cost = {
{4, 4, 5, 10, 20}, /* cost of unaligned stores. */
2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
3, /* cost of moving SSE register to integer. */
- COSTS_N_INSNS (2), /* cost of moving integer to sse register. */
4, 4, /* Gather load static, per_elt. */
4, 4, /* Gather store static, per_elt. */
64, /* size of l1 cache. */
@@ -1347,7 +1336,6 @@ const struct processor_costs bdver_cost = {
{10, 10, 10, 40, 60}, /* cost of unaligned stores. */
2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
16, /* cost of moving SSE register to integer. */
- COSTS_N_INSNS (2), /* cost of moving integer to sse register. */
12, 12, /* Gather load static, per_elt. */
10, 10, /* Gather store static, per_elt. */
16, /* size of l1 cache. */
@@ -1489,7 +1477,6 @@ struct processor_costs znver1_cost = {
{8, 8, 8, 16, 32}, /* cost of unaligned stores. */
2, 3, 6, /* cost of moving XMM,YMM,ZMM register. */
6, /* cost of moving SSE register to integer. */
- COSTS_N_INSNS (1), /* cost of moving integer to sse register. */
/* VGATHERDPD is 23 uops and throughput is 9, VGATHERDPD is 35 uops,
throughput 12. Approx 9 uops do not depend on vector size and every load
is 7 uops. */
@@ -1646,7 +1633,6 @@ struct processor_costs znver2_cost = {
2, 2, 3, /* cost of moving XMM,YMM,ZMM
register. */
6, /* cost of moving SSE register to integer. */
- COSTS_N_INSNS (1), /* cost of moving integer to sse register. */
/* VGATHERDPD is 23 uops and throughput is 9, VGATHERDPD is 35 uops,
throughput 12. Approx 9 uops do not depend on vector size and every load
is 7 uops. */
@@ -1779,7 +1765,6 @@ struct processor_costs znver3_cost = {
2, 2, 3, /* cost of moving XMM,YMM,ZMM
register. */
6, /* cost of moving SSE register to integer. */
- COSTS_N_INSNS (1), /* cost of moving integer to sse register. */
/* VGATHERDPD is 15 uops and throughput is 4, VGATHERDPS is 23 uops,
throughput 9. Approx 7 uops do not depend on vector size and every load
is 4 uops. */
@@ -1924,7 +1909,6 @@ struct processor_costs skylake_cost = {
{8, 8, 8, 8, 16}, /* cost of unaligned stores. */
2, 2, 4, /* cost of moving XMM,YMM,ZMM register */
6, /* cost of moving SSE register to integer. */
- COSTS_N_INSNS (2)+1, /* cost of moving integer to sse register. */
20, 8, /* Gather load static, per_elt. */
22, 10, /* Gather store static, per_elt. */
64, /* size of l1 cache. */
@@ -2051,7 +2035,6 @@ struct processor_costs icelake_cost = {
{8, 8, 8, 8, 16}, /* cost of unaligned stores. */
2, 2, 4, /* cost of moving XMM,YMM,ZMM register */
6, /* cost of moving SSE register to integer. */
- COSTS_N_INSNS (1), /* cost of moving integer to sse register. */
20, 8, /* Gather load static, per_elt. */
22, 10, /* Gather store static, per_elt. */
64, /* size of l1 cache. */
@@ -2165,7 +2148,6 @@ const struct processor_costs btver1_cost = {
{10, 10, 12, 48, 96}, /* cost of unaligned stores. */
2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
14, /* cost of moving SSE register to integer. */
- COSTS_N_INSNS (1), /* cost of moving integer to sse register. */
10, 10, /* Gather load static, per_elt. */
10, 10, /* Gather store static, per_elt. */
32, /* size of l1 cache. */
@@ -2276,7 +2258,6 @@ const struct processor_costs btver2_cost = {
{10, 10, 12, 48, 96}, /* cost of unaligned stores. */
2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
14, /* cost of moving SSE register to integer. */
- COSTS_N_INSNS (1), /* cost of moving integer to sse register. */
10, 10, /* Gather load static, per_elt. */
10, 10, /* Gather store static, per_elt. */
32, /* size of l1 cache. */
@@ -2386,7 +2367,6 @@ struct processor_costs pentium4_cost = {
{32, 32, 32, 64, 128}, /* cost of unaligned stores. */
12, 24, 48, /* cost of moving XMM,YMM,ZMM register */
20, /* cost of moving SSE register to integer. */
- COSTS_N_INSNS (2), /* cost of moving integer to sse register. */
16, 16, /* Gather load static, per_elt. */
16, 16, /* Gather store static, per_elt. */
8, /* size of l1 cache. */
@@ -2499,7 +2479,6 @@ struct processor_costs nocona_cost = {
{24, 24, 24, 48, 96}, /* cost of unaligned stores. */
6, 12, 24, /* cost of moving XMM,YMM,ZMM register */
20, /* cost of moving SSE register to integer. */
- COSTS_N_INSNS (2), /* cost of moving integer to sse register. */
12, 12, /* Gather load static, per_elt. */
12, 12, /* Gather store static, per_elt. */
8, /* size of l1 cache. */
@@ -2610,7 +2589,6 @@ struct processor_costs atom_cost = {
{16, 16, 16, 32, 64}, /* cost of unaligned stores. */
2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
8, /* cost of moving SSE register to integer. */
- COSTS_N_INSNS (1), /* cost of moving integer to sse register. */
8, 8, /* Gather load static, per_elt. */
8, 8, /* Gather store static, per_elt. */
32, /* size of l1 cache. */
@@ -2721,7 +2699,6 @@ struct processor_costs slm_cost = {
{16, 16, 16, 32, 64}, /* cost of unaligned stores. */
2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
8, /* cost of moving SSE register to integer. */
- COSTS_N_INSNS (1), /* cost of moving integer to sse register. */
8, 8, /* Gather load static, per_elt. */
8, 8, /* Gather store static, per_elt. */
32, /* size of l1 cache. */
@@ -2832,7 +2809,6 @@ struct processor_costs intel_cost = {
{10, 10, 10, 10, 10}, /* cost of unaligned loads. */
2, 2, 2, /* cost of moving XMM,YMM,ZMM register */
4, /* cost of moving SSE register to integer. */
- COSTS_N_INSNS (1), /* cost of moving integer to sse register. */
6, 6, /* Gather load static, per_elt. */
6, 6, /* Gather store static, per_elt. */
32, /* size of l1 cache. */
@@ -2950,7 +2926,6 @@ struct processor_costs generic_cost = {
{6, 6, 6, 10, 15}, /* cost of unaligned storess. */
2, 3, 4, /* cost of moving XMM,YMM,ZMM register */
6, /* cost of moving SSE register to integer. */
- COSTS_N_INSNS (1), /* cost of moving integer to sse register. */
18, 6, /* Gather load static, per_elt. */
18, 6, /* Gather store static, per_elt. */
32, /* size of l1 cache. */
@@ -3074,7 +3049,6 @@ struct processor_costs core_cost = {
{6, 6, 6, 6, 12}, /* cost of unaligned stores. */
2, 2, 4, /* cost of moving XMM,YMM,ZMM register */
2, /* cost of moving SSE register to integer. */
- COSTS_N_INSNS (1), /* cost of moving integer to sse register. */
/* VGATHERDPD is 7 uops, rec throughput 5, while VGATHERDPD is 9 uops,
rec. throughput 6.
So 5 uops statically and one uops per load. */
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index a2d47b3..a06a496 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,42 @@
+2021-08-18 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/101344
+ PR c++/101820
+ * cp-tree.h (CONSTRUCTOR_BRACES_ELIDED_P): Define.
+ * decl.c (reshape_init_r): Set it.
+ * pt.c (collect_ctor_idx_types): Recurse into a sub-CONSTRUCTOR
+ iff CONSTRUCTOR_BRACES_ELIDED_P.
+
+2021-08-18 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/101883
+ * pt.c (convert_template_argument): Pass LOOKUP_IMPLICIT to
+ do_auto_deduction.
+
+2021-08-18 Jakub Jelinek <jakub@redhat.com>
+
+ * parser.c (cp_parser_omp_nothing): New function.
+ (cp_parser_pragma): Handle PRAGMA_OMP_NOTHING.
+
+2021-08-18 Jakub Jelinek <jakub@redhat.com>
+
+ * parser.c (cp_parser_omp_ordered): Return true instead of
+ false after emitting errors that the directive is not allowed in
+ pragma_stmt context.
+ (cp_parser_omp_target_update): Likewise.
+ (cp_parser_omp_cancellation_point): Change return type from void to
+ bool, return false if the directive should be ignored in pragma_stmt
+ contexts.
+ (cp_parser_omp_target_enter_data, cp_parser_omp_target_exit_data):
+ Change return type from tree to bool, return false if the
+ directive should be ignored in pragma_stmt contexts.
+ (cp_parser_omp_target): Adjust callers of cp_parser_omp_target_*_data,
+ return their result directly.
+ (cp_parser_pragma): For PRAGMA_OMP_CANCELLATION_POINT return what
+ cp_parser_omp_cancellation_point returned. Return true instead of
+ false after emitting errors that the directive is not allowed in
+ pragma_stmt context.
+
2021-08-17 Jakub Jelinek <jakub@redhat.com>
PR c++/101539
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 04116fb..0af1a2c 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -45479,9 +45479,18 @@ cp_parser_omp_requires (cp_parser *parser, cp_token *pragma_tok)
error_at (cp_lexer_peek_token (parser->lexer)->location,
"expected %<seq_cst%>, %<relaxed%> or "
"%<acq_rel%>");
- if (cp_lexer_nth_token_is (parser->lexer, 2,
- CPP_CLOSE_PAREN))
- cp_lexer_consume_token (parser->lexer);
+ switch (cp_lexer_peek_token (parser->lexer)->type)
+ {
+ case CPP_EOF:
+ case CPP_PRAGMA_EOL:
+ case CPP_CLOSE_PAREN:
+ break;
+ default:
+ if (cp_lexer_nth_token_is (parser->lexer, 2,
+ CPP_CLOSE_PAREN))
+ cp_lexer_consume_token (parser->lexer);
+ break;
+ }
}
else
cp_lexer_consume_token (parser->lexer);
@@ -45570,7 +45579,7 @@ cp_parser_omp_requires (cp_parser *parser, cp_token *pragma_tok)
static void
cp_parser_omp_nothing (cp_parser *parser, cp_token *pragma_tok)
{
- cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ cp_parser_require_pragma_eol (parser, pragma_tok);
}
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 86a2bda..90a3e53 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,9 @@
+2021-08-18 Tobias Burnus <tobias@codesourcery.com>
+
+ * match.h (gfc_match_omp_nothing): New.
+ * openmp.c (gfc_match_omp_nothing): New.
+ * parse.c (decode_omp_directive): Match 'nothing' directive.
+
2021-08-17 Tobias Burnus <tobias@codesourcery.com>
* dump-parse-tree.c (show_omp_node, show_code_node): Handle
diff --git a/gcc/hash-map-tests.c b/gcc/hash-map-tests.c
index 257f2be..6acc0d4 100644
--- a/gcc/hash-map-tests.c
+++ b/gcc/hash-map-tests.c
@@ -328,11 +328,22 @@ test_map_of_type_with_ctor_and_dtor_expand (bool remove_some_inline)
size_t expand_c_expected = 4;
size_t expand_c = 0;
- void *a[N_elem];
+ /* For stability of this testing, we need all Key values 'k' to produce
+ unique hash values 'Traits::hash (k)', as otherwise the dynamic
+ insert/remove behavior may diverge across different architectures. This
+ is, for example, a problem when using the standard 'pointer_hash::hash',
+ which is simply doing a 'k >> 3' operation, which is fine on 64-bit
+ architectures, but on 32-bit architectures produces the same hash value
+ for subsequent 'a[i] = &a[i]' array elements. Therefore, use an
+ 'int_hash'. */
+
+ int a[N_elem];
for (size_t i = 0; i < N_elem; ++i)
- a[i] = &a[i];
+ a[i] = i;
- typedef hash_map <void *, val_t> Map;
+ const int EMPTY = -1;
+ const int DELETED = -2;
+ typedef hash_map<int_hash<int, EMPTY, DELETED>, val_t> Map;
/* Note that we are starting with a fresh 'Map'. Even if an existing one has
been cleared out completely, there remain 'deleted' elements, and these
diff --git a/gcc/jit/ChangeLog b/gcc/jit/ChangeLog
index 2a2675a..7557e17 100644
--- a/gcc/jit/ChangeLog
+++ b/gcc/jit/ChangeLog
@@ -1,3 +1,8 @@
+2021-08-18 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR jit/100613
+ * Make-lang.in: Provide clauses for Darwin hosts.
+
2021-07-18 Antoni Boucher <bouanto@zoho.com>
PR target/95498
diff --git a/gcc/jit/Make-lang.in b/gcc/jit/Make-lang.in
index 663772a..2a774d7 100644
--- a/gcc/jit/Make-lang.in
+++ b/gcc/jit/Make-lang.in
@@ -53,8 +53,40 @@ jit: $(LIBGCCJIT_FILENAME) \
else
-LIBGCCJIT_LINKER_NAME = libgccjit.so
+ifneq (,$(findstring darwin,$(host)))
+
+LIBGCCJIT_AGE = 1
+LIBGCCJIT_BASENAME = libgccjit
+
+LIBGCCJIT_SONAME = \
+ ${libdir}/$(LIBGCCJIT_BASENAME).$(LIBGCCJIT_VERSION_NUM).dylib
+LIBGCCJIT_FILENAME = $(LIBGCCJIT_BASENAME).$(LIBGCCJIT_VERSION_NUM).dylib
+LIBGCCJIT_LINKER_NAME = $(LIBGCCJIT_BASENAME).dylib
+
+# Conditionalize the use of the LD_VERSION_SCRIPT_OPTION and
+# LD_SONAME_OPTION depending if configure found them, using $(if)
+# We have to define a COMMA here, otherwise the commas in the "true"
+# result are treated as separators by the $(if).
+COMMA := ,
+LIBGCCJIT_VERSION_SCRIPT_OPTION = \
+ $(if $(LD_VERSION_SCRIPT_OPTION),\
+ -Wl$(COMMA)$(LD_VERSION_SCRIPT_OPTION)$(COMMA)$(srcdir)/jit/libgccjit.map)
+
+LIBGCCJIT_SONAME_OPTION = \
+ $(if $(LD_SONAME_OPTION), \
+ -Wl$(COMMA)$(LD_SONAME_OPTION)$(COMMA)$(LIBGCCJIT_SONAME))
+
+LIBGCCJIT_SONAME_SYMLINK = $(LIBGCCJIT_FILENAME)
+LIBGCCJIT_LINKER_NAME_SYMLINK = $(LIBGCCJIT_LINKER_NAME)
+
+jit: $(LIBGCCJIT_FILENAME) \
+ $(LIBGCCJIT_SYMLINK) \
+ $(LIBGCCJIT_LINKER_NAME_SYMLINK) \
+ $(FULL_DRIVER_NAME)
+else
+
+LIBGCCJIT_LINKER_NAME = libgccjit.so
LIBGCCJIT_SONAME = $(LIBGCCJIT_LINKER_NAME).$(LIBGCCJIT_VERSION_NUM)
LIBGCCJIT_FILENAME = \
$(LIBGCCJIT_SONAME).$(LIBGCCJIT_MINOR_NUM).$(LIBGCCJIT_RELEASE_NUM)
@@ -79,6 +111,8 @@ jit: $(LIBGCCJIT_FILENAME) \
$(LIBGCCJIT_SYMLINK) \
$(LIBGCCJIT_LINKER_NAME_SYMLINK) \
$(FULL_DRIVER_NAME)
+
+endif
endif
jit.serial = $(LIBGCCJIT_FILENAME)
@@ -109,9 +143,19 @@ ifneq (,$(findstring mingw,$(target)))
# Create import library
LIBGCCJIT_EXTRA_OPTS = -Wl,--out-implib,$(LIBGCCJIT_IMPORT_LIB)
else
+
+ifneq (,$(findstring darwin,$(host)))
+# TODO : Construct a Darwin-style symbol export file.
+LIBGCCJIT_EXTRA_OPTS = -Wl,-compatibility_version,$(LIBGCCJIT_VERSION_NUM) \
+ -Wl,-current_version,$(LIBGCCJIT_VERSION_NUM).$(LIBGCCJIT_MINOR_NUM).$(LIBGCCJIT_AGE) \
+ $(LIBGCCJIT_VERSION_SCRIPT_OPTION) \
+ $(LIBGCCJIT_SONAME_OPTION)
+else
+
LIBGCCJIT_EXTRA_OPTS = $(LIBGCCJIT_VERSION_SCRIPT_OPTION) \
$(LIBGCCJIT_SONAME_OPTION)
endif
+endif
# We avoid using $(BACKEND) from Makefile.in in order to avoid pulling
# in main.o
@@ -130,8 +174,12 @@ $(LIBGCCJIT_FILENAME): $(jit_OBJS) \
# Create symlinks when not building for Windows
ifeq (,$(findstring mingw,$(target)))
+
+ifeq (,$(findstring darwin,$(host)))
+# but only one level for Darwin, version info is embedded.
$(LIBGCCJIT_SONAME_SYMLINK): $(LIBGCCJIT_FILENAME)
ln -sf $(LIBGCCJIT_FILENAME) $(LIBGCCJIT_SONAME_SYMLINK)
+endif
$(LIBGCCJIT_LINKER_NAME_SYMLINK): $(LIBGCCJIT_SONAME_SYMLINK)
ln -sf $(LIBGCCJIT_SONAME_SYMLINK) $(LIBGCCJIT_LINKER_NAME_SYMLINK)
@@ -319,6 +367,18 @@ jit.install-common: installdirs jit.install-headers
# Install DLL file
$(INSTALL_PROGRAM) $(LIBGCCJIT_FILENAME) \
$(DESTDIR)$(bindir)/$(LIBGCCJIT_FILENAME)
+
+else
+ifneq (,$(findstring darwin,$(host)))
+# but only one level for Darwin
+
+jit.install-common: installdirs jit.install-headers
+ $(INSTALL_PROGRAM) $(LIBGCCJIT_FILENAME) \
+ $(DESTDIR)$(libdir)/$(LIBGCCJIT_FILENAME)
+ ln -sf \
+ $(LIBGCCJIT_SONAME_SYMLINK)\
+ $(DESTDIR)$(libdir)/$(LIBGCCJIT_LINKER_NAME_SYMLINK)
+
else
jit.install-common: installdirs jit.install-headers
$(INSTALL_PROGRAM) $(LIBGCCJIT_FILENAME) \
@@ -330,6 +390,7 @@ jit.install-common: installdirs jit.install-headers
$(LIBGCCJIT_SONAME_SYMLINK)\
$(DESTDIR)$(libdir)/$(LIBGCCJIT_LINKER_NAME_SYMLINK)
endif
+endif
jit.install-man:
diff --git a/gcc/jit/docs/examples/tut04-toyvm/toyvm.c b/gcc/jit/docs/examples/tut04-toyvm/toyvm.c
index e742f34..8ea716e 100644
--- a/gcc/jit/docs/examples/tut04-toyvm/toyvm.c
+++ b/gcc/jit/docs/examples/tut04-toyvm/toyvm.c
@@ -24,7 +24,7 @@ along with GCC; see the file COPYING3. If not see
#include <stdlib.h>
#include <string.h>
-#include <dejagnu.h>
+#include "jit-dejagnu.h"
#include <libgccjit.h>
diff --git a/gcc/jit/docs/examples/tut04-toyvm/toyvm.cc b/gcc/jit/docs/examples/tut04-toyvm/toyvm.cc
index 4b9c765..7e95501 100644
--- a/gcc/jit/docs/examples/tut04-toyvm/toyvm.cc
+++ b/gcc/jit/docs/examples/tut04-toyvm/toyvm.cc
@@ -24,7 +24,7 @@ along with GCC; see the file COPYING3. If not see
#include <stdlib.h>
#include <string.h>
-#include <dejagnu.h>
+#include "jit-dejagnu.h"
#include <libgccjit++.h>
diff --git a/gcc/jit/jit-dejagnu.h b/gcc/jit/jit-dejagnu.h
new file mode 100644
index 0000000..eb53cc9
--- /dev/null
+++ b/gcc/jit/jit-dejagnu.h
@@ -0,0 +1,338 @@
+/* DejaGnu unit testing header.
+ Copyright (C) 2000-2016 Free Software Foundation, Inc.
+
+This file is part of DejaGnu.
+
+DejaGnu is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+
+DejaGnu is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with DejaGnu; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Imported from 1.6.2 with modifications
+ * to avoid and unused symbol in C compilations
+ * avoid wait () clashing with system-provided routines
+ * provide a deterministic last line of output after the totals. */
+
+#ifndef __DEJAGNU_H__
+#define __DEJAGNU_H__
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+/* If you have problems with DejaGnu dropping failed, untested, or
+ * unresolved messages generated by a unit testcase, then: */
+
+/* #define _DEJAGNU_WAIT_ */
+
+#ifdef _DEJAGNU_WAIT_
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#endif
+
+static int passed;
+static int failed;
+static int untest;
+static int unresolve;
+static int xfailed;
+#ifdef __cplusplus
+static int xpassed;
+#endif
+
+static char buffer[512];
+
+#ifdef _DEJAGNU_WAIT_
+void
+dg_wait (void)
+{
+ fd_set rfds;
+ struct timeval tv;
+
+ FD_ZERO (&rfds);
+ tv.tv_sec = 0;
+ tv.tv_usec = 1;
+
+ select (0, &rfds, NULL, NULL, &tv);
+}
+#endif
+
+static inline void
+pass (const char* fmt, ...)
+{
+ va_list ap;
+
+ passed++;
+ va_start (ap, fmt);
+ vsnprintf (buffer, sizeof (buffer), fmt, ap);
+ va_end (ap);
+ printf ("\tPASSED: %s\n", buffer);
+#ifdef _DEJAGNU_WAIT_
+ dg_wait ();
+#endif
+}
+
+static inline void
+xpass (const char* fmt, ...)
+{
+ va_list ap;
+
+ passed++;
+ va_start (ap, fmt);
+ vsnprintf (buffer, sizeof (buffer), fmt, ap);
+ va_end (ap);
+ printf ("\tXPASSED: %s\n", buffer);
+#ifdef _DEJAGNU_WAIT_
+ dg_wait ();
+#endif
+}
+
+static inline void
+fail (const char* fmt, ...)
+{
+ va_list ap;
+
+ failed++;
+ va_start (ap, fmt);
+ vsnprintf (buffer, sizeof (buffer), fmt, ap);
+ va_end (ap);
+ printf ("\tFAILED: %s\n", buffer);
+#ifdef _DEJAGNU_WAIT_
+ dg_wait ();
+#endif
+}
+
+static inline void
+xfail (const char* fmt, ...)
+{
+ va_list ap;
+
+ failed++;
+ va_start (ap, fmt);
+ vsnprintf (buffer, sizeof (buffer), fmt, ap);
+ va_end (ap);
+ printf ("\tXFAILED: %s\n", buffer);
+#ifdef _DEJAGNU_WAIT_
+ dg_wait ();
+#endif
+}
+
+static inline void
+untested (const char* fmt, ...)
+{
+ va_list ap;
+
+ untest++;
+ va_start (ap, fmt);
+ vsnprintf (buffer, sizeof (buffer), fmt, ap);
+ va_end (ap);
+ printf ("\tUNTESTED: %s\n", buffer);
+#ifdef _DEJAGNU_WAIT_
+ dg_wait ();
+#endif
+}
+
+static inline void
+unresolved (const char* fmt, ...)
+{
+ va_list ap;
+
+ unresolve++;
+ va_start (ap, fmt);
+ vsnprintf (buffer, sizeof (buffer), fmt, ap);
+ va_end (ap);
+ printf ("\tUNRESOLVED: %s\n", buffer);
+#ifdef _DEJAGNU_WAIT_
+ dg_wait ();
+#endif
+}
+
+static inline void
+note (const char* fmt, ...)
+{
+ va_list ap;
+
+ va_start (ap, fmt);
+ vsnprintf (buffer, sizeof (buffer), fmt, ap);
+ va_end (ap);
+ printf ("\tNOTE: %s\n", buffer);
+#ifdef _DEJAGNU_WAIT_
+ dg_wait ();
+#endif
+}
+
+static inline void
+totals (void)
+{
+ printf ("\nTotals:\n");
+ printf ("\t#passed:\t\t%d\n", passed);
+ printf ("\t#real failed:\t\t%d\n", failed);
+ if (xfailed)
+ printf ("\t#expected failures:\t\t%d\n", xfailed);
+ if (untest)
+ printf ("\t#untested:\t\t%d\n", untest);
+ if (unresolve)
+ printf ("\t#unresolved:\t\t%d\n", unresolve);
+ printf ("\njit-dg-harness-complete\n");
+}
+
+#ifdef __cplusplus
+
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+#include <string>
+
+const char *outstate_list[] = {
+ "FAILED: ", "PASSED: ", "UNTESTED: ", "UNRESOLVED: ", "XFAILED: ", "XPASSED: "
+};
+
+const char ** outstate = outstate_list;
+
+enum teststate { FAILED, PASSED, UNTESTED, UNRESOLVED, XFAILED, XPASSED} laststate;
+
+class TestState {
+ private:
+ teststate laststate;
+ std::string lastmsg;
+ public:
+ TestState (void)
+ {
+ passed = 0;
+ failed = 0;
+ untest = 0;
+ xpassed = 0;
+ xfailed = 0;
+ unresolve = 0;
+ }
+
+ ~TestState (void) { totals(); }
+
+ void testrun (bool b, std::string s)
+ {
+ if (b)
+ pass (s);
+ else
+ fail (s);
+ }
+
+ void pass (std::string s)
+ {
+ passed++;
+ laststate = PASSED;
+ lastmsg = s;
+ std::cout << "\t" << outstate[PASSED] << s << std::endl;
+ }
+
+ void pass (const char *c)
+ {
+ std::string s = c;
+ pass (s);
+ }
+
+ void xpass (std::string s)
+ {
+ xpassed++;
+ laststate = PASSED;
+ lastmsg = s;
+ std::cout << "\t" << outstate[XPASSED] << s << std::endl;
+ }
+
+ void xpass (const char *c)
+ {
+ std::string s = c;
+ xpass (s);
+ }
+
+ void fail (std::string s)
+ {
+ failed++;
+ laststate = FAILED;
+ lastmsg = s;
+ std::cout << "\t" << outstate[FAILED] << s << std::endl;
+ }
+
+ void fail (const char *c)
+ {
+ std::string s = c;
+ fail (s);
+ }
+
+ void xfail (std::string s)
+ {
+ xfailed++;
+ laststate = XFAILED;
+ lastmsg = s;
+ std::cout << "\t" << outstate[XFAILED] << s << std::endl;
+ }
+
+ void xfail (const char *c)
+ {
+ std::string s = c;
+ xfail (s);
+ }
+
+ void untested (std::string s)
+ {
+ untest++;
+ laststate = UNTESTED;
+ lastmsg = s;
+ std::cout << "\t" << outstate[UNTESTED] << s << std::endl;
+ }
+
+ void untested (const char *c)
+ {
+ std::string s = c;
+ untested (s);
+ }
+
+ void unresolved (std::string s)
+ {
+ unresolve++;
+ laststate = UNRESOLVED;
+ lastmsg = s;
+ std::cout << "\t" << outstate[UNRESOLVED] << s << std::endl;
+ }
+
+ void unresolved (const char *c)
+ {
+ std::string s = c;
+ unresolved (s);
+ }
+
+ void totals (void)
+ {
+ std::cout << "\t#passed:\t\t" << passed << std::endl;
+ std::cout << "\t#real failed:\t\t" << failed << std::endl;
+ if (xfailed)
+ std::cout << "\t#expected failures:\t\t" << xfailed << std::endl;
+ if (xpassed)
+ std::cout << "\t#unexpected passes:\t\t" << xpassed << std::endl;
+ if (untest)
+ std::cout << "\t#untested:\t\t" << untest << std::endl;
+ if (unresolve)
+ std::cout << "\t#unresolved:\t\t" << unresolve << std::endl;
+ std::cout << "\njit-dg-harness-complete" << std::endl;
+ }
+
+ // This is so this class can be printed in an ostream.
+ friend std::ostream & operator << (std::ostream &os, TestState& t)
+ {
+ return os << "\t" << outstate[t.laststate] << t.lastmsg ;
+ }
+
+ int GetState (void) { return laststate; }
+ std::string GetMsg (void) { return lastmsg; }
+};
+
+#endif /* __cplusplus */
+#endif /* _DEJAGNU_H_ */
diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog
index 8adde0d..ea8c88b 100644
--- a/gcc/objc/ChangeLog
+++ b/gcc/objc/ChangeLog
@@ -1,3 +1,13 @@
+2021-08-18 Iain Sandoe <iain@sandoe.co.uk>
+ Matt Jacobson <mhjacobson@me.com>
+
+ PR objc/101666
+ * objc-act.c (objc_build_constructor): Handle empty constructor
+ lists.
+ * objc-next-runtime-abi-02.c (build_v2_objc_method_fixup_call):
+ Handle nil receivers.
+ (build_v2_build_objc_method_call): Likewise.
+
2021-08-17 Matt Jacobson <mhjacobson@me.com>
* objc-next-runtime-abi-02.c
diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
index ec20891..6e4fb62 100644
--- a/gcc/objc/objc-act.c
+++ b/gcc/objc/objc-act.c
@@ -3377,8 +3377,10 @@ objc_build_string_object (tree string)
return addr;
}
-/* Build a static constant CONSTRUCTOR
- with type TYPE and elements ELTS. */
+/* Build a static constant CONSTRUCTOR with type TYPE and elements ELTS.
+ We might be presented with a NULL for ELTS, which means 'empty ctor'
+ which will subsequently be converted into a zero initializer in the
+ middle end. */
tree
objc_build_constructor (tree type, vec<constructor_elt, va_gc> *elts)
@@ -3390,12 +3392,10 @@ objc_build_constructor (tree type, vec<constructor_elt, va_gc> *elts)
TREE_READONLY (constructor) = 1;
#ifdef OBJCPLUS
- /* Adjust for impedance mismatch. We should figure out how to build
- CONSTRUCTORs that consistently please both the C and C++ gods. */
- if (!(*elts)[0].index)
+ /* If we know the initializer, then set the type to what C++ expects. */
+ if (elts && !(*elts)[0].index)
TREE_TYPE (constructor) = init_list_type_node;
#endif
-
return constructor;
}
@@ -9664,7 +9664,9 @@ objc_gimplify_property_ref (tree *expr_p)
call_exp = TREE_OPERAND (getter, 1);
}
#endif
- gcc_assert (TREE_CODE (call_exp) == CALL_EXPR);
+ gcc_checking_assert ((flag_objc_nilcheck
+ && TREE_CODE (call_exp) == COND_EXPR)
+ || TREE_CODE (call_exp) == CALL_EXPR);
*expr_p = call_exp;
}
diff --git a/gcc/objc/objc-next-runtime-abi-02.c b/gcc/objc/objc-next-runtime-abi-02.c
index c552013..0d963e3 100644
--- a/gcc/objc/objc-next-runtime-abi-02.c
+++ b/gcc/objc/objc-next-runtime-abi-02.c
@@ -1675,13 +1675,8 @@ build_v2_objc_method_fixup_call (int super_flag, tree method_prototype,
if (TREE_CODE (ret_type) == RECORD_TYPE
|| TREE_CODE (ret_type) == UNION_TYPE)
- {
- vec<constructor_elt, va_gc> *rtt = NULL;
- /* ??? CHECKME. hmmm..... think we need something more
- here. */
- CONSTRUCTOR_APPEND_ELT (rtt, NULL_TREE, NULL_TREE);
- ftree = objc_build_constructor (ret_type, rtt);
- }
+ /* An empty constructor is zero-filled by the middle end. */
+ ftree = objc_build_constructor (ret_type, NULL);
else
ftree = fold_convert (ret_type, integer_zero_node);
@@ -1694,11 +1689,11 @@ build_v2_objc_method_fixup_call (int super_flag, tree method_prototype,
ifexp, ret_val, ftree,
tf_warning_or_error);
#else
- /* ??? CHECKME. */
ret_val = build_conditional_expr (input_location,
- ifexp, 1,
+ ifexp, 0,
ret_val, NULL_TREE, input_location,
ftree, NULL_TREE, input_location);
+ ret_val = fold_convert (ret_type, ret_val);
#endif
}
return ret_val;
@@ -1790,11 +1785,8 @@ build_v2_build_objc_method_call (int super, tree method_prototype,
if (TREE_CODE (ret_type) == RECORD_TYPE
|| TREE_CODE (ret_type) == UNION_TYPE)
{
- vec<constructor_elt, va_gc> *rtt = NULL;
- /* ??? CHECKME. hmmm..... think we need something more
- here. */
- CONSTRUCTOR_APPEND_ELT (rtt, NULL_TREE, NULL_TREE);
- ftree = objc_build_constructor (ret_type, rtt);
+ /* An empty constructor is zero-filled by the middle end. */
+ ftree = objc_build_constructor (ret_type, NULL);
}
else
ftree = fold_convert (ret_type, integer_zero_node);
@@ -1807,10 +1799,10 @@ build_v2_build_objc_method_call (int super, tree method_prototype,
ret_val = build_conditional_expr (loc, ifexp, ret_val, ftree,
tf_warning_or_error);
#else
- /* ??? CHECKME. */
ret_val = build_conditional_expr (loc, ifexp, 1,
ret_val, NULL_TREE, loc,
ftree, NULL_TREE, loc);
+ ret_val = fold_convert (ret_type, ret_val);
#endif
}
return ret_val;
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 14d8ad2..ebed78f 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -2600,6 +2600,82 @@ widen_leading (scalar_int_mode mode, rtx op0, rtx target, optab unoptab)
return 0;
}
+/* Attempt to emit (clrsb:mode op0) as
+ (plus:mode (clz:mode (xor:mode op0 (ashr:mode op0 (const_int prec-1))))
+ (const_int -1))
+ if CLZ_DEFINED_VALUE_AT_ZERO (mode, val) is 2 and val is prec,
+ or as
+ (clz:mode (ior:mode (xor:mode (ashl:mode op0 (const_int 1))
+ (ashr:mode op0 (const_int prec-1)))
+ (const_int 1)))
+ otherwise. */
+
+static rtx
+expand_clrsb_using_clz (scalar_int_mode mode, rtx op0, rtx target)
+{
+ if (optimize_insn_for_size_p ()
+ || optab_handler (clz_optab, mode) == CODE_FOR_nothing)
+ return NULL_RTX;
+
+ start_sequence ();
+ HOST_WIDE_INT val = 0;
+ if (CLZ_DEFINED_VALUE_AT_ZERO (mode, val) != 2
+ || val != GET_MODE_PRECISION (mode))
+ val = 0;
+ else
+ val = 1;
+
+ rtx temp2 = op0;
+ if (!val)
+ {
+ temp2 = expand_binop (mode, ashl_optab, op0, const1_rtx,
+ NULL_RTX, 0, OPTAB_DIRECT);
+ if (!temp2)
+ {
+ fail:
+ end_sequence ();
+ return NULL_RTX;
+ }
+ }
+
+ rtx temp = expand_binop (mode, ashr_optab, op0,
+ GEN_INT (GET_MODE_PRECISION (mode) - 1),
+ NULL_RTX, 0, OPTAB_DIRECT);
+ if (!temp)
+ goto fail;
+
+ temp = expand_binop (mode, xor_optab, temp2, temp, NULL_RTX, 0,
+ OPTAB_DIRECT);
+ if (!temp)
+ goto fail;
+
+ if (!val)
+ {
+ temp = expand_binop (mode, ior_optab, temp, const1_rtx,
+ NULL_RTX, 0, OPTAB_DIRECT);
+ if (!temp)
+ goto fail;
+ }
+ temp = expand_unop_direct (mode, clz_optab, temp, val ? NULL_RTX : target,
+ true);
+ if (!temp)
+ goto fail;
+ if (val)
+ {
+ temp = expand_binop (mode, add_optab, temp, constm1_rtx,
+ target, 0, OPTAB_DIRECT);
+ if (!temp)
+ goto fail;
+ }
+
+ rtx_insn *seq = get_insns ();
+ end_sequence ();
+
+ add_equal_note (seq, temp, CLRSB, op0, NULL_RTX, mode);
+ emit_insn (seq);
+ return temp;
+}
+
/* Try calculating clz of a double-word quantity as two clz's of word-sized
quantities, choosing which based on whether the high word is nonzero. */
static rtx
@@ -3171,6 +3247,9 @@ expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target,
temp = widen_leading (int_mode, op0, target, unoptab);
if (temp)
return temp;
+ temp = expand_clrsb_using_clz (int_mode, op0, target);
+ if (temp)
+ return temp;
}
goto try_libcall;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e5dcd4a..57b714a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,77 @@
+2021-08-18 Tobias Burnus <tobias@codesourcery.com>
+
+ PR testsuite/101963
+ * gfortran.dg/nothing-1.f90: Moved to ...
+ * gfortran.dg/gomp/nothing-1.f90: ... here.
+ * gfortran.dg/nothing-2.f90: Moved to ...
+ * gfortran.dg/gomp/nothing-2.f90: ... here;
+ avoid $ issue in $OMP in dg-error.
+
+2021-08-18 Iain Sandoe <iain@sandoe.co.uk>
+ Matt Jacobson <mhjacobson@me.com>
+
+ PR objc/101666
+ * obj-c++.dg/pr101666-0.mm: New test.
+ * obj-c++.dg/pr101666-1.mm: New test.
+ * obj-c++.dg/pr101666.inc: New.
+ * objc.dg/pr101666-0.m: New test.
+ * objc.dg/pr101666-1.m: New test.
+ * objc.dg/pr101666.inc: New.
+
+2021-08-18 Ankur Saini <arsenic@sourceware.org>
+
+ PR analyzer/97114
+ * g++.dg/analyzer/vfunc-2.C: New test.
+ * g++.dg/analyzer/vfunc-3.C: New test.
+ * g++.dg/analyzer/vfunc-4.C: New test.
+ * g++.dg/analyzer/vfunc-5.C: New test.
+
+2021-08-18 Ankur Saini <arsenic@sourceware.org>
+
+ PR analyzer/100546
+ * gcc.dg/analyzer/function-ptr-4.c: New test.
+ * gcc.dg/analyzer/pr100546.c: New test.
+
+2021-08-18 Tobias Burnus <tobias@codesourcery.com>
+
+ * gfortran.dg/nothing-1.f90: New test.
+ * gfortran.dg/nothing-2.f90: New test.
+
+2021-08-18 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/101344
+ PR c++/101820
+ * g++.dg/cpp2a/class-deduction-aggr11.C: New test.
+ * g++.dg/cpp2a/class-deduction-aggr12.C: New test.
+
+2021-08-18 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/101883
+ * g++.dg/cpp2a/nontype-class49.C: New test.
+
+2021-08-18 Jakub Jelinek <jakub@redhat.com>
+
+ * c-c++-common/gomp/nothing-1.c: New test.
+ * g++.dg/gomp/attrs-1.C (bar): Add nothing directive test.
+ * g++.dg/gomp/attrs-2.C (bar): Likewise.
+ * g++.dg/gomp/attrs-9.C: Likewise.
+
+2021-08-18 Jakub Jelinek <jakub@redhat.com>
+
+ * c-c++-common/gomp/pr63326.c: Don't expect extra "before" errors
+ in C++.
+ * g++.dg/gomp/attrs-7.C: Don't expect one extra error.
+ * g++.dg/gomp/barrier-2.C: Likewise.
+ * gcc.dg/gomp/declare-simd-5.c: Likewise.
+ * gcc.dg/gomp/barrier-2.c: Likewise.
+ * gcc.dg/gomp/declare-variant-2.c: Likewise.
+
+2021-08-18 liuhongt <hongtao.liu@intel.com>
+
+ PR target/97147
+ * gcc.target/i386/pr54400.c: Adjust testcase.
+ * gcc.target/i386/pr94147.c: New test.
+
2021-08-17 Martin Sebor <msebor@redhat.com>
PR middle-end/101854
diff --git a/gcc/testsuite/c-c++-common/gomp/nothing-2.c b/gcc/testsuite/c-c++-common/gomp/nothing-2.c
new file mode 100644
index 0000000..a152035
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/nothing-2.c
@@ -0,0 +1,2 @@
+#pragma omp nothing , /* { dg-error "expected end of line before" } */
+#pragma omp nothing asdf /* { dg-error "expected end of line before" } */
diff --git a/gcc/testsuite/c-c++-common/gomp/requires-3.c b/gcc/testsuite/c-c++-common/gomp/requires-3.c
index e5a6cbb..0e55b66 100644
--- a/gcc/testsuite/c-c++-common/gomp/requires-3.c
+++ b/gcc/testsuite/c-c++-common/gomp/requires-3.c
@@ -1,3 +1,5 @@
#pragma omp requires atomic_default_mem_order(acquire) /* { dg-error "expected 'seq_cst', 'relaxed' or 'acq_rel'" } */
#pragma omp requires atomic_default_mem_order(release) /* { dg-error "expected 'seq_cst', 'relaxed' or 'acq_rel'" } */
#pragma omp requires atomic_default_mem_order(foobar) /* { dg-error "expected 'seq_cst', 'relaxed' or 'acq_rel'" } */
+#pragma omp requires atomic_default_mem_order ( /* { dg-error "expected 'seq_cst', 'relaxed' or 'acq_rel'" } */
+/* { dg-error "expected '\\\)' before end of line" "" { target *-*-* } .-1 } */
diff --git a/gcc/testsuite/g++.dg/analyzer/vfunc-2.C b/gcc/testsuite/g++.dg/analyzer/vfunc-2.C
new file mode 100644
index 0000000..46b68e5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/analyzer/vfunc-2.C
@@ -0,0 +1,44 @@
+#include <cstdio>
+#include <cstdlib>
+
+struct A
+{
+ int m_data;
+ A() {m_data = 0;}
+ virtual int deallocate (void)
+ {
+ return 42;
+ }
+};
+
+struct B: public A
+{
+ int *ptr;
+ int m_data_b;
+ B() {m_data_b = 0;}
+ void allocate ()
+ {
+ ptr = (int*)malloc(sizeof(int));
+ }
+ int deallocate (void)
+ {
+ free(ptr);
+ return 0;
+ }
+};
+
+void foo(A *a_ptr)
+{
+ printf("%d\n",a_ptr->deallocate());
+}
+
+void test()
+{
+ B b;
+ A a, *aptr;
+ aptr = &b;
+ b.allocate();
+ foo(aptr);
+ aptr = &a;
+ foo(aptr);
+}
diff --git a/gcc/testsuite/g++.dg/analyzer/vfunc-3.C b/gcc/testsuite/g++.dg/analyzer/vfunc-3.C
new file mode 100644
index 0000000..03d3cdc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/analyzer/vfunc-3.C
@@ -0,0 +1,32 @@
+#include <cstdlib>
+
+struct A
+{
+ virtual int foo (void)
+ {
+ return 42;
+ }
+};
+
+struct B: public A
+{
+ int *ptr;
+ void alloc ()
+ {
+ ptr = (int*)malloc(sizeof(int));
+ }
+ int foo (void)
+ {
+ free(ptr); /* { dg-warning "double-'free' of 'b.B::ptr'" } */
+ return 0;
+ }
+};
+
+int test ()
+{
+ struct B b, *bptr=&b;
+ b.alloc ();
+ bptr->foo (); /* { dg-message "\\(6\\) calling 'B::foo' from 'test'" "event 6" } */
+ /* { dg-message "\\(9\\) returning to 'test' from 'B::foo'" "event 9" { target *-*-* } .-1 } */
+ return bptr->foo ();
+}
diff --git a/gcc/testsuite/g++.dg/analyzer/vfunc-4.C b/gcc/testsuite/g++.dg/analyzer/vfunc-4.C
new file mode 100644
index 0000000..9751084
--- /dev/null
+++ b/gcc/testsuite/g++.dg/analyzer/vfunc-4.C
@@ -0,0 +1,28 @@
+#include "../../gcc.dg/analyzer/analyzer-decls.h"
+
+struct A
+{
+ int m_data;
+ virtual char foo ()
+ {
+ return 'A';
+ }
+};
+
+struct B: public A
+{
+ int m_data_b;
+ char foo ()
+ {
+ return 'B';
+ }
+};
+
+void test()
+{
+ A a, *a_ptr = &a;
+ B b;
+ __analyzer_eval (a_ptr->foo () == 'A'); /* { dg-warning "TRUE" } */
+ a_ptr = &b;
+ __analyzer_eval (a_ptr->foo () == 'B'); /* { dg-warning "TRUE" } */
+}
diff --git a/gcc/testsuite/g++.dg/analyzer/vfunc-5.C b/gcc/testsuite/g++.dg/analyzer/vfunc-5.C
new file mode 100644
index 0000000..2af8465
--- /dev/null
+++ b/gcc/testsuite/g++.dg/analyzer/vfunc-5.C
@@ -0,0 +1,103 @@
+/* { dg-additional-options "-fdiagnostics-show-line-numbers -fdiagnostics-path-format=inline-events -fanalyzer-checker=malloc -fdiagnostics-show-caret" } */
+/* { dg-enable-nn-line-numbers "" } */
+
+#include <cstdlib>
+
+struct Base
+{
+ virtual void allocate ();
+ virtual void deallocate ();
+};
+
+struct Derived: public Base
+{
+ int *ptr;
+ void allocate ()
+ {
+ ptr = (int*)malloc(sizeof(int));
+ }
+ void deallocate ()
+ {
+ free(ptr);
+ }
+};
+
+void test()
+{
+ Derived D;
+ Base B, *base_ptr;
+ base_ptr = &D;
+
+ D.allocate();
+ base_ptr->deallocate();
+ int n = *D.ptr; /* { dg-warning "use after 'free' of 'D.Derived::ptr'" } */
+}
+
+/* use after 'free' */
+/* { dg-begin-multiline-output "" }
+ NN | int n = *D.ptr;
+ | ^
+ 'void test()': events 1-2
+ |
+ | NN | void test()
+ | | ^~~~
+ | | |
+ | | (1) entry to 'test'
+ |......
+ | NN | D.allocate();
+ | | ~~~~~~~~~~~~
+ | | |
+ | | (2) calling 'Derived::allocate' from 'test'
+ |
+ +--> 'virtual void Derived::allocate()': events 3-4
+ |
+ | NN | void allocate ()
+ | | ^~~~~~~~
+ | | |
+ | | (3) entry to 'Derived::allocate'
+ | NN | {
+ | NN | ptr = (int*)malloc(sizeof(int));
+ | | ~~~~~~~~~~~~~~~~~~~
+ | | |
+ | | (4) allocated here
+ |
+ <------+
+ |
+ 'void test()': events 5-6
+ |
+ | NN | D.allocate();
+ | | ~~~~~~~~~~^~
+ | | |
+ | | (5) returning to 'test' from 'Derived::allocate'
+ | NN | base_ptr->deallocate();
+ | | ~~~~~~~~~~~~~~~~~~~~~~
+ | | |
+ | | (6) calling 'Derived::deallocate' from 'test'
+ |
+ +--> 'virtual void Derived::deallocate()': events 7-8
+ |
+ | NN | void deallocate ()
+ | | ^~~~~~~~~~
+ | | |
+ | | (7) entry to 'Derived::deallocate'
+ | NN | {
+ | NN | free(ptr);
+ | | ~~~~~~~~~
+ | | |
+ | | (8) freed here
+ |
+ <------+
+ |
+ 'void test()': events 9-10
+ |
+ | NN | base_ptr->deallocate();
+ | | ~~~~~~~~~~~~~~~~~~~~^~
+ | | |
+ | | (9) returning to 'test' from 'Derived::deallocate'
+ | NN | int n = *D.ptr;
+ | | ~
+ | | |
+ | | (10) use after 'free' of 'D.Derived::ptr'; freed at (8)
+ |
+ { dg-end-multiline-output "" } */
+
diff --git a/gcc/testsuite/gcc.dg/analyzer/function-ptr-4.c b/gcc/testsuite/gcc.dg/analyzer/function-ptr-4.c
new file mode 100644
index 0000000..016351a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/function-ptr-4.c
@@ -0,0 +1,24 @@
+/* Test to see if the analyzer detect and analyze calls via
+ function pointers or not. */
+
+#include <stdlib.h>
+
+void fun(int *int_ptr)
+{
+ free(int_ptr); /* { dg-warning "double-'free' of 'int_ptr'" } */
+}
+
+void single_call()
+{
+ int *int_ptr = (int*)malloc(sizeof(int));
+ void (*fun_ptr)(int *) = &fun;
+ (*fun_ptr)(int_ptr);
+}
+
+void double_call()
+{
+ int *int_ptr = (int*)malloc(sizeof(int));
+ void (*fun_ptr)(int *) = &fun;
+ (*fun_ptr)(int_ptr); /* { dg-message "calling 'fun' from 'double_call'" } */
+ (*fun_ptr)(int_ptr);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr100546.c b/gcc/testsuite/gcc.dg/analyzer/pr100546.c
new file mode 100644
index 0000000..3349d40
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr100546.c
@@ -0,0 +1,17 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+static void noReturn(const char *str) __attribute__((noreturn));
+static void noReturn(const char *str) {
+ printf("%s\n", str);
+ exit(1);
+}
+
+void (*noReturnPtr)(const char *str) = &noReturn;
+
+int main(int argc, char **argv) {
+ char *str = 0;
+ if (!str)
+ noReturnPtr(__FILE__);
+ return printf("%c\n", *str);
+}
diff --git a/gcc/testsuite/gcc.dg/pr78213.c b/gcc/testsuite/gcc.dg/pr78213.c
index 40dd3c8..04bf038 100644
--- a/gcc/testsuite/gcc.dg/pr78213.c
+++ b/gcc/testsuite/gcc.dg/pr78213.c
@@ -8,4 +8,5 @@ int i;
while (i--)
bar();
}
-/* { dg-message "fself\-test: " "-fself-test" { target *-*-* } 0 } */
+
+/* { dg-regexp {^-fself-test: [0-9]+ pass\(es\) in [.0-9]+ seconds$|.*: note: self-tests are not enabled in this build$} } */
diff --git a/gcc/testsuite/gcc.target/i386/pr101950-1.c b/gcc/testsuite/gcc.target/i386/pr101950-1.c
new file mode 100644
index 0000000..cc98064
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr101950-1.c
@@ -0,0 +1,20 @@
+/* PR middle-end/101950 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mno-lzcnt" } */
+/* { dg-final { scan-assembler-not "call\[^\n\r]*__clrsb.i2" } } */
+/* { dg-final { scan-assembler-times "\tbsr\[ql]\t" 2 } } */
+/* { dg-final { scan-assembler-times "\txor\[ql]\t" 4 } } */
+/* { dg-final { scan-assembler-times "\tor\[ql]\t" 2 } } */
+/* { dg-final { scan-assembler-times "\tsar\[ql]\t|\tcltd" 2 } } */
+
+int
+foo (long x)
+{
+ return __builtin_clrsbl (x);
+}
+
+int
+bar (int x)
+{
+ return __builtin_clrsb (x);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr101950-2.c b/gcc/testsuite/gcc.target/i386/pr101950-2.c
new file mode 100644
index 0000000..896f1b4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr101950-2.c
@@ -0,0 +1,19 @@
+/* PR middle-end/101950 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mlzcnt" } */
+/* { dg-final { scan-assembler-not "call\[^\n\r]*__clrsb.i2" } } */
+/* { dg-final { scan-assembler-times "\tlzcnt\[ql]\t" 2 } } */
+/* { dg-final { scan-assembler-times "\txor\[ql]\t" 2 } } */
+/* { dg-final { scan-assembler-times "\tsar\[ql]\t|\tcltd" 2 } } */
+
+int
+foo (long x)
+{
+ return __builtin_clrsbl (x);
+}
+
+int
+bar (int x)
+{
+ return __builtin_clrsb (x);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr99881.c b/gcc/testsuite/gcc.target/i386/pr99881.c
index a1ec1d1b..3e087eb 100644
--- a/gcc/testsuite/gcc.target/i386/pr99881.c
+++ b/gcc/testsuite/gcc.target/i386/pr99881.c
@@ -1,7 +1,7 @@
/* PR target/99881. */
/* { dg-do compile { target { ! ia32 } } } */
/* { dg-options "-Ofast -march=skylake" } */
-/* { dg-final { scan-assembler-not "xmm\[0-9\]" } } */
+/* { dg-final { scan-assembler-not "xmm\[0-9\]" { xfail *-*-* } } } */
void
foo (int* __restrict a, int n, int c)
diff --git a/gcc/testsuite/gfortran.dg/nothing-1.f90 b/gcc/testsuite/gfortran.dg/gomp/nothing-1.f90
index 9fc24d4..9fc24d4 100644
--- a/gcc/testsuite/gfortran.dg/nothing-1.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/nothing-1.f90
diff --git a/gcc/testsuite/gfortran.dg/nothing-2.f90 b/gcc/testsuite/gfortran.dg/gomp/nothing-2.f90
index 74a4a5a..554d4ef 100644
--- a/gcc/testsuite/gfortran.dg/nothing-2.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/nothing-2.f90
@@ -3,5 +3,5 @@ pure subroutine foo
end subroutine
subroutine bar
- !$omp nothing foo ! { dg-error "Unexpected junk after $OMP NOTHING statement" }
+ !$omp nothing foo ! { dg-error "Unexpected junk after .OMP NOTHING statement" }
end
diff --git a/gcc/testsuite/jit.dg/harness.h b/gcc/testsuite/jit.dg/harness.h
index 6b59fb5..0dc5ed1 100644
--- a/gcc/testsuite/jit.dg/harness.h
+++ b/gcc/testsuite/jit.dg/harness.h
@@ -27,7 +27,7 @@
#define note dejagnu_note
#endif
-#include <dejagnu.h>
+#include "jit-dejagnu.h"
#ifdef MAKE_DEJAGNU_H_THREADSAFE
#undef pass
diff --git a/gcc/testsuite/jit.dg/jit.exp b/gcc/testsuite/jit.dg/jit.exp
index 9af87f9..005ba01 100644
--- a/gcc/testsuite/jit.dg/jit.exp
+++ b/gcc/testsuite/jit.dg/jit.exp
@@ -914,9 +914,14 @@ proc jit-verify-executable { args } {
jit-run-executable $output_filename ${dg-output-text}
}
+set DEFAULT_CFLAGS "-I$srcdir/../jit -lgccjit -g -Wall -Werror"
+
# We need to link with --export-dynamic for test-calling-external-function.c
# so that the JIT-built code can call into functions from the main program.
-set DEFAULT_CFLAGS "-I$srcdir/../jit -lgccjit -g -Wall -Werror -Wl,--export-dynamic"
+
+if { [check_effective_target_rdynamic] } {
+ set DEFAULT_CFLAGS "$DEFAULT_CFLAGS -rdynamic"
+}
# Main loop. This will invoke jig-dg-test on each test-*.c file.
dg-runtest $tests "" $DEFAULT_CFLAGS
diff --git a/gcc/testsuite/jit.dg/test-asm.c b/gcc/testsuite/jit.dg/test-asm.c
index 35a9f9d..43255dc 100644
--- a/gcc/testsuite/jit.dg/test-asm.c
+++ b/gcc/testsuite/jit.dg/test-asm.c
@@ -438,6 +438,18 @@ verify_code_4 (gcc_jit_context *ctxt, gcc_jit_result *result)
static void
create_test_i386_basic_asm_5 (gcc_jit_context *ctxt)
{
+#if __APPLE__
+ /* Darwin's assemblers do not support push/pop section, do not use .type
+ and external symbols should use __USER_LABEL_PREFIX__. */
+ gcc_jit_context_add_top_level_asm (ctxt, NULL,
+ "\t.text\n"
+ "\t.globl _add_asm\n"
+ "_add_asm:\n"
+ "\tmovq %rdi, %rax\n"
+ "\tadd %rsi, %rax\n"
+ "\tret\n"
+ "\t# some asm here\n");
+#else
/* Quote from here in docs/topics/asm.rst: example 5: jit. */
gcc_jit_context_add_top_level_asm (ctxt, NULL,
"\t.pushsection .text\n"
@@ -450,6 +462,7 @@ create_test_i386_basic_asm_5 (gcc_jit_context *ctxt)
"\t# some asm here\n"
"\t.popsection\n");
/* Quote up to here in docs/topics/asm.rst: example 5: jit. */
+#endif
}
static void
diff --git a/gcc/testsuite/jit.dg/test-asm.cc b/gcc/testsuite/jit.dg/test-asm.cc
index be487e3..a3b45da 100644
--- a/gcc/testsuite/jit.dg/test-asm.cc
+++ b/gcc/testsuite/jit.dg/test-asm.cc
@@ -400,6 +400,17 @@ static void
create_test_i386_basic_asm_5 (gcc_jit_context *c_ctxt)
{
gccjit::context ctxt (c_ctxt);
+#if __APPLE__
+ /* Darwin's assemblers do not support push/pop section, do not use .type
+ and external symbols should use __USER_LABEL_PREFIX__. */
+ ctxt.add_top_level_asm ("\t.text\n"
+ "\t.globl _add_asm\n"
+ "_add_asm:\n"
+ "\tmovq %rdi, %rax\n"
+ "\tadd %rsi, %rax\n"
+ "\tret\n"
+ "\t# some asm here\n");
+#else
/* Quote from here in docs/cp/topics/asm.rst: example 5: jit. */
ctxt.add_top_level_asm ("\t.pushsection .text\n"
"\t.globl add_asm\n"
@@ -411,6 +422,7 @@ create_test_i386_basic_asm_5 (gcc_jit_context *c_ctxt)
"\t# some asm here\n"
"\t.popsection\n");
/* Quote up to here in docs/cp/topics/asm.rst: example 5: jit. */
+#endif
}
static void
diff --git a/gcc/testsuite/obj-c++.dg/pr101666-0.mm b/gcc/testsuite/obj-c++.dg/pr101666-0.mm
new file mode 100644
index 0000000..5f87f60
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/pr101666-0.mm
@@ -0,0 +1,7 @@
+/* { dg-do run } */
+/* { dg-skip-if "NeXT only" { *-*-* } { "-fgnu-runtime" } { "" } } */
+/* { dg-skip-if "ABI 2 only" { *-*-* && { ! objc2 } } { "*" } { "" } } */
+/* { dg-additional-options "-fobjc-nilcheck -Wno-objc-root-class" } */
+
+#include "pr101666.inc"
+
diff --git a/gcc/testsuite/obj-c++.dg/pr101666-1.mm b/gcc/testsuite/obj-c++.dg/pr101666-1.mm
new file mode 100644
index 0000000..41ef370
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/pr101666-1.mm
@@ -0,0 +1,10 @@
+/* Later versions of Darwin can compile for 10.5, but cannot link it so we
+ can only run this test up to 10.13. */
+/* { dg-do compile { target *-*-darwin* } } */
+/* { dg-do run { target *-*-darwin[89]* *-*-darwin1[0-7]* } } */
+/* { dg-skip-if "NeXT only" { *-*-* } { "-fgnu-runtime" } { "" } } */
+/* { dg-skip-if "ABI 2 only" { *-*-* && { ! objc2 } } { "*" } { "" } } */
+/* { dg-additional-options "-fobjc-nilcheck -mmacosx-version-min=10.5 " } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
+
+#include "pr101666.inc"
diff --git a/gcc/testsuite/obj-c++.dg/pr101666.inc b/gcc/testsuite/obj-c++.dg/pr101666.inc
new file mode 100644
index 0000000..e81e1be
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/pr101666.inc
@@ -0,0 +1,29 @@
+#include <cstdlib>
+struct point { double x, y, z; };
+
+@interface Foo
+- (struct point)bar;
+- (struct point)baz;
+@end
+
+@implementation Foo
+- (struct point)bar { struct point q = { 1.0, 2.0, 3.0 }; return q; };
+- (struct point)baz { struct point q = { 4.0, 5.0, 6.0 }; return q; };
+@end
+
+/* Cases where a check for nil should be inserted by the compiler, when
+ -fobjc-nilcheck is in force. We should not attempt the calls, and the
+ result should be 0-filled. */
+
+Foo *f;
+
+int main(void) {
+ struct point p = [f bar];
+ if (p.x != 0.0 || p.y != 0.0 || p.z != 0.0)
+ abort ();
+ id nilobj = (id)0;
+ p = [nilobj baz];
+ if (p.x != 0.0 || p.y != 0.0 || p.z != 0.0)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/pr101666-0.m b/gcc/testsuite/objc.dg/pr101666-0.m
new file mode 100644
index 0000000..5f87f60
--- /dev/null
+++ b/gcc/testsuite/objc.dg/pr101666-0.m
@@ -0,0 +1,7 @@
+/* { dg-do run } */
+/* { dg-skip-if "NeXT only" { *-*-* } { "-fgnu-runtime" } { "" } } */
+/* { dg-skip-if "ABI 2 only" { *-*-* && { ! objc2 } } { "*" } { "" } } */
+/* { dg-additional-options "-fobjc-nilcheck -Wno-objc-root-class" } */
+
+#include "pr101666.inc"
+
diff --git a/gcc/testsuite/objc.dg/pr101666-1.m b/gcc/testsuite/objc.dg/pr101666-1.m
new file mode 100644
index 0000000..41ef370
--- /dev/null
+++ b/gcc/testsuite/objc.dg/pr101666-1.m
@@ -0,0 +1,10 @@
+/* Later versions of Darwin can compile for 10.5, but cannot link it so we
+ can only run this test up to 10.13. */
+/* { dg-do compile { target *-*-darwin* } } */
+/* { dg-do run { target *-*-darwin[89]* *-*-darwin1[0-7]* } } */
+/* { dg-skip-if "NeXT only" { *-*-* } { "-fgnu-runtime" } { "" } } */
+/* { dg-skip-if "ABI 2 only" { *-*-* && { ! objc2 } } { "*" } { "" } } */
+/* { dg-additional-options "-fobjc-nilcheck -mmacosx-version-min=10.5 " } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
+
+#include "pr101666.inc"
diff --git a/gcc/testsuite/objc.dg/pr101666.inc b/gcc/testsuite/objc.dg/pr101666.inc
new file mode 100644
index 0000000..f1dddca
--- /dev/null
+++ b/gcc/testsuite/objc.dg/pr101666.inc
@@ -0,0 +1,29 @@
+#include <stdlib.h>
+struct point { double x, y, z; };
+
+@interface Foo
+- (struct point)bar;
+- (struct point)baz;
+@end
+
+@implementation Foo
+- (struct point)bar { struct point q = { 1.0, 2.0, 3.0 }; return q; };
+- (struct point)baz { struct point q = { 4.0, 5.0, 6.0 }; return q; };
+@end
+
+/* Cases where a check for nil should be inserted by the compiler, when
+ -fobjc-nilcheck is in force. We should not attempt the calls, and the
+ result should be 0-filled. */
+
+Foo *f;
+
+int main(void) {
+ struct point p = [f bar];
+ if (p.x != 0.0 || p.y != 0.0 || p.z != 0.0)
+ abort ();
+ id nilobj = (id)0;
+ p = [nilobj baz];
+ if (p.x != 0.0 || p.y != 0.0 || p.z != 0.0)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index df8323c..b45776e 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,3 +1,23 @@
+2021-08-18 Tobias Burnus <tobias@codesourcery.com>
+
+ * omp_lib.f90.in (omp_alloc, omp_free, omp_target_alloc,
+ omp_target_free. omp_target_is_present, omp_target_memcpy,
+ omp_target_memcpy_rect, omp_target_associate_ptr,
+ omp_target_disassociate_ptr): Add interface.
+ * omp_lib.h.in (omp_alloc, omp_free, omp_target_alloc,
+ omp_target_free. omp_target_is_present, omp_target_memcpy,
+ omp_target_memcpy_rect, omp_target_associate_ptr,
+ omp_target_disassociate_ptr): Add interface.
+ * testsuite/libgomp.fortran/alloc-1.F90: Remove local
+ interface block for omp_alloc + omp_free.
+ * testsuite/libgomp.fortran/alloc-4.f90: Likewise.
+ * testsuite/libgomp.fortran/refcount-1.f90: New test.
+ * testsuite/libgomp.fortran/target-12.f90: New test.
+
+2021-08-18 Jakub Jelinek <jakub@redhat.com>
+
+ * testsuite/libgomp.c-c++-common/nothing-1.c: New test.
+
2021-08-17 Tobias Burnus <tobias@codesourcery.com>
* testsuite/libgomp.fortran/scope-1.f90: New test.
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index 0143d42..f6ffd16 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,8 @@
+2021-08-18 Iain Sandoe <iain@sandoe.co.uk>
+
+ * simple-object-mach-o.c (simple_object_mach_o_write_segment):
+ Arrange to swap the LTO index tables where needed.
+
2021-06-30 Gerald Pfeifer <gerald@pfeifer.com>
* make-temp-file.c (usrtmp): Remove.
diff --git a/libiberty/simple-object-mach-o.c b/libiberty/simple-object-mach-o.c
index aa5e095..72b69d1 100644
--- a/libiberty/simple-object-mach-o.c
+++ b/libiberty/simple-object-mach-o.c
@@ -1225,6 +1225,11 @@ simple_object_mach_o_write_segment (simple_object_write *sobj, int descriptor,
index[4 * i] -= index[0];
index[0] = 0;
+ /* Swap the indices, if required. */
+
+ for (i = 0; i < (nsects_in * 4); ++i)
+ set_32 (&index[i], index[i]);
+
sechdr_offset += sechdrsize;
/* Write out the section names.
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 8f01da8..e64efaf 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,65 @@
+2021-08-18 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/bits/unique_ptr.h (default_delete): Add @since tag.
+ (unique_ptr, unique_ptr<T[]>): Likewise. Improve @brief.
+ (make_unique, make_unique_for_overwrite): Likewise. Add @tparam,
+ @param, and @returns.
+ (_MakeUniq): Move to __detail namespace. Add alias template
+ helpers.
+
+2021-08-18 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/bits/stl_function.h: Improve doxygen comments.
+
+2021-08-18 Jonathan Wakely <jwakely@redhat.com>
+
+ * doc/doxygen/user.cfg.in (PREDEFINED): Enable doxygen
+ processing for C++20 components and components that depend on
+ compiler features.
+ * include/bits/stl_algo.h (random_shuffle): Use @deprecated.
+ * include/std/type_traits: Improve doxygen comments for C++20
+ traits.
+
+2021-08-18 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/ext/type_traits.h (__promote_2, __promote_3)
+ (__promote_4): Redfine as alias templates using __promoted_t.
+ * include/std/complex (__promote_2): Remove partial
+ specializations for std::complex.
+
+2021-08-18 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/bits/stl_algo.h (min(initializer_list<T>))
+ (min(initializer_list<T>, Compare)): Call __min_element directly to
+ avoid redundant debug checks for valid ranges.
+ (max(initializer_list<T>), max(initializer_list<T>, Compare)):
+ Likewise, for __max_element.
+ (minmax(initializer_list<T>), minmax(initializer_list<T>, Compare)):
+ Likewise, for __minmax_element.
+
+2021-08-18 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/debug/deque (deque(size_type, const T&, const A&)):
+ Prevent class template argument deduction and replace with a
+ deduction guide.
+ * include/debug/forward_list (forward_list(size_type, const T&, const A&)):
+ Likewise.
+ * include/debug/list (list(size_type, const T&, const A&)):
+ Likewise.
+ * include/debug/vector (vector(size_type, const T&, const A&)):
+ Likewise.
+
+2021-08-18 Jonathan Wakely <jwakely@redhat.com>
+
+ * python/libstdcxx/v6/printers.py (StdBitReferencePrinter): Use
+ 'std::vector<bool>::reference' as type name, not _Bit_reference.
+ (build_libstdcxx_dictionary): Register printers for vector<bool>
+ types in debug mode too.
+ * testsuite/libstdc++-prettyprinters/simple.cc: Adjust expected
+ output for invalid _Bit_reference. Use vector<bool>::reference
+ instead of _Bit_reference.
+ * testsuite/libstdc++-prettyprinters/simple11.cc: Likewise.
+
2021-08-17 Thomas Schwinge <thomas@codesourcery.com>
* testsuite/lib/libstdc++.exp: Avoid illegal argument to verbose,
diff --git a/libstdc++-v3/doc/doxygen/user.cfg.in b/libstdc++-v3/doc/doxygen/user.cfg.in
index 349b9ec..ab9e552 100644
--- a/libstdc++-v3/doc/doxygen/user.cfg.in
+++ b/libstdc++-v3/doc/doxygen/user.cfg.in
@@ -2384,7 +2384,7 @@ INCLUDE_FILE_PATTERNS =
# recursively expanded use the := operator instead of the = operator.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-PREDEFINED = __cplusplus=201703L \
+PREDEFINED = __cplusplus=202002L \
__GTHREADS \
_GLIBCXX_HAS_GTHREADS \
_GLIBCXX_HAVE_TLS \
@@ -2427,6 +2427,13 @@ PREDEFINED = __cplusplus=201703L \
__cpp_exceptions \
__cpp_rtti \
__cpp_inline_variables \
+ __cpp_constexpr_dynamic_alloc \
+ __cpp_aligned_new \
+ __cpp_sized_deallocation \
+ __cpp_concepts=209900 \
+ __cpp_deduction_guides=209900 \
+ __cpp_impl_three_way_comparison=209900 \
+ __cpp_impl_coroutine \
ATOMIC_INT_LOCK_FREE=2 \
PB_DS_DATA_TRUE_INDICATOR \
PB_DS_STATIC_ASSERT=// \
@@ -2448,8 +2455,15 @@ PREDEFINED = __cplusplus=201703L \
"_GLIBCXX20_DEPRECATED(E)= " \
"_GLIBCXX20_DEPRECATED(E)= " \
_GLIBCXX17_INLINE=inline \
- _GLIBCXX_CHRONO_INT64_T=int64_t \
- _GLIBCXX_DEFAULT_ABI_TAG
+ _GLIBCXX_CHRONO_INT64_T=int64_t \
+ _GLIBCXX_DEFAULT_ABI_TAG \
+ _GLIBCXX_USE_DEPRECATED \
+ _GLIBCXX_HOSTED \
+ "__has_builtin(x)=1" \
+ _GLIBCXX_HAVE_BUILTIN_HAS_UNIQ_OBJ_REP \
+ _GLIBCXX_HAVE_BUILTIN_IS_AGGREGATE \
+ _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED \
+ _GLIBCXX_HAVE_BUILTIN_LAUNDER \
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
# tag can be used to specify a list of macro names that should be expanded. The
diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h
index 54ad383..5d12972 100644
--- a/libstdc++-v3/include/bits/stl_algo.h
+++ b/libstdc++-v3/include/bits/stl_algo.h
@@ -3445,38 +3445,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__gnu_cxx::__ops::__iter_comp_iter(__comp));
}
- // N2722 + DR 915.
- template<typename _Tp>
- _GLIBCXX14_CONSTEXPR
- inline _Tp
- min(initializer_list<_Tp> __l)
- { return *std::min_element(__l.begin(), __l.end()); }
-
- template<typename _Tp, typename _Compare>
- _GLIBCXX14_CONSTEXPR
- inline _Tp
- min(initializer_list<_Tp> __l, _Compare __comp)
- { return *std::min_element(__l.begin(), __l.end(), __comp); }
-
- template<typename _Tp>
- _GLIBCXX14_CONSTEXPR
- inline _Tp
- max(initializer_list<_Tp> __l)
- { return *std::max_element(__l.begin(), __l.end()); }
-
- template<typename _Tp, typename _Compare>
- _GLIBCXX14_CONSTEXPR
- inline _Tp
- max(initializer_list<_Tp> __l, _Compare __comp)
- { return *std::max_element(__l.begin(), __l.end(), __comp); }
-
template<typename _Tp>
_GLIBCXX14_CONSTEXPR
inline pair<_Tp, _Tp>
minmax(initializer_list<_Tp> __l)
{
+ __glibcxx_requires_irreflexive(__l.begin(), __l.end());
pair<const _Tp*, const _Tp*> __p =
- std::minmax_element(__l.begin(), __l.end());
+ std::__minmax_element(__l.begin(), __l.end(),
+ __gnu_cxx::__ops::__iter_less_iter());
return std::make_pair(*__p.first, *__p.second);
}
@@ -3485,8 +3462,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
inline pair<_Tp, _Tp>
minmax(initializer_list<_Tp> __l, _Compare __comp)
{
+ __glibcxx_requires_irreflexive_pred(__l.begin(), __l.end(), __comp);
pair<const _Tp*, const _Tp*> __p =
- std::minmax_element(__l.begin(), __l.end(), __comp);
+ std::__minmax_element(__l.begin(), __l.end(),
+ __gnu_cxx::__ops::__iter_comp_iter(__comp));
return std::make_pair(*__p.first, *__p.second);
}
@@ -3793,7 +3772,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
std::iter_swap(__i, __first + __d(__g, __p_type(0, __i - __first)));
}
-#endif
+#endif // USE C99_STDINT
#endif // C++11
@@ -4566,6 +4545,10 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
* Reorder the elements in the range @p [__first,__last) using a random
* distribution, so that every possible ordering of the sequence is
* equally likely.
+ *
+ * @deprecated
+ * Since C++14 `std::random_shuffle` is not part of the C++ standard.
+ * Use `std::shuffle` instead, which was introduced in C++11.
*/
template<typename _RandomAccessIterator>
_GLIBCXX14_DEPRECATED_SUGGEST("std::shuffle")
@@ -4602,6 +4585,10 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
* provide a random distribution. Calling @p __rand(N) for a positive
* integer @p N should return a randomly chosen integer from the
* range [0,N).
+ *
+ * @deprecated
+ * Since C++14 `std::random_shuffle` is not part of the C++ standard.
+ * Use `std::shuffle` instead, which was introduced in C++11.
*/
template<typename _RandomAccessIterator, typename _RandomNumberGenerator>
_GLIBCXX14_DEPRECATED_SUGGEST("std::shuffle")
@@ -5746,6 +5733,49 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
__gnu_cxx::__ops::__iter_comp_iter(__comp));
}
+#if __cplusplus >= 201103L
+ // N2722 + DR 915.
+ template<typename _Tp>
+ _GLIBCXX14_CONSTEXPR
+ inline _Tp
+ min(initializer_list<_Tp> __l)
+ {
+ __glibcxx_requires_irreflexive(__l.begin(), __l.end());
+ return *_GLIBCXX_STD_A::__min_element(__l.begin(), __l.end(),
+ __gnu_cxx::__ops::__iter_less_iter());
+ }
+
+ template<typename _Tp, typename _Compare>
+ _GLIBCXX14_CONSTEXPR
+ inline _Tp
+ min(initializer_list<_Tp> __l, _Compare __comp)
+ {
+ __glibcxx_requires_irreflexive_pred(__l.begin(), __l.end(), __comp);
+ return *_GLIBCXX_STD_A::__min_element(__l.begin(), __l.end(),
+ __gnu_cxx::__ops::__iter_comp_iter(__comp));
+ }
+
+ template<typename _Tp>
+ _GLIBCXX14_CONSTEXPR
+ inline _Tp
+ max(initializer_list<_Tp> __l)
+ {
+ __glibcxx_requires_irreflexive(__l.begin(), __l.end());
+ return *_GLIBCXX_STD_A::__max_element(__l.begin(), __l.end(),
+ __gnu_cxx::__ops::__iter_less_iter());
+ }
+
+ template<typename _Tp, typename _Compare>
+ _GLIBCXX14_CONSTEXPR
+ inline _Tp
+ max(initializer_list<_Tp> __l, _Compare __comp)
+ {
+ __glibcxx_requires_irreflexive_pred(__l.begin(), __l.end(), __comp);
+ return *_GLIBCXX_STD_A::__max_element(__l.begin(), __l.end(),
+ __gnu_cxx::__ops::__iter_comp_iter(__comp));
+ }
+#endif // C++11
+
#if __cplusplus >= 201402L
/// Reservoir sampling algorithm.
template<typename _InputIterator, typename _RandomAccessIterator,
diff --git a/libstdc++-v3/include/bits/stl_function.h b/libstdc++-v3/include/bits/stl_function.h
index 073018d..5de8c32 100644
--- a/libstdc++-v3/include/bits/stl_function.h
+++ b/libstdc++-v3/include/bits/stl_function.h
@@ -66,40 +66,52 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// 20.3.1 base classes
/** @defgroup functors Function Objects
- * @ingroup utilities
+ * @ingroup utilities
*
- * Function objects, or @e functors, are objects with an @c operator()
+ * Function objects, or _functors_, are objects with an `operator()`
* defined and accessible. They can be passed as arguments to algorithm
* templates and used in place of a function pointer. Not only is the
* resulting expressiveness of the library increased, but the generated
* code can be more efficient than what you might write by hand. When we
- * refer to @a functors, then, generally we include function pointers in
+ * refer to _functors_, then, generally we include function pointers in
* the description as well.
*
* Often, functors are only created as temporaries passed to algorithm
* calls, rather than being created as named variables.
*
* Two examples taken from the standard itself follow. To perform a
- * by-element addition of two vectors @c a and @c b containing @c double,
- * and put the result in @c a, use
+ * by-element addition of two vectors `a` and `b` containing `double`,
+ * and put the result in `a`, use
* \code
* transform (a.begin(), a.end(), b.begin(), a.begin(), plus<double>());
* \endcode
- * To negate every element in @c a, use
+ * To negate every element in `a`, use
* \code
* transform(a.begin(), a.end(), a.begin(), negate<double>());
* \endcode
- * The addition and negation functions will be inlined directly.
+ * The addition and negation functions will usually be inlined directly.
*
- * The standard functors are derived from structs named @c unary_function
- * and @c binary_function. These two classes contain nothing but typedefs,
- * to aid in generic (template) programming. If you write your own
- * functors, you might consider doing the same.
+ * An _adaptable function object_ is one which provides nested typedefs
+ * `result_type` and either `argument_type` (for a unary function) or
+ * `first_argument_type` and `second_argument_type` (for a binary function).
+ * Those typedefs are used by function object adaptors such as `bind2nd`.
+ * The standard library provides two class templates, `unary_function` and
+ * `binary_function`, which define those typedefs and so can be used as
+ * base classes of adaptable function objects.
+ *
+ * Since C++11 the use of function object adaptors has been superseded by
+ * more powerful tools such as lambda expressions, `function<>`, and more
+ * powerful type deduction (using `auto` and `decltype`). The helpers for
+ * defining adaptable function objects are deprecated since C++11, and no
+ * longer part of the standard library since C++17. However, they are still
+ * defined and used by libstdc++ after C++17, as a conforming extension.
*
* @{
*/
+
/**
- * This is one of the @link functors functor base classes@endlink.
+ * Helper for defining adaptable unary function objects.
+ * @deprecated Deprecated in C++11, no longer in the standard since C++17.
*/
template<typename _Arg, typename _Result>
struct unary_function
@@ -112,7 +124,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
};
/**
- * This is one of the @link functors functor base classes@endlink.
+ * Helper for defining adaptable binary function objects.
+ * @deprecated Deprecated in C++11, no longer in the standard since C++17.
*/
template<typename _Arg1, typename _Arg2, typename _Result>
struct binary_function
@@ -129,12 +142,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/** @} */
// 20.3.2 arithmetic
- /** @defgroup arithmetic_functors Arithmetic Classes
- * @ingroup functors
+
+ /** @defgroup arithmetic_functors Arithmetic Function Object Classes
+ * @ingroup functors
*
- * Because basic math often needs to be done during an algorithm,
- * the library provides functors for those operations. See the
- * documentation for @link functors the base classes@endlink
+ * The library provides function objects for basic arithmetic operations.
+ * See the documentation for @link functors function objects @endlink
* for examples of their use.
*
* @{
@@ -166,6 +179,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp>
struct plus : public binary_function<_Tp, _Tp, _Tp>
{
+ /// Returns the sum
_GLIBCXX14_CONSTEXPR
_Tp
operator()(const _Tp& __x, const _Tp& __y) const
@@ -319,7 +333,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// 20.3.3 comparisons
/** @defgroup comparison_functors Comparison Classes
- * @ingroup functors
+ * @ingroup functors
*
* The library provides six wrapper functors for all the basic comparisons
* in C++, like @c <.
@@ -763,10 +777,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// 20.3.4 logical operations
/** @defgroup logical_functors Boolean Operations Classes
- * @ingroup functors
+ * @ingroup functors
*
- * Here are wrapper functors for Boolean operations: @c &&, @c ||,
- * and @c !.
+ * The library provides function objects for the logical operations:
+ * `&&`, `||`, and `!`.
*
* @{
*/
@@ -971,30 +985,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// 20.3.5 negators
/** @defgroup negators Negators
- * @ingroup functors
+ * @ingroup functors
*
- * The functions @c not1 and @c not2 each take a predicate functor
- * and return an instance of @c unary_negate or
- * @c binary_negate, respectively. These classes are functors whose
- * @c operator() performs the stored predicate function and then returns
- * the negation of the result.
+ * The function templates `not1` and `not2` are function object adaptors,
+ * which each take a predicate functor and wrap it in an instance of
+ * `unary_negate` or `binary_negate`, respectively. Those classes are
+ * functors whose `operator()` evaluates the wrapped predicate function
+ * and then returns the negation of the result.
*
* For example, given a vector of integers and a trivial predicate,
* \code
* struct IntGreaterThanThree
* : public std::unary_function<int, bool>
* {
- * bool operator() (int x) { return x > 3; }
+ * bool operator() (int x) const { return x > 3; }
* };
*
* std::find_if (v.begin(), v.end(), not1(IntGreaterThanThree()));
* \endcode
- * The call to @c find_if will locate the first index (i) of @c v for which
- * <code>!(v[i] > 3)</code> is true.
+ * The call to `find_if` will locate the first index (i) of `v` for which
+ * `!(v[i] > 3)` is true.
*
* The not1/unary_negate combination works on predicates taking a single
- * argument. The not2/binary_negate combination works on predicates which
- * take two arguments.
+ * argument. The not2/binary_negate combination works on predicates taking
+ * two arguments.
+ *
+ * @deprecated Deprecated in C++17, no longer in the standard since C++20.
+ * Use `not_fn` instead.
*
* @{
*/
@@ -1055,24 +1072,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// 20.3.7 adaptors pointers functions
/** @defgroup pointer_adaptors Adaptors for pointers to functions
- * @ingroup functors
+ * @ingroup functors
*
* The advantage of function objects over pointers to functions is that
* the objects in the standard library declare nested typedefs describing
- * their argument and result types with uniform names (e.g., @c result_type
- * from the base classes @c unary_function and @c binary_function).
+ * their argument and result types with uniform names (e.g., `result_type`
+ * from the base classes `unary_function` and `binary_function`).
* Sometimes those typedefs are required, not just optional.
*
* Adaptors are provided to turn pointers to unary (single-argument) and
* binary (double-argument) functions into function objects. The
- * long-winded functor @c pointer_to_unary_function is constructed with a
- * function pointer @c f, and its @c operator() called with argument @c x
- * returns @c f(x). The functor @c pointer_to_binary_function does the same
- * thing, but with a double-argument @c f and @c operator().
+ * long-winded functor `pointer_to_unary_function` is constructed with a
+ * function pointer `f`, and its `operator()` called with argument `x`
+ * returns `f(x)`. The functor `pointer_to_binary_function` does the same
+ * thing, but with a double-argument `f` and `operator()`.
*
- * The function @c ptr_fun takes a pointer-to-function @c f and constructs
+ * The function `ptr_fun` takes a pointer-to-function `f` and constructs
* an instance of the appropriate functor.
*
+ * @deprecated Deprecated in C++11, no longer in the standard since C++17.
+ *
* @{
*/
/// One of the @link pointer_adaptors adaptors for function pointers@endlink.
@@ -1182,8 +1201,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
};
// 20.3.8 adaptors pointers members
- /** @defgroup memory_adaptors Adaptors for pointers to members
- * @ingroup functors
+ /** @defgroup ptrmem_adaptors Adaptors for pointers to members
+ * @ingroup functors
*
* There are a total of 8 = 2^3 function objects in this family.
* (1) Member functions taking no arguments vs member functions taking
@@ -1192,13 +1211,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* (3) Const vs non-const member function.
*
* All of this complexity is in the function objects themselves. You can
- * ignore it by using the helper function mem_fun and mem_fun_ref,
+ * ignore it by using the helper function `mem_fun` and `mem_fun_ref`,
* which create whichever type of adaptor is appropriate.
*
+ * @deprecated Deprecated in C++11, no longer in the standard since C++17.
+ * Use `mem_fn` instead.
+ *
* @{
*/
- /// One of the @link memory_adaptors adaptors for member
- /// pointers@endlink.
+ /// One of the @link ptrmem_adaptors adaptors for member pointers@endlink.
template<typename _Ret, typename _Tp>
class mem_fun_t : public unary_function<_Tp*, _Ret>
{
@@ -1215,8 +1236,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Ret (_Tp::*_M_f)();
};
- /// One of the @link memory_adaptors adaptors for member
- /// pointers@endlink.
+ /// One of the @link ptrmem_adaptors adaptors for member pointers@endlink.
template<typename _Ret, typename _Tp>
class const_mem_fun_t : public unary_function<const _Tp*, _Ret>
{
@@ -1233,8 +1253,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Ret (_Tp::*_M_f)() const;
};
- /// One of the @link memory_adaptors adaptors for member
- /// pointers@endlink.
+ /// One of the @link ptrmem_adaptors adaptors for member pointers@endlink.
template<typename _Ret, typename _Tp>
class mem_fun_ref_t : public unary_function<_Tp, _Ret>
{
@@ -1251,8 +1270,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Ret (_Tp::*_M_f)();
};
- /// One of the @link memory_adaptors adaptors for member
- /// pointers@endlink.
+ /// One of the @link ptrmem_adaptors adaptors for member pointers@endlink.
template<typename _Ret, typename _Tp>
class const_mem_fun_ref_t : public unary_function<_Tp, _Ret>
{
@@ -1269,8 +1287,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Ret (_Tp::*_M_f)() const;
};
- /// One of the @link memory_adaptors adaptors for member
- /// pointers@endlink.
+ /// One of the @link ptrmem_adaptors adaptors for member pointers@endlink.
template<typename _Ret, typename _Tp, typename _Arg>
class mem_fun1_t : public binary_function<_Tp*, _Arg, _Ret>
{
@@ -1287,8 +1304,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Ret (_Tp::*_M_f)(_Arg);
};
- /// One of the @link memory_adaptors adaptors for member
- /// pointers@endlink.
+ /// One of the @link ptrmem_adaptors adaptors for member pointers@endlink.
template<typename _Ret, typename _Tp, typename _Arg>
class const_mem_fun1_t : public binary_function<const _Tp*, _Arg, _Ret>
{
@@ -1305,8 +1321,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Ret (_Tp::*_M_f)(_Arg) const;
};
- /// One of the @link memory_adaptors adaptors for member
- /// pointers@endlink.
+ /// One of the @link ptrmem_adaptors adaptors for member pointers@endlink.
template<typename _Ret, typename _Tp, typename _Arg>
class mem_fun1_ref_t : public binary_function<_Tp, _Arg, _Ret>
{
@@ -1323,8 +1338,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Ret (_Tp::*_M_f)(_Arg);
};
- /// One of the @link memory_adaptors adaptors for member
- /// pointers@endlink.
+ /// One of the @link ptrmem_adaptors adaptors for member pointers@endlink.
template<typename _Ret, typename _Tp, typename _Arg>
class const_mem_fun1_ref_t : public binary_function<_Tp, _Arg, _Ret>
{
diff --git a/libstdc++-v3/include/bits/unique_ptr.h b/libstdc++-v3/include/bits/unique_ptr.h
index 2d8b9ed..023bd4d 100644
--- a/libstdc++-v3/include/bits/unique_ptr.h
+++ b/libstdc++-v3/include/bits/unique_ptr.h
@@ -58,6 +58,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif
/// Primary template of default_delete, used by unique_ptr for single objects
+ /// @since C++11
template<typename _Tp>
struct default_delete
{
@@ -236,7 +237,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
};
/// @endcond
- /// 20.7.1.2 unique_ptr for single objects.
+ // 20.7.1.2 unique_ptr for single objects.
+
+ /// A move-only smart pointer that manages unique ownership of a resource.
+ /// @since C++11
template <typename _Tp, typename _Dp = default_delete<_Tp>>
class unique_ptr
{
@@ -468,10 +472,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
unique_ptr& operator=(const unique_ptr&) = delete;
};
- /// 20.7.1.3 unique_ptr for array objects with a runtime length
+ // 20.7.1.3 unique_ptr for array objects with a runtime length
// [unique.ptr.runtime]
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 740 - omit specialization for array objects with a compile time length
+
+ /// A move-only smart pointer that manages unique ownership of an array.
+ /// @since C++11
template<typename _Tp, typename _Dp>
class unique_ptr<_Tp[], _Dp>
{
@@ -939,7 +946,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#define __cpp_lib_make_unique 201304
/// @cond undocumented
-
+namespace __detail
+{
template<typename _Tp>
struct _MakeUniq
{ typedef unique_ptr<_Tp> __single_object; };
@@ -952,54 +960,92 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct _MakeUniq<_Tp[_Bound]>
{ struct __invalid_type { }; };
+ template<typename _Tp>
+ using __unique_ptr_t = typename _MakeUniq<_Tp>::__single_object;
+ template<typename _Tp>
+ using __unique_ptr_array_t = typename _MakeUniq<_Tp>::__array;
+ template<typename _Tp>
+ using __invalid_make_unique_t = typename _MakeUniq<_Tp>::__invalid_type;
+}
/// @endcond
- /// @{
- /// @relates unique_ptr
-
- /// std::make_unique for single objects
+ /** Create an object owned by a `unique_ptr`.
+ * @tparam _Tp A non-array object type.
+ * @param __args Constructor arguments for the new object.
+ * @returns A `unique_ptr<_Tp>` that owns the new object.
+ * @since C++14
+ * @relates unique_ptr
+ */
template<typename _Tp, typename... _Args>
- inline typename _MakeUniq<_Tp>::__single_object
+ inline __detail::__unique_ptr_t<_Tp>
make_unique(_Args&&... __args)
{ return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
- /// std::make_unique for arrays of unknown bound
+ /** Create an array owned by a `unique_ptr`.
+ * @tparam _Tp An array type of unknown bound, such as `U[]`.
+ * @param __num The number of elements of type `U` in the new array.
+ * @returns A `unique_ptr<U[]>` that owns the new array.
+ * @since C++14
+ * @relates unique_ptr
+ *
+ * The array elements are value-initialized.
+ */
template<typename _Tp>
- inline typename _MakeUniq<_Tp>::__array
+ inline __detail::__unique_ptr_array_t<_Tp>
make_unique(size_t __num)
{ return unique_ptr<_Tp>(new remove_extent_t<_Tp>[__num]()); }
- /// Disable std::make_unique for arrays of known bound
+ /** Disable std::make_unique for arrays of known bound.
+ * @tparam _Tp An array type of known bound, such as `U[N]`.
+ * @since C++14
+ * @relates unique_ptr
+ */
template<typename _Tp, typename... _Args>
- typename _MakeUniq<_Tp>::__invalid_type
+ __detail::__invalid_make_unique_t<_Tp>
make_unique(_Args&&...) = delete;
#if __cplusplus > 201703L
- /// std::make_unique_for_overwrite for single objects
+ /** Create a default-initialied object owned by a `unique_ptr`.
+ * @tparam _Tp A non-array object type.
+ * @returns A `unique_ptr<_Tp>` that owns the new object.
+ * @since C++20
+ * @relates unique_ptr
+ */
template<typename _Tp>
- inline typename _MakeUniq<_Tp>::__single_object
+ inline __detail::__unique_ptr_t<_Tp>
make_unique_for_overwrite()
{ return unique_ptr<_Tp>(new _Tp); }
- /// std::make_unique_for_overwrite for arrays of unknown bound
+ /** Create a default-initialized array owned by a `unique_ptr`.
+ * @tparam _Tp An array type of unknown bound, such as `U[]`.
+ * @param __num The number of elements of type `U` in the new array.
+ * @returns A `unique_ptr<U[]>` that owns the new array.
+ * @since C++20
+ * @relates unique_ptr
+ */
template<typename _Tp>
- inline typename _MakeUniq<_Tp>::__array
+ inline __detail::__unique_ptr_array_t<_Tp>
make_unique_for_overwrite(size_t __n)
{ return unique_ptr<_Tp>(new remove_extent_t<_Tp>[__n]); }
- /// Disable std::make_unique_for_overwrite for arrays of known bound
+ /** Disable std::make_unique_for_overwrite for arrays of known bound.
+ * @tparam _Tp An array type of known bound, such as `U[N]`.
+ * @since C++20
+ * @relates unique_ptr
+ */
template<typename _Tp, typename... _Args>
- typename _MakeUniq<_Tp>::__invalid_type
+ __detail::__invalid_make_unique_t<_Tp>
make_unique_for_overwrite(_Args&&...) = delete;
#endif // C++20
- /// @} relates unique_ptr
#endif // C++14
#if __cplusplus > 201703L && __cpp_concepts
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2948. unique_ptr does not define operator<< for stream output
/// Stream output operator for unique_ptr
+ /// @relates unique_ptr
+ /// @since C++20
template<typename _CharT, typename _Traits, typename _Tp, typename _Dp>
inline basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os,
diff --git a/libstdc++-v3/include/debug/deque b/libstdc++-v3/include/debug/deque
index 4257a16..574cab1 100644
--- a/libstdc++-v3/include/debug/deque
+++ b/libstdc++-v3/include/debug/deque
@@ -130,7 +130,7 @@ namespace __debug
deque(size_type __n, const _Allocator& __a = _Allocator())
: _Base(__n, __a) { }
- deque(size_type __n, const _Tp& __value,
+ deque(size_type __n, const __type_identity_t<_Tp>& __value,
const _Allocator& __a = _Allocator())
: _Base(__n, __value, __a) { }
#else
@@ -668,6 +668,11 @@ namespace __debug
typename = _RequireAllocator<_Allocator>>
deque(_InputIterator, _InputIterator, _Allocator = _Allocator())
-> deque<_ValT, _Allocator>;
+
+ template<typename _Tp, typename _Allocator = allocator<_Tp>,
+ typename = _RequireAllocator<_Allocator>>
+ deque(size_t, _Tp, _Allocator = _Allocator())
+ -> deque<_Tp, _Allocator>;
#endif
template<typename _Tp, typename _Alloc>
diff --git a/libstdc++-v3/include/debug/forward_list b/libstdc++-v3/include/debug/forward_list
index 9cc05e8..cae5b5f 100644
--- a/libstdc++-v3/include/debug/forward_list
+++ b/libstdc++-v3/include/debug/forward_list
@@ -251,7 +251,7 @@ namespace __debug
: _Base(__n, __al)
{ }
- forward_list(size_type __n, const _Tp& __value,
+ forward_list(size_type __n, const __type_identity_t<_Tp>& __value,
const allocator_type& __al = allocator_type())
: _Base(__n, __value, __al)
{ }
@@ -854,6 +854,11 @@ namespace __debug
typename = _RequireAllocator<_Allocator>>
forward_list(_InputIterator, _InputIterator, _Allocator = _Allocator())
-> forward_list<_ValT, _Allocator>;
+
+ template<typename _Tp, typename _Allocator = allocator<_Tp>,
+ typename = _RequireAllocator<_Allocator>>
+ forward_list(size_t, _Tp, _Allocator = _Allocator())
+ -> forward_list<_Tp, _Allocator>;
#endif
template<typename _Tp, typename _Alloc>
diff --git a/libstdc++-v3/include/debug/list b/libstdc++-v3/include/debug/list
index 83122f8..b599e93 100644
--- a/libstdc++-v3/include/debug/list
+++ b/libstdc++-v3/include/debug/list
@@ -135,7 +135,7 @@ namespace __debug
list(size_type __n, const allocator_type& __a = allocator_type())
: _Base(__n, __a) { }
- list(size_type __n, const _Tp& __value,
+ list(size_type __n, const __type_identity_t<_Tp>& __value,
const _Allocator& __a = _Allocator())
: _Base(__n, __value, __a) { }
#else
@@ -921,6 +921,11 @@ namespace __debug
typename = _RequireAllocator<_Allocator>>
list(_InputIterator, _InputIterator, _Allocator = _Allocator())
-> list<_ValT, _Allocator>;
+
+ template<typename _Tp, typename _Allocator = allocator<_Tp>,
+ typename = _RequireAllocator<_Allocator>>
+ list(size_t, _Tp, _Allocator = _Allocator())
+ -> list<_Tp, _Allocator>;
#endif
template<typename _Tp, typename _Alloc>
diff --git a/libstdc++-v3/include/debug/vector b/libstdc++-v3/include/debug/vector
index 5527138..d30d750 100644
--- a/libstdc++-v3/include/debug/vector
+++ b/libstdc++-v3/include/debug/vector
@@ -181,7 +181,7 @@ namespace __debug
vector(size_type __n, const _Allocator& __a = _Allocator())
: _Base(__n, __a), _Safe_vector(__n) { }
- vector(size_type __n, const _Tp& __value,
+ vector(size_type __n, const __type_identity_t<_Tp>& __value,
const _Allocator& __a = _Allocator())
: _Base(__n, __value, __a) { }
#else
@@ -811,6 +811,11 @@ namespace __debug
typename = _RequireAllocator<_Allocator>>
vector(_InputIterator, _InputIterator, _Allocator = _Allocator())
-> vector<_ValT, _Allocator>;
+
+ template<typename _Tp, typename _Allocator = allocator<_Tp>,
+ typename = _RequireAllocator<_Allocator>>
+ vector(size_t, _Tp, _Allocator = _Allocator())
+ -> vector<_Tp, _Allocator>;
#endif
} // namespace __debug
diff --git a/libstdc++-v3/include/ext/type_traits.h b/libstdc++-v3/include/ext/type_traits.h
index 065edb4..fed78d3 100644
--- a/libstdc++-v3/include/ext/type_traits.h
+++ b/libstdc++-v3/include/ext/type_traits.h
@@ -189,9 +189,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ typedef float __type; };
#if __cpp_fold_expressions
+
template<typename... _Tp>
using __promoted_t = decltype((typename __promote<_Tp>::__type(0) + ...));
-#endif
+
+ // Deducing the promoted type is done by __promoted_t<_Tp...>,
+ // then __promote is used to provide the nested __type member.
+ template<typename _Tp, typename _Up>
+ using __promote_2 = __promote<__promoted_t<_Tp, _Up>>;
+
+ template<typename _Tp, typename _Up, typename _Vp>
+ using __promote_3 = __promote<__promoted_t<_Tp, _Up, _Vp>>;
+
+ template<typename _Tp, typename _Up, typename _Vp, typename _Wp>
+ using __promote_4 = __promote<__promoted_t<_Tp, _Up, _Vp, _Wp>>;
+
+#else
template<typename _Tp, typename _Up,
typename _Tp2 = typename __promote<_Tp>::__type,
@@ -219,6 +232,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
typedef __typeof__(_Tp2() + _Up2() + _Vp2() + _Wp2()) __type;
};
+#endif
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
diff --git a/libstdc++-v3/include/std/complex b/libstdc++-v3/include/std/complex
index c2f6421..a5b4406 100644
--- a/libstdc++-v3/include/std/complex
+++ b/libstdc++-v3/include/std/complex
@@ -1557,35 +1557,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
-namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
- // See ext/type_traits.h for the primary template.
- template<typename _Tp, typename _Up>
- struct __promote_2<std::complex<_Tp>, _Up>
- {
- public:
- typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type;
- };
-
- template<typename _Tp, typename _Up>
- struct __promote_2<_Tp, std::complex<_Up> >
- {
- public:
- typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type;
- };
-
- template<typename _Tp, typename _Up>
- struct __promote_2<std::complex<_Tp>, std::complex<_Up> >
- {
- public:
- typedef std::complex<typename __promote_2<_Tp, _Up>::__type> __type;
- };
-
-_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace
-
#if __cplusplus >= 201103L
namespace std _GLIBCXX_VISIBILITY(default)
diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index 2be4944..1571800 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -551,7 +551,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ };
/// __is_nullptr_t (deprecated extension).
- /// @deprecated Use `is_null_pointer` instead.
+ /// @deprecated Non-standard. Use `is_null_pointer` instead.
template<typename _Tp>
struct __is_nullptr_t
: public is_null_pointer<_Tp>
@@ -732,8 +732,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
"template argument must be a complete class or an unbounded array");
};
- /** is_pod (deprecated in C++20)
- * @deprecated Use `is_standard_layout && is_trivial` instead.
+ /** is_pod
+ * @deprecated Deprecated in C++20.
+ * Use `is_standard_layout && is_trivial` instead.
*/
// Could use is_standard_layout && is_trivial instead of the builtin.
template<typename _Tp>
@@ -747,7 +748,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
};
/** is_literal_type
- * @deprecated Deprecated in C++20. The idea of a literal type isn't useful.
+ * @deprecated Deprecated in C++17, removed in C++20.
+ * The idea of a literal type isn't useful.
*/
template<typename _Tp>
struct
@@ -3097,7 +3099,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* Each variable `is_xxx_v<T>` is a boolean constant with the same value
* as the `value` member of the corresponding type trait `is_xxx<T>`.
*
- * @since C++17
+ * @since C++17 unless noted otherwise.
*/
/**
@@ -3286,6 +3288,7 @@ template<typename _Ret, typename _Fn, typename... _Args>
#ifdef _GLIBCXX_HAVE_BUILTIN_HAS_UNIQ_OBJ_REP
# define __cpp_lib_has_unique_object_representations 201606
/// has_unique_object_representations
+ /// @since C++17
template<typename _Tp>
struct has_unique_object_representations
: bool_constant<__has_unique_object_representations(
@@ -3305,6 +3308,7 @@ template<typename _Ret, typename _Fn, typename... _Args>
#ifdef _GLIBCXX_HAVE_BUILTIN_IS_AGGREGATE
# define __cpp_lib_is_aggregate 201703
/// is_aggregate
+ /// @since C++17
template<typename _Tp>
struct is_aggregate
: bool_constant<__is_aggregate(remove_cv_t<_Tp>)>
@@ -3316,10 +3320,14 @@ template<typename _Ret, typename _Fn, typename... _Args>
#endif
#endif // C++17
-#if __cplusplus > 201703L
+#if __cplusplus >= 202002L
+
+ /** * Remove references and cv-qualifiers.
+ * @since C++20
+ * @{
+ */
#define __cpp_lib_remove_cvref 201711L
- /// Remove references and cv-qualifiers.
template<typename _Tp>
struct remove_cvref
: remove_cv<_Tp>
@@ -3337,18 +3345,26 @@ template<typename _Ret, typename _Fn, typename... _Args>
template<typename _Tp>
using remove_cvref_t = typename remove_cvref<_Tp>::type;
+ /// @}
+ /** * Identity metafunction.
+ * @since C++20
+ * @{
+ */
#define __cpp_lib_type_identity 201806L
- /// Identity metafunction.
template<typename _Tp>
struct type_identity { using type = _Tp; };
template<typename _Tp>
using type_identity_t = typename type_identity<_Tp>::type;
+ /// @}
#define __cpp_lib_unwrap_ref 201811L
- /// Unwrap a reference_wrapper
+ /** Unwrap a reference_wrapper
+ * @since C++20
+ * @{
+ */
template<typename _Tp>
struct unwrap_reference { using type = _Tp; };
@@ -3357,34 +3373,43 @@ template<typename _Ret, typename _Fn, typename... _Args>
template<typename _Tp>
using unwrap_reference_t = typename unwrap_reference<_Tp>::type;
+ /// @}
- /// Decay type and if it's a reference_wrapper, unwrap it
+ /** Decay type and if it's a reference_wrapper, unwrap it
+ * @since C++20
+ * @{
+ */
template<typename _Tp>
struct unwrap_ref_decay { using type = unwrap_reference_t<decay_t<_Tp>>; };
template<typename _Tp>
using unwrap_ref_decay_t = typename unwrap_ref_decay<_Tp>::type;
+ /// @}
#define __cpp_lib_bounded_array_traits 201902L
/// True for a type that is an array of known bound.
+ /// @since C++20
template<typename _Tp>
struct is_bounded_array
: public __is_array_known_bounds<_Tp>
{ };
/// True for a type that is an array of unknown bound.
+ /// @since C++20
template<typename _Tp>
struct is_unbounded_array
: public __is_array_unknown_bounds<_Tp>
{ };
/// @ingroup variable_templates
+ /// @since C++20
template<typename _Tp>
inline constexpr bool is_bounded_array_v
= is_bounded_array<_Tp>::value;
/// @ingroup variable_templates
+ /// @since C++20
template<typename _Tp>
inline constexpr bool is_unbounded_array_v
= is_unbounded_array<_Tp>::value;
@@ -3419,8 +3444,8 @@ template<typename _Ret, typename _Fn, typename... _Args>
#if __cplusplus > 202002L
#define __cpp_lib_is_scoped_enum 202011L
+ /// True if the type is a scoped enumeration type.
/// @since C++23
- //@{
template<typename _Tp>
struct is_scoped_enum
@@ -3443,11 +3468,11 @@ template<typename _Ret, typename _Fn, typename... _Args>
: bool_constant<!requires(_Tp __t, void(*__f)(int)) { __f(__t); }>
{ };
- /**
- * @ingroup variable_templates
- */
+ /// @ingroup variable_templates
+ /// @since C++23
template<typename _Tp>
inline constexpr bool is_scoped_enum_v = is_scoped_enum<_Tp>::value;
+
#endif // C++23
#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
@@ -3455,10 +3480,10 @@ template<typename _Ret, typename _Fn, typename... _Args>
#define __cpp_lib_is_constant_evaluated 201811L
/// Returns true only when called during constant evaluation.
+ /// @since C++20
constexpr inline bool
is_constant_evaluated() noexcept
{ return __builtin_is_constant_evaluated(); }
- /// @}
#endif
/// @cond undocumented
diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
index 82d262d..c7da407 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -491,14 +491,14 @@ class StdBitIteratorPrinter:
return bool(self.val['_M_p'].dereference() & (1 << self.val['_M_offset']))
class StdBitReferencePrinter:
- "Print std::_Bit_reference"
+ "Print std::vector<bool>::reference"
def __init__(self, typename, val):
self.val = val
def to_string(self):
if not self.val['_M_p']:
- return 'invalid std::_Bit_reference'
+ return 'invalid std::vector<bool>::reference'
return bool(self.val['_M_p'].dereference() & (self.val['_M_mask']))
class StdTuplePrinter:
@@ -2052,11 +2052,11 @@ def build_libstdcxx_dictionary ():
StdDequeIteratorPrinter)
libstdcxx_printer.add_version('__gnu_cxx::', '__normal_iterator',
StdVectorIteratorPrinter)
- libstdcxx_printer.add_version('std::', '_Bit_iterator',
+ libstdcxx_printer.add_container('std::', '_Bit_iterator',
StdBitIteratorPrinter)
- libstdcxx_printer.add_version('std::', '_Bit_const_iterator',
+ libstdcxx_printer.add_container('std::', '_Bit_const_iterator',
StdBitIteratorPrinter)
- libstdcxx_printer.add_version('std::', '_Bit_reference',
+ libstdcxx_printer.add_container('std::', '_Bit_reference',
StdBitReferencePrinter)
libstdcxx_printer.add_version('__gnu_cxx::', '_Slist_iterator',
StdSlistIteratorPrinter)
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc
index c1fc4b1..02f762e 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc
@@ -144,19 +144,19 @@ main()
std::vector<bool>::iterator vbIt0;
// { dg-final { note-test vbIt0 {non-dereferenceable iterator for std::vector<bool>} } }
- std::_Bit_reference br = *vb.begin();
+ std::vector<bool>::reference br = *vb.begin();
// { dg-final { note-test br {true} } }
- std::_Bit_reference br2 = *vbIt2;
+ std::vector<bool>::reference br2 = *vbIt2;
// { dg-final { note-test br2 {true} } }
- std::_Bit_reference br3 = *vbIt3;
+ std::vector<bool>::reference br3 = *vbIt3;
// { dg-final { note-test br3 {false} } }
- std::_Bit_reference br4 = *vbIt4;
+ std::vector<bool>::reference br4 = *vbIt4;
// { dg-final { note-test br4 {false} } }
- std::_Bit_reference br5 = *vbIt5;
+ std::vector<bool>::reference br5 = *vbIt5;
// { dg-final { note-test br5 {true} } }
- std::_Bit_reference br0;
-// { dg-final { note-test br0 {invalid std::_Bit_reference} } }
+ std::vector<bool>::reference br0;
+// { dg-final { note-test br0 {invalid std::vector<bool>::reference} } }
__gnu_cxx::slist<int> sll;
sll.push_front(23);
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc
index d219e27..bd6e026 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc
@@ -137,19 +137,19 @@ main()
std::vector<bool>::iterator vbIt0;
// { dg-final { note-test vbIt0 {non-dereferenceable iterator for std::vector<bool>} } }
- std::_Bit_reference br = *vb.begin();
+ std::vector<bool>::reference br = *vb.begin();
// { dg-final { note-test br {true} } }
- std::_Bit_reference br2 = *vbIt2;
+ std::vector<bool>::reference br2 = *vbIt2;
// { dg-final { note-test br2 {true} } }
- std::_Bit_reference br3 = *vbIt3;
+ std::vector<bool>::reference br3 = *vbIt3;
// { dg-final { note-test br3 {false} } }
- std::_Bit_reference br4 = *vbIt4;
+ std::vector<bool>::reference br4 = *vbIt4;
// { dg-final { note-test br4 {false} } }
- std::_Bit_reference br5 = *vbIt5;
+ std::vector<bool>::reference br5 = *vbIt5;
// { dg-final { note-test br5 {true} } }
- std::_Bit_reference br0;
-// { dg-final { note-test br0 {invalid std::_Bit_reference} } }
+ std::vector<bool>::reference br0;
+// { dg-final { note-test br0 {invalid std::vector<bool>::reference} } }
__gnu_cxx::slist<int> sll;
sll.push_front(23);