[clang] 6170072 - Improve modeling of variable template specializations with dependent
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Tue Aug 11 00:50:05 PDT 2020
On Tue, 11 Aug 2020 at 00:29, Martin Storsjö <martin at 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
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200811/e13fd748/attachment.html>
More information about the cfe-commits
mailing list