On Wed, Apr 27, 2022 at 12:02:33PM +0200, Richard Biener wrote: > On Wed, 27 Apr 2022, Jakub Jelinek wrote: > > > On Wed, Apr 27, 2022 at 11:56:55AM +0200, Richard Biener wrote: > > > Bootstrapped & tested on x86_64-unknown-linux-gnu. > > > > > > OK? > > > > I think a testcase from the #c0 of the PR would be nice, but it can > > be added incrementally, so ok for trunk and unless somebody beats me > > to it, I'll try to reduce the testcase. With a fixed and unfixed compiler > > around it might be easier for reduction. > > 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, ok for trunk? 2022-04-27 Jakub Jelinek <ja...@redhat.com> PR middle-end/104492 * g++.dg/warn/pr104492.C: New test. --- gcc/testsuite/g++.dg/warn/pr104492.C.jj 2022-04-27 17:40:52.427671414 +0200 +++ gcc/testsuite/g++.dg/warn/pr104492.C 2022-04-27 17:40:12.524214984 +0200 @@ -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; +} Jakub