Don't reuse iterator var to avoid -D_GLIBCXX_DEBUG crash
For a CXXFLAGS='-D_GLIBCXX_DEBUG' build, running the
examples/corelib/ipc/sharedmemory/sharedmemory
example and clicking on the "Load Image from File..." button
would result in a crash:
> usr/include/c++/13/debug/safe_iterator.h:492:
> In function:
> bool gnu_debug::operator!=(const
> _Safe_iterator<std::_Rb_tree_const_iterator<std::pair<const
> QSettingsKey, QVariant> >, std::debug::map<QSettingsKey, QVariant,
> std::less<QSettingsKey>, std::allocator<std::pair<const QSettingsKey,
> QVariant> > >, std::forward_iterator_tag>::_Self&, const
> _Safe_iterator<std::_Rb_tree_const_iterator<std::pair<const
> QSettingsKey, QVariant> >, std::debug::map<QSettingsKey, QVariant,
> std::less<QSettingsKey>, std::allocator<std::pair<const QSettingsKey,
> QVariant> > >, std::forward_iterator_tag>::_Self&)
>
> Error: attempt to compare a singular iterator to a
> singular (value-initialized) iterator.
>
> Objects involved in the operation:
> iterator "lhs" @ 0x7ffe8e811550 {
> type = std::_Rb_tree_const_iterator<std::pair<QSettingsKey const, QVariant> > (constant iterator);
> state = singular;
> }
> iterator "rhs" @ 0x7ffe8e811670 {
> type = std::_Rb_tree_const_iterator<std::pair<QSettingsKey const, QVariant> > (constant iterator);
> state = singular (value-initialized);
> }
> Aborted (core dumped)
This may be a libstdc++ bug, but still avoid/work around the issue
by just using two separate variables for the iterators here.
While at it, simplify the code a bit and replace the use
of const_cast and pointers with the use of const references.
Many thanks to Giuseppe D'Angelo for the analysis of
the underlying problem and reporting a bug for GCC/libstdc++ [1] !
[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112477
Fixes: QTBUG-119044
Pick-to: 6.6 6.5
Change-Id: I00a8cc35033cf3ab4ba1f071cccabdef8ef52f9c
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
bb10
parent
536fd29bdf
commit
5db48d584e
|
|
@ -1256,17 +1256,17 @@ QStringList QConfFileSettingsPrivate::children(const QString &prefix, ChildSpec
|
|||
else
|
||||
ensureSectionParsed(confFile, thePrefix);
|
||||
|
||||
auto j = const_cast<const ParsedSettingsMap *>(
|
||||
&confFile->originalKeys)->lowerBound( thePrefix);
|
||||
while (j != confFile->originalKeys.constEnd() && j.key().startsWith(thePrefix)) {
|
||||
if (!confFile->removedKeys.contains(j.key()))
|
||||
processChild(QStringView{j.key().originalCaseKey()}.sliced(startPos), spec, result);
|
||||
++j;
|
||||
const auto &originalKeys = confFile->originalKeys;
|
||||
auto i = originalKeys.lowerBound(thePrefix);
|
||||
while (i != originalKeys.end() && i.key().startsWith(thePrefix)) {
|
||||
if (!confFile->removedKeys.contains(i.key()))
|
||||
processChild(QStringView{i.key().originalCaseKey()}.sliced(startPos), spec, result);
|
||||
++i;
|
||||
}
|
||||
|
||||
j = const_cast<const ParsedSettingsMap *>(
|
||||
&confFile->addedKeys)->lowerBound(thePrefix);
|
||||
while (j != confFile->addedKeys.constEnd() && j.key().startsWith(thePrefix)) {
|
||||
const auto &addedKeys = confFile->addedKeys;
|
||||
auto j = addedKeys.lowerBound(thePrefix);
|
||||
while (j != addedKeys.end() && j.key().startsWith(thePrefix)) {
|
||||
processChild(QStringView{j.key().originalCaseKey()}.sliced(startPos), spec, result);
|
||||
++j;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue