re PR c++/81933 (Invalid "constexpr call flows off the end of the function" error)
authorMarek Polacek <polacek@redhat.com>
Mon, 22 Jan 2018 16:05:20 +0000 (16:05 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Mon, 22 Jan 2018 16:05:20 +0000 (16:05 +0000)
PR c++/81933
* typeck2.c (split_nonconstant_init_1): Return false if we didn't
split out anything.

* g++.dg/cpp1y/constexpr-empty4.C: New test.

From-SVN: r256951

gcc/cp/ChangeLog
gcc/cp/typeck2.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp1y/constexpr-empty4.C [new file with mode: 0644]

index 0652662f6a19e4f08e5defade2b946a116f349fa..3cbb2a45c94525fb05fe6b68052567012046322c 100644 (file)
@@ -1,7 +1,12 @@
+2018-01-22  Marek Polacek  <polacek@redhat.com>
+
+       PR c++/81933
+       * typeck2.c (split_nonconstant_init_1): Return false if we didn't
+       split out anything.
+       
 2018-01-22  Ville Voutilainen  <ville.voutilainen@gmail.com>
 
        PR c++/83895
-
        * decl.c (grokdeclarator): Don't diagnose extra parens
        on typedefs.
 
index 8d933257f5f481f97484c72cd41827c55b7bf67b..8cb0e8811d355f5a7a8da917d6bd3616908f4fc6 100644 (file)
@@ -725,6 +725,11 @@ split_nonconstant_init_1 (tree dest, tree init)
 
   /* The rest of the initializer is now a constant. */
   TREE_CONSTANT (init) = 1;
+
+  /* We didn't split out anything.  */
+  if (num_split_elts == 0)
+    return false;
+
   return complete_p && complete_ctor_at_level_p (TREE_TYPE (init),
                                                 num_split_elts, inner_type);
 }
index 3fd258e43d0f220506ee49a5e48be66a07a7cdc8..e046a97dd35b88e4c9492ec8cd118d57d8ca06b6 100644 (file)
@@ -1,3 +1,8 @@
+2018-01-22  Marek Polacek  <polacek@redhat.com>
+
+       PR c++/81933
+       * g++.dg/cpp1y/constexpr-empty4.C: New test.
+
 2018-01-22  Will Schmidt <will_schmidt@vnet.ibm.com>
 
        * gcc.target/powerpc/fold-vec-abs-short-fwrap.c: Add xxspltib to
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-empty4.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-empty4.C
new file mode 100644 (file)
index 0000000..059220f
--- /dev/null
@@ -0,0 +1,51 @@
+// PR c++/81933
+// { dg-do compile { target c++14 } }
+
+namespace std {
+template <typename _Tp> struct __decay_and_strip { typedef _Tp __type; };
+template <int> struct enable_if { typedef int type; };
+template <typename _Head> struct _Head_base {
+  constexpr _Head_base(_Head) {}
+};
+template <unsigned long, typename...> struct _Tuple_impl;
+template <unsigned long _Idx, typename _Head, typename... _Tail>
+struct _Tuple_impl<_Idx, _Head, _Tail...> : _Tuple_impl<1, _Tail...>, // { dg-warning "direct base" }
+                                            _Head_base<_Head> {
+  typedef _Tuple_impl<1, _Tail...> _Inherited;
+  typedef _Head_base<_Head> _Base;
+  constexpr _Tuple_impl(_Head __head, _Tail... __tail)
+      : _Inherited(__tail...), _Base(__head) {}
+  _Tuple_impl(const _Tuple_impl &) = default;
+  _Tuple_impl(_Tuple_impl &&);
+};
+template <unsigned long _Idx, typename _Head>
+struct _Tuple_impl<_Idx, _Head> : _Head_base<_Head> {
+  typedef _Head_base<_Head> _Base;
+  constexpr _Tuple_impl(_Head __head) : _Base(__head) {}
+};
+template <int> struct _TC {
+  static constexpr bool _NotSameTuple() { return true; }
+};
+template <typename... _Elements> class tuple : _Tuple_impl<0, _Elements...> {
+  typedef _Tuple_impl<0, _Elements...> _Inherited;
+
+public:
+  template <typename... _UElements,
+            enable_if<_TC<1>::_NotSameTuple()>::type = false>
+  constexpr tuple(_UElements... __elements) : _Inherited(__elements...) {}
+  tuple(const tuple &) = default;
+};
+template <typename... _Elements>
+constexpr tuple<typename __decay_and_strip<_Elements>::__type...>
+    make_tuple(_Elements... __args) {
+  typedef tuple<typename __decay_and_strip<_Elements>::__type...> __result_type;
+  return __result_type(__args...);
+}
+}
+struct any_udt {};
+template <typename... Tuples> constexpr auto flatten(Tuples... tuples) {
+  auto all = std::make_tuple(tuples...);
+  auto flat(all);
+  return flat;
+}
+constexpr auto fail = flatten(any_udt{}, any_udt{});