From a8b4c93ccd8ff8e1aadf89325f9cef7d3b8278a4 Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Wed, 17 Jan 2018 13:27:57 +1100 Subject: [PATCH] coord: mitigate gcc ICE when using redim --- coord/base.hpp | 48 ++++++++++++++++++++++++++++++++---------------- test/point.cpp | 3 +-- 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/coord/base.hpp b/coord/base.hpp index 41c370d6..52dd0ccd 100644 --- a/coord/base.hpp +++ b/coord/base.hpp @@ -148,21 +148,24 @@ namespace util::coord { /// /// explicitly does not allow a fill parameter given it can't be used /// when reducing dimensions. + /// + /// HACK,gcc#,gcc-7.x: This function _must not_ use std::copy or + /// similar algorithms to move the data as it produces an ICE on some + /// code fragements if it does. Namely: + /// "internal compiler error: in trunc_int_for_mode, at explow.c:55" template < size_t D, - typename _sfinae = SelfT - > - std::enable_if_t< - has_redim_v<_sfinae>, - redim_t<_sfinae,D> + typename = std::enable_if_t< + has_redim_v && S >= D, + void + > > + auto redim (void) const { redim_t out; - - std::copy_n (std::cbegin (this->data), - min (S, D), - std::begin (out.data)); + for (size_t i = 0; i < D; ++i) + out[i] = this->data[i]; return out; } @@ -174,17 +177,24 @@ namespace util::coord { /// /// explicitly requires a fill parameter so that we avoid undefined /// values. + /// + /// HACK,gcc#,gcc-7.x: This function _must not_ use std::copy or + /// similar algorithms to move the data as it produces an ICE on some + /// code fragements if it does. Namely: + /// "internal compiler error: in trunc_int_for_mode, at explow.c:55" template std::enable_if_t< - has_redim_v<_sfinae>, + has_redim_v<_sfinae> && S <= D, redim_t<_sfinae,D> > redim (const redim_t<_sfinae,D> fill) const { redim_t out; - auto next = std::copy (cbegin (), cend (), std::begin (out)); - std::copy (std::cbegin (fill) + S, std::cend (fill), next); + for (size_t i = 0; i < S; ++i) + out[i] = this->data[i]; + for (size_t i = S; i < D; ++i) + out[i] = fill[i]; return out; } @@ -194,20 +204,26 @@ namespace util::coord { /// /// explicitly requires a fill parameter so that we avoid undefined /// values. + /// + /// HACK,gcc#,gcc-7.x: This function _must not_ use std::copy or + /// similar algorithms to move the data as it produces an ICE on some + /// code fragements if it does. Namely: + /// "internal compiler error: in trunc_int_for_mode, at explow.c:55" template < size_t D, typename _sfinae = SelfT > std::enable_if_t< - has_redim_v<_sfinae>, + has_redim_v<_sfinae> && S <= D, redim_t<_sfinae,D> > redim (T fill) const { redim_t out; - - auto next = std::copy (cbegin (), cend (), std::begin (out)); - std::fill (next, std::end (out), fill); + for (size_t i = 0; i < S; ++i) + out[i] = this->data[i]; + for (size_t i = S; i < D; ++i) + out[i] = fill; return out; } diff --git a/test/point.cpp b/test/point.cpp index 14261df6..d63559df 100644 --- a/test/point.cpp +++ b/test/point.cpp @@ -20,6 +20,7 @@ main (void) const point2f r { 0.f, 1.f }; tap.expect_eq (q, r, "redim to lower dimension"); + } // Redim to higher dimension without fill @@ -39,7 +40,6 @@ main (void) // // HACK: This fails under GCC-7.1.0, and i'm not wasting any more time // reducing this test case. it's _really_ template heavy. -#if !(__GNUC_PREREQ (7, 1)) { static const point4f FILL (1.f, 2.f, 3.f, 4.f); const point2f p (0.1f, 1.f); @@ -54,7 +54,6 @@ main (void) "redim to higher with fill" ); } -#endif // Simple linking check for coord type casting. Relies on truncation. {