On Tue, 11 Aug 2020 at 00:29, Martin Storsjö <mar...@martin.st> wrote:
> On Sun, 9 Aug 2020, Richard Smith via cfe-commits wrote: > > > > > Author: Richard Smith > > Date: 2020-08-09T23:22:26-07:00 > > New Revision: 617007240cbfb97c8ccf6d61b0c4ca0bb62d43c9 > > > > URL: > https://github.com/llvm/llvm-project/commit/617007240cbfb97c8ccf6d61b0c4ca0bb62d43c9 > > DIFF: > https://github.com/llvm/llvm-project/commit/617007240cbfb97c8ccf6d61b0c4ca0bb62d43c9.diff > > > > LOG: Improve modeling of variable template specializations with dependent > > arguments. > > > > Don't build a variable template specialization declaration until its > > scope and template arguments are non-dependent. > > > > No functionality change intended, but the AST representation is now more > > consistent with how we model other templates. > > This did turn out to make a functional change, breaking building the dev > branch of Qt. A halfway reduced example below: > Thanks for reporting this! Reduced a bit more: template<class _Tp, class _Arg> inline constexpr bool is_nothrow_assignable_v = true; template<class T> class QCache { void replace() noexcept(is_nothrow_assignable_v<T>); }; We used to allow this and now reject. This code is ill-formed (no diagnostic required) by [temp.res]/8, because it has no valid instantiations, because the second template argument of is_nothrow_assignable_v is missing. So, assuming the case from which this was reduced was similarly ill-formed (which it looks like it is: https://github.com/qt/qtbase/blob/48c8322a613f58d19ad9e0262bbac437ce2598f8/src/corelib/tools/qcache.h#L114), I think that's a (minor) quality of implementation improvement -- we now diagnose a bug that we used to miss. ICC also rejects this, although GCC does not, and all three compilers reject the corresponding case using a class template instead of a variable template. > template <class _Tp, _Tp __v> > struct integral_constant > { > static constexpr const _Tp value = __v; > typedef _Tp value_type; > typedef integral_constant type; > __attribute__ ((__exclude_from_explicit_instantiation__)) > constexpr operator value_type() const noexcept {return value;} > > __attribute__ ((__exclude_from_explicit_instantiation__)) > constexpr value_type operator ()() const noexcept {return value;} > }; > > > template <class _Tp, class _Arg> > struct is_nothrow_assignable > : public integral_constant<bool, __is_nothrow_assignable(_Tp, _Arg)> > {}; > template <class _Tp, class _Arg> > inline constexpr bool is_nothrow_assignable_v > = is_nothrow_assignable<_Tp, _Arg>::value; > > > template <class T> > class QCache > { > struct Value { > T *t = nullptr; > }; > > struct Node { > Value value; > > void replace(const Value &t) noexcept(is_nothrow_assignable_v<T>) > { > value = t; > } > }; > > }; > > > > // Martin > >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits