Bug 23528 - [3.4 Regression] Wrong default allocator in ext/hash_map
Summary: [3.4 Regression] Wrong default allocator in ext/hash_map
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 3.4.4
: P2 normal
Target Milestone: 3.4.5
Assignee: Paolo Carlini
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-08-23 11:58 UTC by Mattias Ellert
Modified: 2005-08-29 22:14 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work: 3.3.3 4.0.0 4.1.0
Known to fail: 3.4.0
Last reconfirmed:


Attachments
The testcase that exemplifies the error (240 bytes, text/plain)
2005-08-23 12:01 UTC, Mattias Ellert
Details
Patch against the gcc 3.4.4 STL headers (316 bytes, patch)
2005-08-23 12:02 UTC, Mattias Ellert
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Mattias Ellert 2005-08-23 11:58:28 UTC
The attached testcase compiles and runs correctly with gcc 3.3.4, but gives the
following compilation errors with gcc 3.4.4:

hashtest.cxx: In function `int main()':
hashtest.cxx:11: error: cannot convert `int*' to `std::pair<const int, int>*' in
initialization
hashtest.cxx:12: error: no matching function for call to
`std::allocator<int>::construct(std::pair<const int, int>*&, std::pair<const
int, int>&)'
/usr/lib/gcc/i386-redhat-linux/3.4.4/../../../../include/c++/3.4.4/ext/new_allocator.h:96:
note: candidates are: void __gnu_cxx::new_allocator<_Tp>::construct(_Tp*, const
_Tp&) [with _Tp = int]
hashtest.cxx:17: error: no matching function for call to
`std::allocator<int>::destroy(std::pair<const int, int>*&)'
/usr/lib/gcc/i386-redhat-linux/3.4.4/../../../../include/c++/3.4.4/ext/new_allocator.h:99:
note: candidates are: void __gnu_cxx::new_allocator<_Tp>::destroy(_Tp*) [with
_Tp = int]
hashtest.cxx:18: error: no matching function for call to
`std::allocator<int>::deallocate(std::pair<const int, int>*&, int)'
/usr/lib/gcc/i386-redhat-linux/3.4.4/../../../../include/c++/3.4.4/ext/new_allocator.h:86:
note: candidates are: void __gnu_cxx::new_allocator<_Tp>::deallocate(_Tp*,
size_t) [with _Tp = int]

The reason for the errors are wrong default allocators in ext/hash_map. A patch
that fixes the problem is attached.
Comment 1 Mattias Ellert 2005-08-23 12:01:11 UTC
Created attachment 9563 [details]
The testcase that exemplifies the error

It fails with gcc 3.4.4 but works correctly with gcc 3.3.4
Comment 2 Mattias Ellert 2005-08-23 12:02:39 UTC
Created attachment 9564 [details]
Patch against the gcc 3.4.4 STL headers

With this patch applied to gcc 3.4.4 it compiles correctly with this compiler
too.
Comment 3 Andrew Pinski 2005-08-23 12:42:00 UTC
This works in both on the mainlline and in 4.0.0.  Also the fix is not really a correct fix as this area was 
not what changed between 3.4.0 and 4.0.0.
Comment 4 Paolo Carlini 2005-08-23 13:15:57 UTC
I agree that something much more subtle is going on, maybe even a C++ front-end
bug in 3_4-branch. Notice that hash_map<>::allocator_type is typedef-ed as
_Ht::allocator_type, which, in turn (see the hashtable class in hashtable.h) is,
correctly, an allocator of pair<const _Key, _Tp>. Likewise for 
hash_map<>::value_type. More analysis is required...
Comment 5 Andrew Pinski 2005-08-23 13:18:25 UTC
I forgot to mention that the preprocessed source from 4.1.0 compiles just fine with the 3.4.0 compiler.
Comment 6 Paolo Carlini 2005-08-23 13:26:21 UTC
(In reply to comment #5)
I find this very hard to believe: the ext/ headers are basically frozen.
Comment 7 Paolo Carlini 2005-08-23 13:34:45 UTC
(In reply to comment #6)
Ok, Andrew is right, just double checked. A big mistery...
Comment 8 Paolo Carlini 2005-08-23 13:42:07 UTC
(In reply to comment #7)
> A big mistery...
Actually, in 3_4-branch memory allocation in class hashtable was rather different,
forgot about that. The bug is there.

Comment 9 Andrew Pinski 2005-08-23 13:42:57 UTC
Oh and the preprocessed created with 3.4.0 gives the same error on the mainline too.
Comment 10 Paolo Carlini 2005-08-23 13:55:07 UTC
It looks like the problem has been fixed in revision 1.6 of hashtable.h.

Mattias, can you experiment a bit with just changing in class hashtable:

  typedef _Alloc allocator_type;

to

  typedef typename _Alloc::template rebind<value_type>::other allocator_type;

(likely, you have available code using hash_map much more complex than I do)
Comment 11 Mattias Ellert 2005-08-23 17:14:00 UTC
(In reply to comment #10)

Your proposed alternative patch works for me. Both for the testcase in this bug
report and when I compile the code I was building when I found the bug.
Comment 12 Paolo Carlini 2005-08-23 18:23:32 UTC
(In reply to comment #11)
Thanks a lot. I think adding a proper rebind is the right way to fix the problem,
already used in mainline and 4_0-branch, by the way.
Comment 13 Paolo Carlini 2005-08-29 22:14:21 UTC
Fixed with:

2005-08-29  Paolo Carlini  <pcarlini@suse.de>

        PR libstdc++/23528
        Port from HEAD/4_0-branch:
	2004-07-28  Matt Austern  <austern@apple.com>
	* include/ext/hashtable.h: Use rebind so that allocator_type
	has correct type for a container's allocator.
	* testsuite/ext/23528.cc: New.