testsuite: Add testcase for dangling pointer equality bogus warning [PR104492]
On Wed, Apr 27, 2022 at 12:02:33PM +0200, Richard Biener wrote: > I did that but the reduction result did not resemble the same failure > mode. I've failed to manually construct a testcase as well. Possibly > a testcase using libstdc++ but less Qt internals might be possible. Here is a testcase that I've managed to reduce, FAILs with: FAIL: g++.dg/warn/pr104492.C -std=gnu++14 (test for bogus messages, line 111) FAIL: g++.dg/warn/pr104492.C -std=gnu++17 (test for bogus messages, line 111) FAIL: g++.dg/warn/pr104492.C -std=gnu++20 (test for bogus messages, line 111) on both x86_64-linux and i686-linux without your commit and passes with it. 2022-04-27 Jakub Jelinek <jakub@redhat.com> PR middle-end/104492 * g++.dg/warn/pr104492.C: New test.
This commit is contained in:
parent
f654140140
commit
948e8e4010
115
gcc/testsuite/g++.dg/warn/pr104492.C
Normal file
115
gcc/testsuite/g++.dg/warn/pr104492.C
Normal file
@ -0,0 +1,115 @@
|
||||
// PR middle-end/104492
|
||||
// { dg-do compile { target c++14 } }
|
||||
// { dg-options "-O3 -Wall" }
|
||||
|
||||
namespace std {
|
||||
typedef decltype (sizeof 0) size_t;
|
||||
template <typename _Tp, _Tp __v> struct integral_constant {
|
||||
static constexpr _Tp value = __v;
|
||||
};
|
||||
template <typename _Tp, typename _Up>
|
||||
struct is_same : integral_constant<bool, __is_same(_Tp, _Up)> {};
|
||||
template <bool, typename> struct enable_if;
|
||||
template <typename _Tp> _Tp forward;
|
||||
}
|
||||
class QString;
|
||||
struct random_access_iterator_tag {};
|
||||
template <typename> struct iterator_traits {
|
||||
typedef random_access_iterator_tag iterator_category;
|
||||
};
|
||||
template <typename _Iter>
|
||||
typename iterator_traits<_Iter>::iterator_category __iterator_category(_Iter);
|
||||
namespace __gnu_cxx {
|
||||
namespace __ops {
|
||||
template <typename> struct _Iter_equals_val {
|
||||
template <typename _Iterator> bool operator()(_Iterator);
|
||||
};
|
||||
template <typename _Value> _Iter_equals_val<_Value> __iter_equals_val(_Value);
|
||||
}
|
||||
}
|
||||
namespace std {
|
||||
template <typename _RandomAccessIterator, typename _Predicate>
|
||||
_RandomAccessIterator __find_if(_RandomAccessIterator __first,
|
||||
_RandomAccessIterator __last, _Predicate __pred,
|
||||
random_access_iterator_tag) {
|
||||
if (__pred(__first))
|
||||
return __first;
|
||||
return __last;
|
||||
}
|
||||
template <typename _Iterator, typename _Predicate>
|
||||
_Iterator __find_if(_Iterator __first, _Iterator __last, _Predicate __pred) {
|
||||
return __find_if(__first, __last, __pred, __iterator_category(__first));
|
||||
}
|
||||
template <typename _Tp, size_t _Nm> _Tp *begin(_Tp (&__arr)[_Nm]) {
|
||||
return __arr;
|
||||
}
|
||||
template <typename _Tp, size_t _Nm> _Tp *end(_Tp (&__arr)[_Nm]) {
|
||||
return __arr + _Nm;
|
||||
}
|
||||
template <typename _InputIterator, typename _Tp>
|
||||
_InputIterator find(_InputIterator __first, _InputIterator __last, _Tp __val) {
|
||||
return __find_if(__first, __last, __gnu_cxx::__ops::__iter_equals_val(__val));
|
||||
}
|
||||
}
|
||||
struct QStringView {
|
||||
template <typename T>
|
||||
using if_compatible_qstring_like = std::enable_if<std::is_same<T, QString>::value, bool>;
|
||||
template <typename String> QStringView(String);
|
||||
};
|
||||
template <typename Haystack, typename> struct QStringTokenizerBase {
|
||||
class sentinel {};
|
||||
struct iterator {
|
||||
Haystack operator*();
|
||||
iterator operator++(int);
|
||||
bool operator!=(sentinel);
|
||||
};
|
||||
iterator begin();
|
||||
template <bool = std::is_same<iterator, sentinel>::value> sentinel end();
|
||||
};
|
||||
namespace QtPrivate {
|
||||
namespace Tok {
|
||||
template <typename Haystack, typename Needle>
|
||||
using TokenizerBase = QStringTokenizerBase<Haystack, Needle>;
|
||||
}
|
||||
}
|
||||
template <typename Haystack, typename Needle>
|
||||
struct QStringTokenizer
|
||||
: public QtPrivate::Tok::TokenizerBase<Haystack, Needle> {
|
||||
QStringTokenizer(Haystack, Needle);
|
||||
};
|
||||
namespace QtPrivate {
|
||||
namespace Tok {
|
||||
template <typename Haystack, typename Needle>
|
||||
using TokenizerResult = QStringTokenizer<Haystack, Needle>;
|
||||
}
|
||||
}
|
||||
template <typename Haystack, typename Needle>
|
||||
auto qTokenize(Haystack, Needle)
|
||||
-> decltype(QtPrivate::Tok::TokenizerResult<Haystack, Needle>{
|
||||
std::forward<Haystack>, std::forward<Needle>});
|
||||
struct QLatin1String {
|
||||
QLatin1String(const char *) {}
|
||||
};
|
||||
class QString {};
|
||||
class QLibrary {
|
||||
bool isLibrary(const QString &);
|
||||
};
|
||||
|
||||
bool QLibrary::isLibrary(const QString &fileName)
|
||||
{
|
||||
QString completeSuffix = fileName;
|
||||
auto isValidSuffix = [](QStringView s) {
|
||||
const QLatin1String candidates[] = {
|
||||
QLatin1String("so"),
|
||||
};
|
||||
return std::find(std::begin(candidates), std::end(candidates), s) != std::end(candidates);
|
||||
};
|
||||
auto suffixes = qTokenize(completeSuffix, u'.');
|
||||
auto it = suffixes.begin();
|
||||
const auto end = suffixes.end();
|
||||
while (it != end) {
|
||||
if (isValidSuffix(*it++)) // { dg-bogus "dangling pointer to .candidates. may be used" }
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
Loading…
Reference in New Issue
Block a user