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
  • [PATCH] D86649: Fix for a... Sunil Srivastava via Phabricator via cfe-commits

Reply via email to