aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2021-12-13 11:57:11 +0100
committerMartin Liska <mliska@suse.cz>2021-12-13 11:57:11 +0100
commit193c48050a11822ab093cef4463a3737b44e4222 (patch)
tree7333eb9a5a3e12cb4bff208847226004e3f26a7f
parentcf116c791582be1c0cc9e04872cb7f8d0d463fd8 (diff)
parent3788c4ed2c774e36b2721ee2af454591a42afdeb (diff)
downloadgcc-193c48050a11822ab093cef4463a3737b44e4222.zip
gcc-193c48050a11822ab093cef4463a3737b44e4222.tar.gz
gcc-193c48050a11822ab093cef4463a3737b44e4222.tar.bz2
Merge branch 'master' into devel/sphinx
-rw-r--r--gcc/ChangeLog42
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/Makefile.in1
-rw-r--r--gcc/analyzer/ChangeLog4
-rw-r--r--gcc/analyzer/engine.cc2
-rw-r--r--gcc/attribs.c13
-rw-r--r--gcc/c-family/ChangeLog7
-rw-r--r--gcc/c-family/known-headers.cc2
-rw-r--r--gcc/c-family/name-hint.h12
-rw-r--r--gcc/c/ChangeLog5
-rw-r--r--gcc/c/c-decl.c2
-rw-r--r--gcc/c/c-parser.c2
-rw-r--r--gcc/config/aarch64/aarch64-sve-builtins.cc2
-rw-r--r--gcc/cp/ChangeLog12
-rw-r--r--gcc/cp/error.c2
-rw-r--r--gcc/cp/lex.c2
-rw-r--r--gcc/cp/name-lookup.c10
-rw-r--r--gcc/cp/parser.c2
-rw-r--r--gcc/doc/extend.texi2
-rw-r--r--gcc/ipa-fnsummary.c2
-rw-r--r--gcc/jit/ChangeLog16
-rw-r--r--gcc/jit/docs/topics/compatibility.rst9
-rw-r--r--gcc/jit/docs/topics/expressions.rst21
-rw-r--r--gcc/jit/jit-playback.h6
-rw-r--r--gcc/jit/jit-recording.c21
-rw-r--r--gcc/jit/jit-recording.h5
-rw-r--r--gcc/jit/libgccjit.c13
-rw-r--r--gcc/jit/libgccjit.h14
-rw-r--r--gcc/jit/libgccjit.map5
-rw-r--r--gcc/machmode.h2
-rw-r--r--gcc/poly-int.h2
-rw-r--r--gcc/selftest-run-tests.c1
-rw-r--r--gcc/selftest.h1
-rw-r--r--gcc/system.h8
-rw-r--r--gcc/testsuite/ChangeLog13
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr103513.c8
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr103515.c30
-rw-r--r--gcc/testsuite/jit.dg/all-non-failing-tests.h3
-rw-r--r--gcc/testsuite/jit.dg/jit.exp33
-rw-r--r--gcc/testsuite/jit.dg/test-link-section-assembler.c37
-rw-r--r--gcc/unique-ptr-tests.cc236
-rw-r--r--gcc/wide-int.h4
-rw-r--r--include/ChangeLog4
-rw-r--r--include/unique-ptr.h405
44 files changed, 345 insertions, 680 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d343471..890ddae 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,45 @@
+2021-12-12 Jonathan Wakely <jwakely@redhat.com>
+
+ * Makefile.in: Remove unique-ptr-tests.o.
+ * selftest-run-tests.c (selftest::run_tests): Remove
+ unique_ptr_tests_cc_tests.
+ * selftest.h (unique_ptr_tests_cc_tests): Remove.
+ * system.h: Check INCLUDE_MEMORY instead of INCLUDE_UNIQUE_PTR
+ and include <memory> instead of "unique-ptr.h".
+ * unique-ptr-tests.cc: Removed.
+
+2021-12-12 Roger Sayle <roger@nextmovesoftware.com>
+
+ * config/nvptx/nvptx-opts.h (ptx_isa): Add PTX_ISA_SM53 ISA level
+ to enumeration.
+ * config/nvptx/nvptx.opt: Add sm_53 to -misa.
+ * config/nvptx/nvptx-modes.def: Add support for HFmode.
+ * config/nvptx/nvptx.h (TARGET_SM53):
+ New helper macro to conditionalize functionality on target ISA.
+ * config/nvptx/nvptx-c.c (nvptx_cpu_cpp_builtins): Add __PTX_SM__
+ support for the new ISA levels.
+ * config/nvptx/nvptx.c (nvtx_ptx_type_from_mode): Support new HFmode
+ with the ".f16" suffix/qualifier.
+ (nvptx_file_start): Add support for TARGET_SM53.
+ (nvptx_omp_device_kind_arch_isa): Add support for TARGET_SM53
+ and tweak TARGET_SM35.
+ (nvptx_scalar_mode_supported_p): Target hook with conditional
+ HFmode support on TARGET_SM53 and higher.
+ (nvptx_libgcc_floating_mode_supported_p): Likewise.
+ (TARGET_SCALAR_MODE_SUPPORTED_P): Use nvptx_scalar_mode_supported_p.
+ (TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P): Likewise, use new hook.
+ * config/nvptx/nvptx.md (*movhf_insn): New define_insn.
+ (movhf): New define_expand for HFmode moves.
+ (addhf3, subhf3, mulhf, extendhf<mode>2, trunc<mode>hf2): New
+ instructions conditional on TARGET_SM53 (i.e. -misa=sm_53).
+
+2021-12-12 Jan Hubicka <hubicka@ucw.cz>
+
+ PR ipa/103665
+ * ipa-modref.c (modref_access_analysis::analyze): Terminate BB
+ analysis on NULL memory access.
+ * ipa-pure-const.c (analyze_function): Likewise.
+
2021-12-11 Jan Hubicka <hubicka@ucw.cz>
* ipa-profile.c (ipa_profile): Do not update hot bb threshold.
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index c59e542..6fc1d23 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20211212
+20211213
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 41949f0..3e0cb4794 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1699,7 +1699,6 @@ OBJS = \
tree.o \
tristate.o \
typed-splay-tree.o \
- unique-ptr-tests.o \
valtrack.o \
value-pointer-equiv.o \
value-query.o \
diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog
index bcbd8de..b526aff 100644
--- a/gcc/analyzer/ChangeLog
+++ b/gcc/analyzer/ChangeLog
@@ -1,3 +1,7 @@
+2021-12-12 Jonathan Wakely <jwakely@redhat.com>
+
+ * engine.cc: Define INCLUDE_MEMORY instead of INCLUDE_UNIQUE_PTR.
+
2021-12-06 David Malcolm <dmalcolm@redhat.com>
PR analyzer/103533
diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index e8a7cca..4aa246c 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -19,7 +19,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
-#define INCLUDE_UNIQUE_PTR
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "tree.h"
diff --git a/gcc/attribs.c b/gcc/attribs.c
index 32c9415..01a9ed6 100644
--- a/gcc/attribs.c
+++ b/gcc/attribs.c
@@ -607,7 +607,18 @@ decl_attributes (tree *node, tree attributes, int flags,
if (TREE_CODE (*node) == FUNCTION_DECL
&& optimization_current_node != optimization_default_node
&& !DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node))
- DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node) = optimization_current_node;
+ {
+ DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node) = optimization_current_node;
+ tree cur_tree
+ = build_target_option_node (&global_options, &global_options_set);
+ tree old_tree = DECL_FUNCTION_SPECIFIC_TARGET (*node);
+ if (!old_tree)
+ old_tree = target_option_default_node;
+ /* The changes on optimization options can cause the changes in
+ target options, update it accordingly if it's changed. */
+ if (old_tree != cur_tree)
+ DECL_FUNCTION_SPECIFIC_TARGET (*node) = cur_tree;
+ }
/* If this is a function and the user used #pragma GCC target, add the
options to the attribute((target(...))) list. */
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 66f28fb..605a484 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,10 @@
+2021-12-12 Jonathan Wakely <jwakely@redhat.com>
+
+ * known-headers.cc: Define INCLUDE_MEMORY instead of
+ INCLUDE_UNIQUE_PTR.
+ * name-hint.h: Likewise.
+ (class name_hint): Use std::unique_ptr instead of gnu::unique_ptr.
+
2021-12-09 Jakub Jelinek <jakub@redhat.com>
PR pch/71934
diff --git a/gcc/c-family/known-headers.cc b/gcc/c-family/known-headers.cc
index a391246..572cca1 100644
--- a/gcc/c-family/known-headers.cc
+++ b/gcc/c-family/known-headers.cc
@@ -18,7 +18,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
-#define INCLUDE_UNIQUE_PTR
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "c-family/c-common.h"
diff --git a/gcc/c-family/name-hint.h b/gcc/c-family/name-hint.h
index ea43324..3141552 100644
--- a/gcc/c-family/name-hint.h
+++ b/gcc/c-family/name-hint.h
@@ -20,12 +20,12 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_NAME_HINT_H
#define GCC_NAME_HINT_H
-/* This header uses gnu::unique_ptr, but unique-ptr.h can't be directly
+/* This header uses std::unique_ptr, but <memory> can't be directly
included due to issues with macros. Hence it must be included from
- system.h by defining INCLUDE_UNIQUE_PTR in any source file using it. */
+ system.h by defining INCLUDE_MEMORY in any source file using it. */
-#ifndef GNU_UNIQUE_PTR_H
-# error "You must define INCLUDE_UNIQUE_PTR before including system.h to use name-hint.h"
+#ifndef INCLUDE_MEMORY
+# error "You must define INCLUDE_MEMORY before including system.h to use name-hint.h"
#endif
enum lookup_name_fuzzy_kind {
@@ -106,7 +106,7 @@ public:
/* Take ownership of this name_hint's deferred_diagnostic, for use
in chaining up deferred diagnostics. */
- gnu::unique_ptr<deferred_diagnostic> take_deferred () { return move (m_deferred); }
+ std::unique_ptr<deferred_diagnostic> take_deferred () { return move (m_deferred); }
/* Call this on a name_hint if the corresponding warning was not emitted,
in which case we should also not emit the deferred_diagnostic. */
@@ -119,7 +119,7 @@ public:
private:
const char *m_suggestion;
- gnu::unique_ptr<deferred_diagnostic> m_deferred;
+ std::unique_ptr<deferred_diagnostic> m_deferred;
};
extern name_hint lookup_name_fuzzy (tree, enum lookup_name_fuzzy_kind,
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index d899302..90c0640 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,8 @@
+2021-12-12 Jonathan Wakely <jwakely@redhat.com>
+
+ * c-decl.c: Define INCLUDE_MEMORY instead of INCLUDE_UNIQUE_PTR.
+ * c-parser.c: Likewise.
+
2021-12-09 Jakub Jelinek <jakub@redhat.com>
PR pch/71934
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 9e45798..4b5481c 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -26,7 +26,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#define INCLUDE_STRING
-#define INCLUDE_UNIQUE_PTR
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "target.h"
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index e99c847..e25df4f 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -36,7 +36,7 @@ along with GCC; see the file COPYING3. If not see
location rather than implicitly using input_location. */
#include "config.h"
-#define INCLUDE_UNIQUE_PTR
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "target.h"
diff --git a/gcc/config/aarch64/aarch64-sve-builtins.cc b/gcc/config/aarch64/aarch64-sve-builtins.cc
index 27be8b9..4250eaf 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins.cc
+++ b/gcc/config/aarch64/aarch64-sve-builtins.cc
@@ -3913,7 +3913,7 @@ gt_pch_nx (function_instance *)
}
inline void
-gt_pch_nx (function_instance *, void (*) (void *, void *, void *), void *)
+gt_pch_nx (function_instance *, gt_pointer_operator, void *)
{
}
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 3ea43f1..0cdb2e1 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,15 @@
+2021-12-12 Jonathan Wakely <jwakely@redhat.com>
+
+ * error.c: Define INCLUDE_MEMORY instead of
+ INCLUDE_UNIQUE_PTR.
+ * lex.c: Likewise.
+ * name-lookup.c: Likewise.
+ (class namespace_limit_reached): Use std::unique_ptr instead of
+ gnu::unique_ptr.
+ (suggest_alternatives_for): Use std::move instead of gnu::move.
+ (suggest_alternatives_in_other_namespaces): Likewise.
+ * parser.c: Define INCLUDE_MEMORY instead of INCLUDE_UNIQUE_PTR.
+
2021-12-09 Marek Polacek <polacek@redhat.com>
PR c++/103401
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index daea3b3..323643d 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -19,7 +19,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
/* For use with name_hint. */
-#define INCLUDE_UNIQUE_PTR
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "cp-tree.h"
diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c
index 43abd01..06de6cf 100644
--- a/gcc/cp/lex.c
+++ b/gcc/cp/lex.c
@@ -23,7 +23,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
/* For use with name_hint. */
-#define INCLUDE_UNIQUE_PTR
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "cp-tree.h"
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 229ba45..6b5e434 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -19,7 +19,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
-#define INCLUDE_UNIQUE_PTR
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "cp-tree.h"
@@ -6340,7 +6340,7 @@ class namespace_limit_reached : public deferred_diagnostic
{
public:
namespace_limit_reached (location_t loc, unsigned limit, tree name,
- gnu::unique_ptr<deferred_diagnostic> wrapped)
+ std::unique_ptr<deferred_diagnostic> wrapped)
: deferred_diagnostic (loc),
m_limit (limit), m_name (name),
m_wrapped (move (wrapped))
@@ -6360,7 +6360,7 @@ class namespace_limit_reached : public deferred_diagnostic
private:
unsigned m_limit;
tree m_name;
- gnu::unique_ptr<deferred_diagnostic> m_wrapped;
+ std::unique_ptr<deferred_diagnostic> m_wrapped;
};
/* Subclass of deferred_diagnostic, for use when issuing a single suggestion.
@@ -6604,7 +6604,7 @@ suggest_alternatives_for (location_t location, tree name,
if (!result)
result = suggest_alternatives_for_1 (location, name, suggest_misspellings);
- return ns_hints.maybe_decorate_with_limit (gnu::move (result));
+ return ns_hints.maybe_decorate_with_limit (std::move (result));
}
/* The second half of suggest_alternatives_for, for when no exact matches
@@ -6649,7 +6649,7 @@ suggest_alternatives_in_other_namespaces (location_t location, tree name)
name_hint result = ns_hints.convert_candidates_to_name_hint ();
- return ns_hints.maybe_decorate_with_limit (gnu::move (result));
+ return ns_hints.maybe_decorate_with_limit (std::move (result));
}
/* A well-known name within the C++ standard library, returned by
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index de464afd..52225d4 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -19,7 +19,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
-#define INCLUDE_UNIQUE_PTR
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "cp-tree.h"
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index d4c35e5..5099fa9 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -2519,7 +2519,7 @@ The following attributes are supported on most targets.
@table @code
@c Keep this table alphabetized by attribute name. Treat _ as space.
-@itemx access (@var{access-mode}, @var{ref-index})
+@item access (@var{access-mode}, @var{ref-index})
@itemx access (@var{access-mode}, @var{ref-index}, @var{size-index})
The @code{access} attribute enables the detection of invalid or unsafe
diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c
index 6c1cdf1..cb3c198 100644
--- a/gcc/ipa-fnsummary.c
+++ b/gcc/ipa-fnsummary.c
@@ -513,7 +513,7 @@ evaluate_conditions_for_known_args (struct cgraph_node *node,
op->index ? &vr : &op0);
}
else
- gcc_unreachable ();
+ res.set_varying (op->type);
type = op->type;
vr = res;
}
diff --git a/gcc/jit/ChangeLog b/gcc/jit/ChangeLog
index 349b795..ab06d51 100644
--- a/gcc/jit/ChangeLog
+++ b/gcc/jit/ChangeLog
@@ -1,5 +1,21 @@
2021-12-12 Antoni Boucher <bouanto@zoho.com>
+ PR target/100688
+ * docs/topics/compatibility.rst (LIBGCCJIT_ABI_18): New ABI
+ tag.
+ * docs/topics/expressions.rst: Add documentation for the
+ function gcc_jit_lvalue_set_link_section.
+ * jit-playback.h: New function (set_link_section).
+ * jit-recording.c: New function (set_link_section) and
+ support for setting the link section.
+ * jit-recording.h: New function (set_link_section) and new
+ field m_link_section.
+ * libgccjit.c: New function (gcc_jit_lvalue_set_link_section).
+ * libgccjit.h: New function (gcc_jit_lvalue_set_link_section).
+ * libgccjit.map (LIBGCCJIT_ABI_18): New ABI tag.
+
+2021-12-12 Antoni Boucher <bouanto@zoho.com>
+
PR target/95415
* docs/topics/compatibility.rst (LIBGCCJIT_ABI_17): New ABI
tag.
diff --git a/gcc/jit/docs/topics/compatibility.rst b/gcc/jit/docs/topics/compatibility.rst
index 2ad6e42..c6c14f0 100644
--- a/gcc/jit/docs/topics/compatibility.rst
+++ b/gcc/jit/docs/topics/compatibility.rst
@@ -293,3 +293,12 @@ entrypoints:
thread-local storage model of a variable:
* :func:`gcc_jit_lvalue_set_tls_model`
+
+.. _LIBGCCJIT_ABI_18:
+
+``LIBGCCJIT_ABI_18``
+-----------------------
+``LIBGCCJIT_ABI_18`` covers the addition of an API entrypoint to set the link
+section of a variable:
+
+ * :func:`gcc_jit_lvalue_set_link_section`
diff --git a/gcc/jit/docs/topics/expressions.rst b/gcc/jit/docs/topics/expressions.rst
index 386b80d..280e0ea 100644
--- a/gcc/jit/docs/topics/expressions.rst
+++ b/gcc/jit/docs/topics/expressions.rst
@@ -576,6 +576,27 @@ where the rvalue is computed by reading from the storage area.
#ifdef LIBGCCJIT_HAVE_gcc_jit_lvalue_set_tls_model
+.. function:: void
+ gcc_jit_lvalue_set_link_section (gcc_jit_lvalue *lvalue,
+ const char *section_name)
+
+ Set the link section of a variable.
+ The parameter ``section_name`` must be non-NULL and must contain the
+ leading dot. Analogous to:
+
+ .. code-block:: c
+
+ int variable __attribute__((section(".section")));
+
+ in C.
+
+ This entrypoint was added in :ref:`LIBGCCJIT_ABI_18`; you can test for
+ its presence using
+
+ .. code-block:: c
+
+ #ifdef LIBGCCJIT_HAVE_gcc_jit_lvalue_set_link_section
+
Global variables
****************
diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h
index c9839c2..21ddffb 100644
--- a/gcc/jit/jit-playback.h
+++ b/gcc/jit/jit-playback.h
@@ -681,6 +681,12 @@ public:
set_decl_tls_model (as_tree (), tls_model);
}
+ void
+ set_link_section (const char* name)
+ {
+ set_decl_section_name (as_tree (), name);
+ }
+
private:
bool mark_addressable (location *loc);
};
diff --git a/gcc/jit/jit-recording.c b/gcc/jit/jit-recording.c
index 5ba35bd..b424079 100644
--- a/gcc/jit/jit-recording.c
+++ b/gcc/jit/jit-recording.c
@@ -3724,6 +3724,11 @@ recording::lvalue::set_tls_model (enum gcc_jit_tls_model model)
m_tls_model = model;
}
+void recording::lvalue::set_link_section (const char *name)
+{
+ m_link_section = new_string (name);
+}
+
/* The implementation of class gcc::jit::recording::param. */
/* Implementation of pure virtual hook recording::memento::replay_into
@@ -4568,8 +4573,8 @@ static const enum tls_model tls_models[] = {
void
recording::global::replay_into (replayer *r)
{
- playback::lvalue *global = m_initializer
- ? r->new_global_initialized (playback_location (r, m_loc),
+ playback::lvalue *global = m_initializer
+ ? r->new_global_initialized (playback_location (r, m_loc),
m_kind,
m_type->playback_type (),
m_type->dereference ()->get_size (),
@@ -4577,13 +4582,17 @@ recording::global::replay_into (replayer *r)
/ m_type->dereference ()->get_size (),
m_initializer,
playback_string (m_name))
- : r->new_global (playback_location (r, m_loc),
+ : r->new_global (playback_location (r, m_loc),
m_kind,
m_type->playback_type (),
playback_string (m_name));
+
if (m_tls_model != GCC_JIT_TLS_MODEL_NONE)
global->set_tls_model (recording::tls_models[m_tls_model]);
+ if (m_link_section != NULL)
+ global->set_link_section (m_link_section->c_str ());
+
set_playback_obj (global);
}
@@ -4713,6 +4722,12 @@ recording::global::write_reproducer (reproducer &r)
id,
tls_model_enum_strings[m_tls_model]);
+ if (m_link_section != NULL)
+ r.write (" gcc_jit_lvalue_set_link_section (%s, /* gcc_jit_lvalue *lvalue */\n"
+ " \"%s\"); /* */\n",
+ id,
+ m_link_section->c_str ());
+
if (m_initializer)
switch (m_type->dereference ()->get_size ())
{
diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h
index 72fa30c..cedb247 100644
--- a/gcc/jit/jit-recording.h
+++ b/gcc/jit/jit-recording.h
@@ -1133,7 +1133,8 @@ public:
location *loc,
type *type_)
: rvalue (ctxt, loc, type_),
- m_tls_model (GCC_JIT_TLS_MODEL_NONE)
+ m_tls_model (GCC_JIT_TLS_MODEL_NONE),
+ m_link_section (NULL)
{}
playback::lvalue *
@@ -1156,9 +1157,11 @@ public:
virtual const char *access_as_lvalue (reproducer &r);
virtual bool is_global () const { return false; }
void set_tls_model (enum gcc_jit_tls_model model);
+ void set_link_section (const char *name);
protected:
enum gcc_jit_tls_model m_tls_model;
+ string *m_link_section;
};
class param : public lvalue
diff --git a/gcc/jit/libgccjit.c b/gcc/jit/libgccjit.c
index 7ccb76a..59cef61 100644
--- a/gcc/jit/libgccjit.c
+++ b/gcc/jit/libgccjit.c
@@ -2238,6 +2238,19 @@ gcc_jit_lvalue_set_tls_model (gcc_jit_lvalue *lvalue,
/* Public entrypoint. See description in libgccjit.h.
After error-checking, the real work is done by the
+ gcc::jit::recording::lvalue::set_link_section method in jit-recording.c. */
+
+void
+gcc_jit_lvalue_set_link_section (gcc_jit_lvalue *lvalue,
+ const char *section_name)
+{
+ RETURN_IF_FAIL (section_name, NULL, NULL, "NULL section_name");
+ lvalue->set_link_section (section_name);
+}
+
+/* Public entrypoint. See description in libgccjit.h.
+
+ After error-checking, the real work is done by the
gcc::jit::recording::function::new_local method in jit-recording.c. */
gcc_jit_lvalue *
diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h
index 5aa2e40..024c8d7 100644
--- a/gcc/jit/libgccjit.h
+++ b/gcc/jit/libgccjit.h
@@ -1110,6 +1110,20 @@ extern void
gcc_jit_lvalue_set_tls_model (gcc_jit_lvalue *lvalue,
enum gcc_jit_tls_model model);
+#define LIBGCCJIT_HAVE_gcc_jit_lvalue_set_link_section
+
+/* Set the link section of a global variable; analogous to:
+ __attribute__((section(".section_name")))
+ in C.
+
+ This API entrypoint was added in LIBGCCJIT_ABI_18; you can test for its
+ presence using
+ #ifdef LIBGCCJIT_HAVE_gcc_jit_lvalue_set_link_section
+*/
+extern void
+gcc_jit_lvalue_set_link_section (gcc_jit_lvalue *lvalue,
+ const char *section_name);
+
extern gcc_jit_lvalue *
gcc_jit_function_new_local (gcc_jit_function *func,
gcc_jit_location *loc,
diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map
index 98d693f..b176711 100644
--- a/gcc/jit/libgccjit.map
+++ b/gcc/jit/libgccjit.map
@@ -231,3 +231,8 @@ LIBGCCJIT_ABI_17 {
global:
gcc_jit_lvalue_set_tls_model;
} LIBGCCJIT_ABI_16;
+
+LIBGCCJIT_ABI_18 {
+ global:
+ gcc_jit_lvalue_set_link_section;
+} LIBGCCJIT_ABI_17;
diff --git a/gcc/machmode.h b/gcc/machmode.h
index 2e5bafd..5a43c66 100644
--- a/gcc/machmode.h
+++ b/gcc/machmode.h
@@ -1199,7 +1199,7 @@ gt_pch_nx (pod_mode<T> *)
template<typename T>
void
-gt_pch_nx (pod_mode<T> *, void (*) (void *, void *, void *), void *)
+gt_pch_nx (pod_mode<T> *, gt_pointer_operator, void *)
{
}
diff --git a/gcc/poly-int.h b/gcc/poly-int.h
index 60a38c3..f7226e6 100644
--- a/gcc/poly-int.h
+++ b/gcc/poly-int.h
@@ -2717,7 +2717,7 @@ gt_pch_nx (poly_int_pod<N, C> *)
template<unsigned int N, typename C>
void
-gt_pch_nx (poly_int_pod<N, C> *, void (*) (void *, void *, void *), void *)
+gt_pch_nx (poly_int_pod<N, C> *, gt_pointer_operator, void *)
{
}
diff --git a/gcc/selftest-run-tests.c b/gcc/selftest-run-tests.c
index 6a8f291..8eb1239 100644
--- a/gcc/selftest-run-tests.c
+++ b/gcc/selftest-run-tests.c
@@ -71,7 +71,6 @@ selftest::run_tests ()
sreal_c_tests ();
fibonacci_heap_c_tests ();
typed_splay_tree_c_tests ();
- unique_ptr_tests_cc_tests ();
opt_proposer_c_tests ();
opts_c_tests ();
json_cc_tests ();
diff --git a/gcc/selftest.h b/gcc/selftest.h
index 24ef57cb..e6c7fc3 100644
--- a/gcc/selftest.h
+++ b/gcc/selftest.h
@@ -262,7 +262,6 @@ extern void tree_cfg_c_tests ();
extern void tree_diagnostic_path_cc_tests ();
extern void tristate_cc_tests ();
extern void typed_splay_tree_c_tests ();
-extern void unique_ptr_tests_cc_tests ();
extern void vec_c_tests ();
extern void vec_perm_indices_c_tests ();
extern void wide_int_cc_tests ();
diff --git a/gcc/system.h b/gcc/system.h
index 4ac656c..2cd2017 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -737,12 +737,10 @@ extern int vsnprintf (char *, size_t, const char *, va_list);
/* Some of the headers included by <memory> can use "abort" within a
namespace, e.g. "_VSTD::abort();", which fails after we use the
- preprocessor to redefine "abort" as "fancy_abort" below.
- Given that unique-ptr.h can use "free", we need to do this after "free"
- is declared but before "abort" is overridden. */
+ preprocessor to redefine "abort" as "fancy_abort" below. */
-#ifdef INCLUDE_UNIQUE_PTR
-# include "unique-ptr.h"
+#ifdef INCLUDE_MEMORY
+# include <memory>
#endif
#ifdef INCLUDE_MALLOC_H
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 2da36cf..836fa33 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,18 @@
2021-12-12 Antoni Boucher <bouanto@zoho.com>
+ PR target/100688
+ * jit.dg/all-non-failing-tests.h: Mention new test
+ link-section-assembler.
+ * jit.dg/test-link-section-assembler.c: New test.
+ * jit.dg/jit.exp: New helper function to test that the
+ assembly contains a pattern.
+
+2021-12-12 Roger Sayle <roger@nextmovesoftware.com>
+
+ * gcc.target/nvptx/float16-1.c: New test case.
+
+2021-12-12 Antoni Boucher <bouanto@zoho.com>
+
PR target/95415
* jit.dg/all-non-failing-tests.h: Add test-tls.c.
* jit.dg/test-tls.c: New test.
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr103513.c b/gcc/testsuite/gcc.c-torture/compile/pr103513.c
new file mode 100644
index 0000000..ca876a9
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr103513.c
@@ -0,0 +1,8 @@
+int a;
+void b(int c) {
+ int d = 3;
+ d ^= c < 2;
+ if (d < 3 && a)
+ while (1)
+ b(!a);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/pr103515.c b/gcc/testsuite/gcc.target/powerpc/pr103515.c
new file mode 100644
index 0000000..698b9a9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr103515.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-rtl-loop2_unroll-optimized" } */
+
+/* The pragma specified for foo2 should not affect foo1.
+ Verify compiler won't perform unrolling for foo1. */
+
+#define N 1024
+extern int a1[N], b1[N], c1[N];
+extern int a2[N], b2[N], c2[N];
+extern int n;
+
+void
+foo1 ()
+{
+ int i;
+ for (i = 0; i < n; i++)
+ c1[i] += a1[i] + b1[i];
+}
+
+#pragma GCC optimize("O3,unroll-loops")
+void
+foo2 ()
+{
+ int i;
+ for (i = 0; i < n; i++)
+ c2[i] += a2[i] + b2[i];
+}
+
+/* { dg-final { scan-rtl-dump-times "optimized: loop unrolled" 1 "loop2_unroll" } } */
+
diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h
index 350a30b..3e8ccbc 100644
--- a/gcc/testsuite/jit.dg/all-non-failing-tests.h
+++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h
@@ -209,6 +209,9 @@
#undef create_code
#undef verify_code
+/* test-link-section-assembler.c: This can't be in the testcases array as it
+ doesn't have a verify_code implementation. */
+
/* test-linked-list.c */
#define create_code create_code_linked_list
#define verify_code verify_code_linked_list
diff --git a/gcc/testsuite/jit.dg/jit.exp b/gcc/testsuite/jit.dg/jit.exp
index 10b98bd..3568dbb 100644
--- a/gcc/testsuite/jit.dg/jit.exp
+++ b/gcc/testsuite/jit.dg/jit.exp
@@ -864,6 +864,39 @@ proc jit-verify-assembler { args } {
jit-run-executable ${executable_from_asm} ${dg-output-text}
}
+# Assuming that a .s file has been written out named
+# OUTPUT_FILENAME, check that the argument matches the
+# output file.
+# For use by the test-link-section-assembler.c testcase.
+proc jit-verify-assembler-output { args } {
+ verbose "jit-verify-assembler: $args"
+
+ set dg-output-text [lindex $args 0]
+ verbose "dg-output-text: ${dg-output-text}"
+
+ upvar 2 name name
+ verbose "name: $name"
+
+ upvar 2 prog prog
+ verbose "prog: $prog"
+ set asm_filename [jit-get-output-filename $prog]
+ verbose " asm_filename: ${asm_filename}"
+
+ # Read the assembly file.
+ set f [open $asm_filename r]
+ set content [read $f]
+ close $f
+
+ # Verify that the assembly matches the regex.
+ if { ![regexp ${dg-output-text} $content] } {
+ fail "${asm_filename} output pattern test, is ${content}, should match ${dg-output-text}"
+ verbose "Failed test for output pattern ${dg-output-text}" 3
+ } else {
+ pass "${asm_filename} output pattern test, ${dg-output-text}"
+ verbose "Passed test for output pattern ${dg-output-text}" 3
+ }
+
+}
# Assuming that a .o file has been written out named
# OUTPUT_FILENAME, invoke the driver to try to turn it into
# an executable, and try to run the result.
diff --git a/gcc/testsuite/jit.dg/test-link-section-assembler.c b/gcc/testsuite/jit.dg/test-link-section-assembler.c
new file mode 100644
index 0000000..a90b00e
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-link-section-assembler.c
@@ -0,0 +1,37 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+
+#define TEST_COMPILING_TO_FILE
+#define OUTPUT_KIND GCC_JIT_OUTPUT_KIND_ASSEMBLER
+#define OUTPUT_FILENAME "output-of-test-link-section-assembler.c.s"
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ /* Let's try to inject the equivalent of:
+ int foo __attribute__((section(".section")));
+ */
+ gcc_jit_type *int_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+ gcc_jit_lvalue *foo =
+ gcc_jit_context_new_global (
+ ctxt, NULL, GCC_JIT_GLOBAL_EXPORTED, int_type, "foo");
+ gcc_jit_lvalue_set_link_section(foo, ".my_section");
+
+ gcc_jit_function *func_main =
+ gcc_jit_context_new_function (ctxt, NULL,
+ GCC_JIT_FUNCTION_EXPORTED,
+ int_type,
+ "main",
+ 0, NULL,
+ 0);
+ gcc_jit_rvalue *zero = gcc_jit_context_zero (ctxt, int_type);
+ gcc_jit_block *block = gcc_jit_function_new_block (func_main, NULL);
+ gcc_jit_block_end_with_return (block, NULL, zero);
+}
+
+/* { dg-final { jit-verify-output-file-was-created "" } } */
+/* { dg-final { jit-verify-assembler-output ".section .my_section" } } */
diff --git a/gcc/unique-ptr-tests.cc b/gcc/unique-ptr-tests.cc
deleted file mode 100644
index 975dd57..0000000
--- a/gcc/unique-ptr-tests.cc
+++ /dev/null
@@ -1,236 +0,0 @@
-/* Unit tests for unique-ptr.h.
- Copyright (C) 2017-2021 Free Software Foundation, Inc.
-
-This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 3, or (at your option) any later
-version.
-
-GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3. If not see
-<http://www.gnu.org/licenses/>. */
-
-#include "config.h"
-#define INCLUDE_UNIQUE_PTR
-#include "system.h"
-#include "coretypes.h"
-#include "selftest.h"
-
-#if CHECKING_P
-
-namespace selftest {
-
-namespace {
-
-/* A class for counting ctor and dtor invocations. */
-
-class stats
-{
-public:
- stats () : ctor_count (0), dtor_count (0) {}
-
- int ctor_count;
- int dtor_count;
-};
-
-/* A class that uses "stats" to track its ctor and dtor invocations. */
-
-class foo
-{
-public:
- foo (stats &s) : m_s (s) { ++m_s.ctor_count; }
- ~foo () { ++m_s.dtor_count; }
-
- int example_method () const { return 42; }
-
-private:
- foo (const foo&);
- foo & operator= (const foo &);
-
-private:
- stats &m_s;
-};
-
-/* A struct for testing unique_ptr<T[]>. */
-
-class has_default_ctor
-{
-public:
- has_default_ctor () : m_field (42) {}
- int m_field;
-};
-
-/* A dummy struct for testing unique_xmalloc_ptr. */
-
-struct dummy
-{
- int field;
-};
-
-} // anonymous namespace
-
-/* Verify that the default ctor inits ptrs to NULL. */
-
-static void
-test_null_ptr ()
-{
- gnu::unique_ptr<void *> p;
- ASSERT_EQ (NULL, p);
-
- gnu::unique_xmalloc_ptr<void *> q;
- ASSERT_EQ (NULL, q);
-}
-
-/* Verify that deletion happens when a unique_ptr goes out of scope. */
-
-static void
-test_implicit_deletion ()
-{
- stats s;
- ASSERT_EQ (0, s.ctor_count);
- ASSERT_EQ (0, s.dtor_count);
-
- {
- gnu::unique_ptr<foo> f (new foo (s));
- ASSERT_NE (NULL, f);
- ASSERT_EQ (1, s.ctor_count);
- ASSERT_EQ (0, s.dtor_count);
- }
-
- /* Verify that the foo was implicitly deleted. */
- ASSERT_EQ (1, s.ctor_count);
- ASSERT_EQ (1, s.dtor_count);
-}
-
-/* Verify that we can assign to a NULL unique_ptr. */
-
-static void
-test_overwrite_of_null ()
-{
- stats s;
- ASSERT_EQ (0, s.ctor_count);
- ASSERT_EQ (0, s.dtor_count);
-
- {
- gnu::unique_ptr<foo> f;
- ASSERT_EQ (NULL, f);
- ASSERT_EQ (0, s.ctor_count);
- ASSERT_EQ (0, s.dtor_count);
-
- /* Overwrite with a non-NULL value. */
- f = gnu::unique_ptr<foo> (new foo (s));
- ASSERT_EQ (1, s.ctor_count);
- ASSERT_EQ (0, s.dtor_count);
- }
-
- /* Verify that the foo is implicitly deleted. */
- ASSERT_EQ (1, s.ctor_count);
- ASSERT_EQ (1, s.dtor_count);
-}
-
-/* Verify that we can assign to a non-NULL unique_ptr. */
-
-static void
-test_overwrite_of_non_null ()
-{
- stats s;
- ASSERT_EQ (0, s.ctor_count);
- ASSERT_EQ (0, s.dtor_count);
-
- {
- gnu::unique_ptr<foo> f (new foo (s));
- ASSERT_NE (NULL, f);
- ASSERT_EQ (1, s.ctor_count);
- ASSERT_EQ (0, s.dtor_count);
-
- /* Overwrite with a different value. */
- f = gnu::unique_ptr<foo> (new foo (s));
- ASSERT_EQ (2, s.ctor_count);
- ASSERT_EQ (1, s.dtor_count);
- }
-
- /* Verify that the 2nd foo was implicitly deleted. */
- ASSERT_EQ (2, s.ctor_count);
- ASSERT_EQ (2, s.dtor_count);
-}
-
-/* Verify that unique_ptr's overloaded ops work. */
-
-static void
-test_overloaded_ops ()
-{
- stats s;
- gnu::unique_ptr<foo> f (new foo (s));
- ASSERT_EQ (42, f->example_method ());
- ASSERT_EQ (42, (*f).example_method ());
- ASSERT_EQ (f, f);
- ASSERT_NE (NULL, f.get ());
-
- gnu::unique_ptr<foo> g (new foo (s));
- ASSERT_NE (f, g);
-}
-
-/* Verify that the gnu::unique_ptr specialization for T[] works. */
-
-static void
-test_array_new ()
-{
- const int num = 10;
- gnu::unique_ptr<has_default_ctor[]> p (new has_default_ctor[num]);
- ASSERT_NE (NULL, p.get ());
- /* Verify that operator[] works, and that the default ctor was called
- on each element. */
- for (int i = 0; i < num; i++)
- ASSERT_EQ (42, p[i].m_field);
-}
-
-/* Verify that gnu::unique_xmalloc_ptr works. */
-
-static void
-test_xmalloc ()
-{
- gnu::unique_xmalloc_ptr<dummy> p (XNEW (dummy));
- ASSERT_NE (NULL, p.get ());
-}
-
-/* Verify the gnu::unique_xmalloc_ptr specialization for T[]. */
-
-static void
-test_xmalloc_array ()
-{
- const int num = 10;
- gnu::unique_xmalloc_ptr<dummy[]> p (XNEWVEC (dummy, num));
- ASSERT_NE (NULL, p.get ());
-
- /* Verify that operator[] works. */
- for (int i = 0; i < num; i++)
- p[i].field = 42;
- for (int i = 0; i < num; i++)
- ASSERT_EQ (42, p[i].field);
-}
-
-/* Run all of the selftests within this file. */
-
-void
-unique_ptr_tests_cc_tests ()
-{
- test_null_ptr ();
- test_implicit_deletion ();
- test_overwrite_of_null ();
- test_overwrite_of_non_null ();
- test_overloaded_ops ();
- test_array_new ();
- test_xmalloc ();
- test_xmalloc_array ();
-}
-
-} // namespace selftest
-
-#endif /* #if CHECKING_P */
diff --git a/gcc/wide-int.h b/gcc/wide-int.h
index d03a174..bc51aa9 100644
--- a/gcc/wide-int.h
+++ b/gcc/wide-int.h
@@ -3338,7 +3338,7 @@ gt_pch_nx (generic_wide_int <T> *)
template<typename T>
void
-gt_pch_nx (generic_wide_int <T> *, void (*) (void *, void *, void *), void *)
+gt_pch_nx (generic_wide_int <T> *, gt_pointer_operator, void *)
{
}
@@ -3356,7 +3356,7 @@ gt_pch_nx (trailing_wide_ints <N> *)
template<int N>
void
-gt_pch_nx (trailing_wide_ints <N> *, void (*) (void *, void *, void *), void *)
+gt_pch_nx (trailing_wide_ints <N> *, gt_pointer_operator, void *)
{
}
diff --git a/include/ChangeLog b/include/ChangeLog
index 88f15e4..6f5f7a9 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,7 @@
+2021-12-12 Jonathan Wakely <jwakely@redhat.com>
+
+ * unique-ptr.h: Removed.
+
2021-12-10 Andrew Stubbs <ams@codesourcery.com>
* gomp-constants.h (GOMP_VERSION_GCN): Bump.
diff --git a/include/unique-ptr.h b/include/unique-ptr.h
deleted file mode 100644
index d1b2ba5..0000000
--- a/include/unique-ptr.h
+++ /dev/null
@@ -1,405 +0,0 @@
-/* gnu::unique_ptr, a simple std::unique_ptr replacement for C++03.
-
- Copyright (C) 2007-2021 Free Software Foundation, Inc.
-
- This file is part of GCC.
-
- This program 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.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-/* gnu::unique_ptr defines a C++ owning smart pointer that exposes a
- subset of the std::unique_ptr API.
-
- In fact, when compiled with a C++11 compiler, gnu::unique_ptr
- actually _is_ std::unique_ptr. When compiled with a C++03 compiler
- OTOH, it's an hand coded std::unique_ptr emulation that assumes
- code is correct and doesn't try to be too smart.
-
- This supports custom deleters, but not _stateful_ deleters, so you
- can't use those in C++11 mode either. Only the managed pointer is
- stored in the smart pointer. That could be changed; it simply
- wasn't found necessary.
-
- At the end of the file you'll find a gnu::unique_ptr partial
- specialization that uses a custom (stateless) deleter:
- gnu::unique_xmalloc_ptr. That is used to manage pointers to
- objects allocated with xmalloc.
-
- The C++03 version was originally based on GCC 7.0's std::auto_ptr
- and then heavily customized to behave more like C++11's
- std::unique_ptr, but at this point, it no longer shares much at all
- with the original file. But, that's the history and the reason for
- the copyright's starting year.
-
- The C++03 version lets you shoot yourself in the foot, since
- similarly to std::auto_ptr, the copy constructor and assignment
- operators actually move. Also, in the name of simplicity, no
- effort is spent on using SFINAE to prevent invalid conversions,
- etc. This is not really a problem, because the goal here is to
- allow code that would be correct using std::unique_ptr to be
- equally correct in C++03 mode, and, just as efficient. If client
- code compiles correctly with a C++11 (or newer) compiler, we know
- we're not doing anything invalid by mistake.
-
- Usage notes:
-
- - Putting gnu::unique_ptr in standard containers is not supported,
- since C++03 containers are not move-aware (and our emulation
- relies on copy actually moving).
-
- - Since there's no nullptr in C++03, gnu::unique_ptr allows
- implicit initialization and assignment from NULL instead.
-
- - To check whether there's an associated managed object, all these
- work as expected:
-
- if (ptr)
- if (!ptr)
- if (ptr != NULL)
- if (ptr == NULL)
- if (NULL != ptr)
- if (NULL == ptr)
-*/
-
-#ifndef GNU_UNIQUE_PTR_H
-#define GNU_UNIQUE_PTR_H 1
-
-#if __cplusplus >= 201103
-# include <memory>
-#endif
-
-namespace gnu
-{
-
-#if __cplusplus >= 201103
-
-/* In C++11 mode, all we need is import the standard
- std::unique_ptr. */
-template<typename T> using unique_ptr = std::unique_ptr<T>;
-
-/* Pull in move as well. */
-using std::move;
-
-#else /* C++11 */
-
-/* Default destruction policy used by gnu::unique_ptr when no deleter
- is specified. Uses delete. */
-
-template<typename T>
-struct default_delete
-{
- void operator () (T *ptr) const { delete ptr; }
-};
-
-/* Specialization for arrays. Uses delete[]. */
-
-template<typename T>
-struct default_delete<T[]>
-{
- void operator () (T *ptr) const { delete [] ptr; }
-};
-
-namespace detail
-{
-/* Type used to support implicit construction from NULL:
-
- gnu::unique_ptr<foo> func (....)
- {
- return NULL;
- }
-
- and assignment from NULL:
-
- gnu::unique_ptr<foo> ptr (....);
- ...
- ptr = NULL;
-
- It is intentionally not defined anywhere. */
-struct nullptr_t;
-
-/* Base class of our unique_ptr emulation. Contains code common to
- both unique_ptr<T, D> and unique_ptr<T[], D>. */
-
-template<typename T, typename D>
-class unique_ptr_base
-{
-public:
- typedef T *pointer;
- typedef T element_type;
- typedef D deleter_type;
-
- /* Takes ownership of a pointer. P is a pointer to an object of
- element_type type. Defaults to NULL. */
- explicit unique_ptr_base (element_type *p = NULL) throw () : m_ptr (p) {}
-
- /* The "move" constructor. Really a copy constructor that actually
- moves. Even though std::unique_ptr is not copyable, our little
- simpler emulation allows it, because:
-
- - There are no rvalue references in C++03. Our move emulation
- instead relies on copy/assignment moving, like std::auto_ptr.
- - RVO/NRVO requires an accessible copy constructor
- */
- unique_ptr_base (const unique_ptr_base &other) throw ()
- : m_ptr (const_cast<unique_ptr_base &> (other).release ()) {}
-
- /* Converting "move" constructor. Really an lvalue ref converting
- constructor that actually moves. This allows constructs such as:
-
- unique_ptr<Derived> func_returning_unique_ptr (.....);
- ...
- unique_ptr<Base> ptr = func_returning_unique_ptr (.....);
- */
- template<typename T1, typename D1>
- unique_ptr_base (const unique_ptr_base<T1, D1> &other) throw ()
- : m_ptr (const_cast<unique_ptr_base<T1, D1> &> (other).release ()) {}
-
- /* The "move" assignment operator. Really an lvalue ref copy
- assignment operator that actually moves. See comments above. */
- unique_ptr_base &operator= (const unique_ptr_base &other) throw ()
- {
- reset (const_cast<unique_ptr_base &> (other).release ());
- return *this;
- }
-
- /* Converting "move" assignment. Really an lvalue ref converting
- copy assignment operator that moves. See comments above. */
- template<typename T1, typename D1>
- unique_ptr_base &operator= (const unique_ptr_base<T1, D1> &other) throw ()
- {
- reset (const_cast<unique_ptr_base<T1, D1> &> (other).release ());
- return *this;
- }
-
- /* std::unique_ptr does not allow assignment, except from nullptr.
- nullptr doesn't exist in C++03, so we allow assignment from NULL
- instead [ptr = NULL;].
- */
- unique_ptr_base &operator= (detail::nullptr_t *) throw ()
- {
- reset ();
- return *this;
- }
-
- ~unique_ptr_base () { call_deleter (); }
-
- /* "explicit operator bool ()" emulation using the safe bool
- idiom. */
-private:
- typedef void (unique_ptr_base::*explicit_operator_bool) () const;
- void this_type_does_not_support_comparisons () const {}
-
-public:
- operator explicit_operator_bool () const
- {
- return (m_ptr != NULL
- ? &unique_ptr_base::this_type_does_not_support_comparisons
- : 0);
- }
-
- element_type *get () const throw () { return m_ptr; }
-
- element_type *release () throw ()
- {
- pointer tmp = m_ptr;
- m_ptr = NULL;
- return tmp;
- }
-
- void reset (element_type *p = NULL) throw ()
- {
- if (p != m_ptr)
- {
- call_deleter ();
- m_ptr = p;
- }
- }
-
-private:
-
- /* Call the deleter. Note we assume the deleter is "stateless". */
- void call_deleter ()
- {
- D d;
-
- d (m_ptr);
- }
-
- element_type *m_ptr;
-};
-
-} /* namespace detail */
-
-/* Macro used to create a unique_ptr_base "partial specialization" --
- a subclass that uses a specific deleter. Basically this re-defines
- the necessary constructors. This is necessary because C++03
- doesn't support inheriting constructors with "using". While at it,
- we inherit the assignment operator. TYPE is the name of the type
- being defined. Assumes that 'base_type' is a typedef of the
- baseclass TYPE is inheriting from. */
-#define DEFINE_GNU_UNIQUE_PTR(TYPE) \
-public: \
- explicit TYPE (T *p = NULL) throw () \
- : base_type (p) {} \
- \
- TYPE (const TYPE &other) throw () : base_type (other) {} \
- \
- TYPE (detail::nullptr_t *) throw () : base_type (NULL) {} \
- \
- template<typename T1, typename D1> \
- TYPE (const detail::unique_ptr_base<T1, D1> &other) throw () \
- : base_type (other) {} \
- \
- using base_type::operator=;
-
-/* Define single-object gnu::unique_ptr. */
-
-template <typename T, typename D = default_delete<T> >
-class unique_ptr : public detail::unique_ptr_base<T, D>
-{
- typedef detail::unique_ptr_base<T, D> base_type;
-
- DEFINE_GNU_UNIQUE_PTR (unique_ptr)
-
-public:
- /* Dereferencing. */
- T &operator* () const throw () { return *this->get (); }
- T *operator-> () const throw () { return this->get (); }
-};
-
-/* Define gnu::unique_ptr specialization for T[]. */
-
-template <typename T, typename D>
-class unique_ptr<T[], D> : public detail::unique_ptr_base<T, D>
-{
- typedef detail::unique_ptr_base<T, D> base_type;
-
- DEFINE_GNU_UNIQUE_PTR (unique_ptr)
-
-public:
- /* Indexing operator. */
- T &operator[] (size_t i) const { return this->get ()[i]; }
-};
-
-/* Comparison operators. */
-
-template <typename T, typename D,
- typename U, typename E>
-inline bool
-operator== (const detail::unique_ptr_base<T, D> &x,
- const detail::unique_ptr_base<U, E> &y)
-{ return x.get() == y.get(); }
-
-template <typename T, typename D,
- typename U, typename E>
-inline bool
-operator!= (const detail::unique_ptr_base<T, D> &x,
- const detail::unique_ptr_base<U, E> &y)
-{ return x.get() != y.get(); }
-
-template<typename T, typename D,
- typename U, typename E>
-inline bool
-operator< (const detail::unique_ptr_base<T, D> &x,
- const detail::unique_ptr_base<U, E> &y)
-{ return x.get() < y.get (); }
-
-template<typename T, typename D,
- typename U, typename E>
-inline bool
-operator<= (const detail::unique_ptr_base<T, D> &x,
- const detail::unique_ptr_base<U, E> &y)
-{ return !(y < x); }
-
-template<typename T, typename D,
- typename U, typename E>
-inline bool
-operator> (const detail::unique_ptr_base<T, D> &x,
- const detail::unique_ptr_base<U, E> &y)
-{ return y < x; }
-
-template<typename T, typename D,
- typename U, typename E>
-inline bool
-operator>= (const detail::unique_ptr_base<T, D> &x,
- const detail::unique_ptr_base<U, E> &y)
-{ return !(x < y); }
-
-/* std::move "emulation". This is as simple as it can be -- no
- attempt is made to emulate rvalue references. This relies on T
- having move semantics like std::auto_ptr.
- I.e., copy/assignment actually moves. */
-
-template<typename T>
-const T&
-move (T& v)
-{
- return v;
-}
-
-#endif /* C++11 */
-
-/* Define gnu::unique_xmalloc_ptr, a gnu::unique_ptr that manages
- xmalloc'ed memory. */
-
-/* The deleter for gnu::unique_xmalloc_ptr. Uses free. */
-template <typename T>
-struct xmalloc_deleter
-{
- void operator() (T *ptr) const { free (ptr); }
-};
-
-/* Same, for arrays. */
-template <typename T>
-struct xmalloc_deleter<T[]>
-{
- void operator() (T *ptr) const { free (ptr); }
-};
-
-#if __cplusplus >= 201103
-
-/* In C++11, we just import the standard unique_ptr to our namespace
- with a custom deleter. */
-
-template<typename T> using unique_xmalloc_ptr
- = std::unique_ptr<T, xmalloc_deleter<T>>;
-
-#else /* C++11 */
-
-/* In C++03, we don't have template aliases, so we need to define a
- subclass instead, and re-define the constructors, because C++03
- doesn't support inheriting constructors either. */
-
-template <typename T>
-class unique_xmalloc_ptr : public unique_ptr<T, xmalloc_deleter<T> >
-{
- typedef unique_ptr<T, xmalloc_deleter<T> > base_type;
-
- DEFINE_GNU_UNIQUE_PTR (unique_xmalloc_ptr)
-};
-
-/* Define gnu::unique_xmalloc_ptr specialization for T[]. */
-
-template <typename T>
-class unique_xmalloc_ptr<T[]> : public unique_ptr<T[], xmalloc_deleter<T[]> >
-{
- typedef unique_ptr<T[], xmalloc_deleter<T[]> > base_type;
-
- DEFINE_GNU_UNIQUE_PTR (unique_xmalloc_ptr)
-};
-
-#endif /* C++11 */
-
-} /* namespace gnu */
-
-#endif /* GNU_UNIQUE_PTR_H */