Sunil_Srivastava created this revision. Sunil_Srivastava added reviewers: rsmith, erichkeane. Herald added a project: clang. Herald added a subscriber: cfe-commits. Sunil_Srivastava requested review of this revision.
This is a proposed fix for the crash of PR46865. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D86649 Files: clang/lib/AST/ExprConstant.cpp clang/test/AST/pr46865.cpp Index: clang/test/AST/pr46865.cpp =================================================================== --- /dev/null +++ clang/test/AST/pr46865.cpp @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -fsyntax-only %s +typedef unsigned long size_t; + +namespace std { +template<class _Ty> struct add_const { typedef const _Ty type; }; + +template<class A, class B> class tuple {A a; B b; }; +template<class _Tuple> struct tuple_size; +template<class _Tuple> struct tuple_size<const _Tuple> {static constexpr size_t value = 2;}; // hardcoded 2 + +template<size_t _Index, class _Tuple> struct tuple_element; +template<class _This, class _that> struct tuple_element<0, tuple<_This, _that> > { typedef _This type; }; +template<class _This, class _that> struct tuple_element<1, tuple<_This, _that> > { typedef _that type; }; + +template<size_t _Index, class _Tuple> struct tuple_element<_Index, const _Tuple> { + typedef tuple_element<_Index, _Tuple> _Mybase; + typedef typename add_const<typename _Mybase::type>::type type; +}; + +template<size_t _Index, class A, class B> inline constexpr const typename tuple_element<_Index, tuple<A, B> >::type& + get(const tuple<A, B>& _Tuple) noexcept {} + +template<class A, class B> inline constexpr const typename tuple_element<0, tuple<A, B> >::type& + get(const tuple<A, B>& _Tuple) noexcept { return _Tuple.a; } +template<class A, class B> inline constexpr const typename tuple_element<1, tuple<A, B> >::type& + get(const tuple<A, B>& _Tuple) noexcept { return _Tuple.b; } +} +std::tuple<unsigned,unsigned> inline __attribute__((always_inline)) get_sc(unsigned v) {} + +template <typename T> class bbb { + unsigned u; + inline __attribute__((always_inline)) void cebb(); +}; + +template <typename T> void bbb<T>::cebb() +{ + unsigned p; + auto const t = u; + auto const [s, c] = get_sc(t); + p = s; +} + Index: clang/lib/AST/ExprConstant.cpp =================================================================== --- clang/lib/AST/ExprConstant.cpp +++ clang/lib/AST/ExprConstant.cpp @@ -3095,7 +3095,7 @@ // constant-folding cases, where the variable is not actually of a suitable // type for use in a constant expression (otherwise the DeclRefExpr would // have been value-dependent too), so diagnose that. - assert(!VD->mightBeUsableInConstantExpressions(Info.Ctx)); + assert(!VD->isUsableInConstantExpressions(Info.Ctx)); if (!Info.checkingPotentialConstantExpression()) { Info.FFDiag(E, Info.getLangOpts().CPlusPlus11 ? diag::note_constexpr_ltor_non_constexpr
Index: clang/test/AST/pr46865.cpp =================================================================== --- /dev/null +++ clang/test/AST/pr46865.cpp @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -fsyntax-only %s +typedef unsigned long size_t; + +namespace std { +template<class _Ty> struct add_const { typedef const _Ty type; }; + +template<class A, class B> class tuple {A a; B b; }; +template<class _Tuple> struct tuple_size; +template<class _Tuple> struct tuple_size<const _Tuple> {static constexpr size_t value = 2;}; // hardcoded 2 + +template<size_t _Index, class _Tuple> struct tuple_element; +template<class _This, class _that> struct tuple_element<0, tuple<_This, _that> > { typedef _This type; }; +template<class _This, class _that> struct tuple_element<1, tuple<_This, _that> > { typedef _that type; }; + +template<size_t _Index, class _Tuple> struct tuple_element<_Index, const _Tuple> { + typedef tuple_element<_Index, _Tuple> _Mybase; + typedef typename add_const<typename _Mybase::type>::type type; +}; + +template<size_t _Index, class A, class B> inline constexpr const typename tuple_element<_Index, tuple<A, B> >::type& + get(const tuple<A, B>& _Tuple) noexcept {} + +template<class A, class B> inline constexpr const typename tuple_element<0, tuple<A, B> >::type& + get(const tuple<A, B>& _Tuple) noexcept { return _Tuple.a; } +template<class A, class B> inline constexpr const typename tuple_element<1, tuple<A, B> >::type& + get(const tuple<A, B>& _Tuple) noexcept { return _Tuple.b; } +} +std::tuple<unsigned,unsigned> inline __attribute__((always_inline)) get_sc(unsigned v) {} + +template <typename T> class bbb { + unsigned u; + inline __attribute__((always_inline)) void cebb(); +}; + +template <typename T> void bbb<T>::cebb() +{ + unsigned p; + auto const t = u; + auto const [s, c] = get_sc(t); + p = s; +} + Index: clang/lib/AST/ExprConstant.cpp =================================================================== --- clang/lib/AST/ExprConstant.cpp +++ clang/lib/AST/ExprConstant.cpp @@ -3095,7 +3095,7 @@ // constant-folding cases, where the variable is not actually of a suitable // type for use in a constant expression (otherwise the DeclRefExpr would // have been value-dependent too), so diagnose that. - assert(!VD->mightBeUsableInConstantExpressions(Info.Ctx)); + assert(!VD->isUsableInConstantExpressions(Info.Ctx)); if (!Info.checkingPotentialConstantExpression()) { Info.FFDiag(E, Info.getLangOpts().CPlusPlus11 ? diag::note_constexpr_ltor_non_constexpr
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits