Commit Graph

60 Commits

Author SHA1 Message Date
Louis Dionne 3560fbf304 [libc++] Improve diagnostics for non-const comparators and hashers in associative containers
Summary:
When providing a non-const-callable comparator in a map or set, the
warning diagnostic does not include the point of instantiation of
the container that triggered the warning, which makes it difficult
to track down the problem. This commit improves the diagnostic by
placing it directly in the body of the associative container.

The same change is applied to unordered associative containers, which
had a similar problem.

Finally, this commit cleans up the forward declarations of several
map and unordered_map helpers, which are not needed anymore.

<rdar://problem/41370747>

Reviewers: EricWF, mclow.lists

Subscribers: christof, dexonsmith, llvm-commits

Differential Revision: https://reviews.llvm.org/D48955

llvm-svn: 348529
2018-12-06 21:46:17 +00:00
Erik Pilkington 5c4e07ae5c Second half of C++17's splicing maps and sets
This commit adds a merge member function to all the map and set containers,
which splices nodes from the source container. This completes support for
P0083r3.

Differential revision: https://reviews.llvm.org/D48896

llvm-svn: 345744
2018-10-31 17:31:35 +00:00
Louis Dionne 7c3492b00d [NFC][libc++] Consistently use spaces to indent
rdar://problem/19988944

llvm-svn: 338933
2018-08-03 22:36:53 +00:00
Erik Pilkington b0386a515b First half of C++17's splicing maps and sets
This commit adds a node handle type, (located in __node_handle), and adds
extract() and insert() members to all map and set types, as well as their
implementations in __tree and __hash_table.

The second half of this feature is adding merge() members, which splice nodes
in bulk from one container into another. This will be committed in a follow-up.

Differential revision: https://reviews.llvm.org/D46845

llvm-svn: 338472
2018-08-01 01:33:38 +00:00
Erik Pilkington f52318b47b Fix a strict aliasing violation in map and unordered_map.
These containers type-punned between pair<K, V> and pair<const K, V> as an
optimization. This commit instead provides access to the pair via a pair of
references that assign through to the underlying object. It's still undefined to
mutate a const object, but clang doesn't optimize on this for data members, so
this should be safe.

Differential revision: https://reviews.llvm.org/D47607

llvm-svn: 333948
2018-06-04 20:38:23 +00:00
Joerg Sonnenberger 7e680f15a5 Spelling
llvm-svn: 311156
2017-08-18 12:57:36 +00:00
Eric Fiselier a016efb1dc [Libc++] Use #pragma push_macro/pop_macro to better handle min/max on Windows
Summary:
This patch improves how libc++ handles min/max macros within the headers. Previously libc++ would undef them and emit a warning.
This patch changes libc++ to use `#pragma push_macro`  to save the macro before undefining it, and `#pragma pop_macro` to restore the macros and the end of the header.

Reviewers: mclow.lists, bcraig, compnerd, EricWF

Reviewed By: EricWF

Subscribers: cfe-commits, krytarowski

Differential Revision: https://reviews.llvm.org/D33080

llvm-svn: 304357
2017-05-31 22:07:49 +00:00
Eric Fiselier afa7a957bd Cleanup remaining _LIBCPP_HAS_NO_<c++11-feature> usages in container headers
llvm-svn: 300643
2017-04-19 01:23:04 +00:00
Eric Fiselier e1ec29869b Fix most failures caused by r300140
r300140 introduced a bunch of failures by changing the internal
interface provided by __compressed_pair. This patch fixes all of
the failures caused by the new interface by changing the existing
code to use it.

In addition to those changes this patch also fixes two separate
issues causing test failures:

1) Fix the member swap definition for __map_value_compare. Previously
   the swap was incorrectly configured to swap the comparator as const.

2) Fix an assertion failure in futures.task.members/ctor_func_alloc.pass.cpp
that incorrectly expected a move to take place when a single copy is sufficient.

There is one remaining failure regarding make_shared. I'll commit a fix for that
shortly.

llvm-svn: 300148
2017-04-13 00:34:24 +00:00
Eric Fiselier fb5c750222 Undefine min/max in __tree
llvm-svn: 294099
2017-02-04 20:27:46 +00:00
Eric Fiselier 04333f9bda Diagnose non-const-callable hash functions and comparators
llvm-svn: 291969
2017-01-13 22:42:53 +00:00
Eric Fiselier b1e7a12ee8 Add _LIBCPP_DIAGNOSE_WARNING and _LIBCPP_DIAGNOSE_ERROR macros.
Clang recently added a `diagnose_if(cond, msg, type)` attribute
which can be used to generate diagnostics when `cond` is a constant
expression that evaluates to true. Otherwise no attribute has no
effect.

This patch adds _LIBCPP_DIAGNOSE_ERROR/WARNING macros which
use this new attribute. Additionally this patch implements
a diagnostic message when a non-const-callable comparator is
given to a container.

Note: For now the warning version of the diagnostic is useless
within libc++ since warning diagnostics are suppressed by the
system header pragma. I'm going to work on fixing this.

llvm-svn: 291961
2017-01-13 22:02:08 +00:00
Eric Fiselier cb5cbc8b66 [libcxx] Fix PR31402: map::__find_equal_key has undefined behavior.
Summary:
This patch fixes llvm.org/PR31402 by replacing `map::__find_equal_key` with `__tree::__find_equal`, which has already addressed the same undefined behavior.

Unfortunately I haven't been able to write a test case which causes the UBSAN diagnostic mentioned in the bug report. I can write tests which exercise the UB but for some reason they do not cause UBSAN to fail. Any help writing a test case would be appreciated.


Reviewers: mclow.lists, vsk, EricWF

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D28131

llvm-svn: 291087
2017-01-05 06:06:18 +00:00
Eric Fiselier e2f2d1edef [NFC] Rename _LIBCPP_TYPE_VIS_ONLY to _LIBCPP_TEMPLATE_VIS
The name _LIBCPP_TYPE_VIS_ONLY is no longer accurate because both
_LIBCPP_TYPE_VIS and _LIBCPP_TYPE_VIS_ONLY expand to
__attribute__((__type_visibility__)) with Clang. The only remaining difference
is that _LIBCPP_TYPE_VIS_ONLY can be applied to templates whereas
_LIBCPP_TYPE_VIS cannot (due to dllimport/dllexport not being allowed on
templates).

This patch renames _LIBCPP_TYPE_VIS_ONLY to _LIBCPP_TEMPLATE_VIS.

llvm-svn: 291035
2017-01-04 23:56:00 +00:00
Eric Fiselier fd83822741 Fix unused parameters and variables
llvm-svn: 290459
2016-12-23 23:37:52 +00:00
Eric Fiselier 55b31b4e69 [libcxx] Fix max_size() across all containers
Summary: The `max_size()` method of containers should respect both the allocator's reported `max_size` and the range of the `difference_type`. This patch makes all containers choose the smallest of those two values.

Reviewers: mclow.lists, EricWF

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D26885

llvm-svn: 287729
2016-11-23 01:18:56 +00:00
Dimitry Andric f8563f3206 Avoid embedded preprocessor directives in __tree
Similar to rL242623, move C++ version checks outside of _NOEXCEPT_()
macro invocation argument lists, to avoid "embedding a directive within
macro arguments has undefined behavior" warnings.

Differential Revision: https://reviews.llvm.org/D23961

llvm-svn: 279926
2016-08-27 19:32:03 +00:00
Marshall Clow d4e8659dfc make the associative containers do the right thing for propogate_on_container_assignment. Fixes bug #29001. Tests are only for <map> right now - more complete tests will come when we revamp our allocator testing structure.
llvm-svn: 279008
2016-08-17 23:24:02 +00:00
Eric Fiselier d05b10ab4f Fix undefined behavior in __tree
Summary:
This patch attempts to fix the undefined behavior in __tree by changing the node pointer types used throughout. The pointer types are changed for raw pointers in the current ABI and for fancy pointers in ABI V2 (since the fancy pointer types may not be ABI compatible).

The UB in `__tree` arises because tree downcasts the embedded end node and then deferences that pointer. Currently there are 3 node types in __tree.

* `__tree_end_node` which contains the `__left_` pointer. This node is embedded within the container.
* `__tree_node_base` which contains `__right_`, `__parent_` and `__is_black`. This node is used throughout the tree rebalancing algorithms.
* `__tree_node` which contains `__value_`.

Currently `__tree` stores the start of the tree, `__begin_node_`, as a pointer to a `__tree_node`. Additionally the iterators store their position as a pointer to a `__tree_node`. In both of these cases the pointee can be the end node. This is fixed by changing them to store `__tree_end_node` pointers instead.

To make this change I introduced an `__iter_pointer` typedef which is defined to be a pointer to either `__tree_end_node` in the new ABI or `__tree_node` in the current one.
Both `__tree::__begin_node_` and iterator pointers are now stored as `__iter_pointers`.

The other situation where `__tree_end_node` is stored as the wrong type is in `__tree_node_base::__parent_`.  Currently `__left_`, `__right_`, and `__parent_` are all `__tree_node_base` pointers. Since the end node will only be stored in `__parent_` the fix is to change `__parent_` to be a pointer to `__tree_end_node`.

To make this change I introduced a `__parent_pointer` typedef which is defined to be a pointer to either `__tree_end_node` in the new ABI or `__tree_node_base` in the current one.

Note that in the new ABI `__iter_pointer` and `__parent_pointer` are the same type (but not in the old one). The confusion between these two types is unfortunate but it was the best solution I could come up with that maintains the ABI.

The typedef changes force a ton of explicit type casts to correct pointer types and to make current code compatible with both the old and new pointer typedefs. This is the bulk of the change and it's really messy. Unfortunately I don't know how to avoid it.

Please let me know what you think.





Reviewers: howard.hinnant, mclow.lists

Subscribers: howard.hinnant, bbannier, cfe-commits

Differential Revision: https://reviews.llvm.org/D20786

llvm-svn: 276003
2016-07-19 17:56:20 +00:00
Marshall Clow 3b8669edbf Fix static assert problem on gcc; remove XFAILs that I put in in r274250
llvm-svn: 274285
2016-06-30 22:05:45 +00:00
Marshall Clow 497677449b Implement LWG#2436: 'Comparators for associative containers should always be CopyConstructible'
llvm-svn: 274235
2016-06-30 15:11:53 +00:00
Eric Fiselier 500886841d Teach map/unordered_map how to optimize 'emplace(Key, T)'.
In cases where emplace is called with two arguments and the first one
matches the key_type we can Key to check for duplicates before allocating.

This patch expands on work done by dexonsmith@apple.com.

llvm-svn: 266498
2016-04-16 00:23:12 +00:00
Eric Fiselier fa1f613f7e Extract key to avoid preemptive mallocs in insert/emplace in associative containers
Summary: This patch applies Duncan's work on __hash_table to __tree.

Reviewers: mclow.lists, dexonsmith

Subscribers: dexonsmith, cfe-commits

Differential Revision: http://reviews.llvm.org/D18637

llvm-svn: 266491
2016-04-15 23:27:27 +00:00
Eric Fiselier 5e3ea4dd79 Teach __tree how to handle map's __value_type
This patch is fairly large and contains a number of changes. The changes all work towards
allowing __tree to properly handle __value_type esspecially when inserting into the __tree.
I chose not to break this change into smaller patches because it wouldn't be possible to
write meaningful standard-compliant tests for each patch.

It is very similar to r260513 "[libcxx] Teach __hash_table how to handle unordered_map's __hash_value_type".

Changes in <map>
 * Remove __value_type's constructors because it should never be constructed directly.

 * Make map::emplace and multimap::emplace forward to __tree and remove the old definitions

 * Remove "__construct_node" map and multimap member functions. Almost all of the construction is done within __tree.

 * Fix map's move constructor to access "__value_type.__nc" directly and pass this object to __tree::insert.

Changes in <__tree>
 * Add traits to detect, handle, and unwrap, map's "__value_type".

 * Convert methods taking "value_type" to take "__container_value_type" instead. Previously these methods caused
  unwanted implicit conversions from "std::pair<Key, Value>" to "__value_type<Key, Value>".

 * Delete __tree_node and __tree_node_base's constructors and assignment operators. The node types should never be constructed
   because the "__value_" member of __tree_node must be constructed directly by the allocator.

 * Make the __tree_node_destructor class and "__construct_node" methods unwrap "__node_value_type" into "__container_value_type" before invoking the allocator. The user's allocator can only be used to construct and destroy the container's value_type. Passing it map's "__value_type" was incorrect.

 * Cleanup the "__insert" and "__emplace" methods. Have __insert forward to an __emplace function wherever possible to reduce
   code duplication. __insert_unique(value_type const&) and __insert_unique(value_type&&) forward to __emplace_unique_key_args.
   These functions will not allocate a new node if the value is already in the tree.

 * Change the __find* functions to take the "key_type" directly instead of passing in "value_type" and unwrapping the key later.
   This change allows the find functions to be used without having to construct a "value_type" first. This allows for a number
   of optimizations.

 * Teach __move_assign and __assign_multi methods to unwrap map's __value_type.

llvm-svn: 264986
2016-03-31 02:15:15 +00:00
Eric Fiselier 0594ad713b Remove all usages of "const" node pointer typedefs in the assoc containers.
The "const" pointer typedefs such as "__node_const_pointer" and
"__node_base_const_pointer" are identical to their non-const pointer types.
This patch changes all usages of "const" pointer type names to their respective
non-const typedef.

Since "fancy pointers to const" cannot be converted back to a non-const pointer
type according to the allocator requirements it is important that we never
actually use "const" pointers.

Furthermore since "__node_const_pointer" and "__node_pointer" already
name the same type, it's very confusing to use both names. Especially
when defining const/non-const overloads for member functions.

llvm-svn: 261419
2016-02-20 07:12:17 +00:00
Eric Fiselier 089a7cc5de Cleanup node-type handling in the associative containers.
This patch is very similar to r260431.

This patch is the first in a series of patches that's meant to better
support map. map has a special "value_type" that
differs from pair<const Key, Value>. In order to meet the EmplaceConstructible
and CopyInsertable requirements we need to teach __tree about this
special value_type.

This patch creates a "__tree_node_types" traits class that contains
all of the typedefs needed by the associative containers and their iterators.
These typedefs include ones for each node type and  node pointer type,
as well as special typedefs for "map"'s value type.

Although the associative containers already supported incomplete types, this
patch makes it official by adding tests.

This patch will be followed up shortly with various cleanups within __tree and
fixes for various map bugs and problems.

llvm-svn: 261416
2016-02-20 05:28:30 +00:00
Marshall Clow afc9ff99ec First half of LWG#2354: 'Unnecessary copying when inserting into maps with braced-init syntax'
llvm-svn: 256859
2016-01-05 19:32:41 +00:00
Eric Fiselier 934b092186 Use __rebind_pointer to avoid #ifdef block
llvm-svn: 256654
2015-12-30 21:52:00 +00:00
Dimitry Andric 251c629117 Fix warnings about pessimizing return moves for C++11 and higher
Summary:
Throughout the libc++ headers, there are a few instances where
_VSTD::move() is used to return a local variable.  Howard commented in
r189039 that these were there "for non-obvious reasons such as to help
things limp along in C++03 language mode".

However, when compiling these headers with warnings on, and in C++11 or
higher mode (like we do in FreeBSD), they cause the following complaints
about pessimizing moves:

    In file included from tests.cpp:26:
    In file included from tests.hpp:29:
    /usr/include/c++/v1/map:1368:12: error: moving a local object in a return statement prevents copy elision [-Werror,-Wpessimizing-move]
        return _VSTD::move(__h);  // explicitly moved for C++03
               ^
    /usr/include/c++/v1/__config:368:15: note: expanded from macro '_VSTD'
    #define _VSTD std::_LIBCPP_NAMESPACE
                  ^

Attempt to fix this by adding a _LIBCPP_EXPLICIT_MOVE() macro to
__config, which gets defined to _VSTD::move for pre-C++11, and to
nothing for C++11 and later.

I am not completely satisfied with the macro name (I also considered
_LIBCPP_COMPAT_MOVE and some other variants), so suggestions are
welcome. :)

Reviewers: mclow.lists, howard.hinnant, EricWF

Subscribers: arthur.j.odwyer, cfe-commits

Differential Revision: http://reviews.llvm.org/D11394

llvm-svn: 245421
2015-08-19 06:43:33 +00:00
Eric Fiselier 2decfad7c5 Fix warnings in array and assoc containers
llvm-svn: 242629
2015-07-18 23:56:04 +00:00
Marshall Clow e3fbe1433b Implement the first part of N4258: 'Cleaning up noexcept in the Library'. This patch deals with swapping containers, and implements a more strict noexcept specification (a conforming extension) than the standard mandates.
llvm-svn: 242056
2015-07-13 20:04:56 +00:00
Marshall Clow 1f508014df In many places, there was an #ifdef/#else block that selected one of two implmentations of rebind_alloc based on whether or not we had template aliases. Create a helper struct to encapsulate that bit of logic, and replace all the ifdefs with uses of that struct. No functionality change intented.
llvm-svn: 234296
2015-04-07 05:21:38 +00:00
Dimitry Andric a3175bab88 Fix another -Wunused-local-typedef warning in include/__tree.
The _Pp typedef in __tree<_Tp, _Compare, _Allocator>::__count_multi()
isn't used anywhere, so adding _LIBCPP_UNUSED is unecessary.

Differential Revision: http://reviews.llvm.org/D8140

llvm-svn: 231705
2015-03-09 21:39:02 +00:00
Eric Fiselier b3be398c67 Allow declaration of map and multimap iterator with incomplete mapped type. Patch from eugenis
llvm-svn: 231119
2015-03-03 20:10:01 +00:00
Marshall Clow 7c78beac5d Remove several unused forward declarations. Fixes PR22605.
llvm-svn: 229728
2015-02-18 19:28:35 +00:00
Marshall Clow d5f461ca03 Fix PR22366. When move-constructing an associative container and explicitly passing an allocator that compares different, we were not calling the destructor of the elements in the moved-from container.
llvm-svn: 227359
2015-01-28 19:54:25 +00:00
Marshall Clow ec959d5f46 Remove node from a container before destroying it. Thanks to Alexander Potapenko for pointing this out.
llvm-svn: 206024
2014-04-11 08:22:42 +00:00
Howard Hinnant 179b1f8cf2 Zhihao Yuan noted that there were a few unneeded statements. Eliminated the unnecessary ones, and commented the ones that are there for non-obvious reasons such as to help things limp along in C++03 language mode.
llvm-svn: 189039
2013-08-22 18:29:50 +00:00
Howard Hinnant f0544c2086 Nico Rieck: this patch series fixes visibility issues on Windows as explained in <http://lists.cs.uiuc.edu/pipermail/cfe-dev/2013-August/031214.html>.
llvm-svn: 188192
2013-08-12 18:38:34 +00:00
Marshall Clow 2472b928d2 N3644 tests for map/multimap/set/multiset. Drive-by NOEXCEPT for __tree_const_iterator constructor. Fix comment typos in other tests
llvm-svn: 188019
2013-08-08 21:52:50 +00:00
Howard Hinnant 07d3eccd26 Implement full support for non-pointer types in custom allocators. This is for the associative containers only. This work still needs to be done on the unordered and sequence containers. Fixes http://llvm.org/bugs/show_bug.cgi?id=15978
llvm-svn: 184358
2013-06-19 21:29:40 +00:00
Howard Hinnant 6e41256f68 No functionality change at this time. I've split _LIBCPP_VISIBLE up into two flags: _LIBCPP_TYPE_VIS and _LIBCPP_FUNC_VIS. This is in preparation for taking advantage of clang's new __type_visibility__ attribute.
llvm-svn: 176593
2013-03-06 23:30:19 +00:00
Howard Hinnant aeb85680fb Dimitry Andric: many visibility fixes. Howard: Much appreciated. Can you send me a patch to CREDITS.TXT?
llvm-svn: 163862
2012-09-14 00:39:16 +00:00
Howard Hinnant c003db1fca Further macro protection by replacing _[A-Z] with _[A-Z]p
llvm-svn: 145410
2011-11-29 18:15:50 +00:00
Howard Hinnant 073458b1ab Windows support by Ruben Van Boxem.
llvm-svn: 142235
2011-10-17 20:05:10 +00:00
Howard Hinnant ce48a1137d _STD -> _VSTD to avoid macro clash on windows
llvm-svn: 134190
2011-06-30 21:18:19 +00:00
Howard Hinnant ce53420e37 Provide names for template and function parameters in forward declarations. The purpose is to aid automated documentation tools.
llvm-svn: 133008
2011-06-14 19:58:17 +00:00
Howard Hinnant e691351098 Made more implementation details of [multi]map/set noexcept.
llvm-svn: 132642
2011-06-04 17:10:24 +00:00
Howard Hinnant 1052ee39cb noexcept for <map>.
llvm-svn: 132639
2011-06-04 14:31:57 +00:00
Douglas Gregor 6c38001ec5 Qualify calls to std::next(), to avoid conflicts with
libraries/applications that define their own 'next' template.

llvm-svn: 130511
2011-04-29 16:20:26 +00:00