Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

boost::mpl::integral_c broken in Clang trunk #69

Closed
jyknight opened this issue Aug 4, 2022 · 16 comments · Fixed by #77
Closed

boost::mpl::integral_c broken in Clang trunk #69

jyknight opened this issue Aug 4, 2022 · 16 comments · Fixed by #77

Comments

@jyknight
Copy link

jyknight commented Aug 4, 2022

Clang has recently addressed an issue where it failed to diagnose the UB of casting an out-of-range integer to an enum in a constant expression.

Since undefined behavior is not allowed in a constant expression, Clang now prohibits enum test { zero }; constexpr int g = static_cast<test>(-1); with "error: constexpr variable 'g' must be initialized by a constant expression; note: integer value -1 is outside the valid range of values [0, 1] for this enumeration type"

This change breaks boost::mpl::integral_c, since it does exactly that. Demonstrated with example, below (and on godbolt)

#include <boost/mpl/integral_c.hpp>
enum test { zero, one };
boost::mpl::integral_c<test, zero> m;

Originally discovered with a program that was using the boost::numeric library, which in turn uses mpl like the above example.

#include <boost/numeric/conversion/udt_builtin_mixture.hpp>
boost::numeric::udt_builtin_mixture<int, int> m;
@dabrahams
Copy link
Contributor

The fix looks like this.

@dabrahams
Copy link
Contributor

Actually I'm back to believing there's no true fix if next and prior have to be of type integral_c<T, ...>.

@jyknight
Copy link
Author

Perhaps the correct fix is to somehow cause the next/prior members to be omitted when they're impossible to represent, just like they're omitted for bool? I expect that's possible somehow via some template specialization magic.

Note that Clang has been changed since a week ago to no longer have this be an unconditional error. Now it's a controllable warning -Wenum-constexpr-conversion, which by default is enabled as an error. However, it's suppressed in system headers, and can be downgraded/disabled in user code as well. So, to see the error in the godbolt example you'll now need to add -Wsystem-headers to the compiler options. (e.g. https://godbolt.org/z/v4PPjW1n1)

Since most code using boost will be using it as a system header, they'll also not see the error, and anyone else may downgrade the error to a warning or disable it entirely if desired. However, it may become an unconditional error again in some future release of Clang, so it'd still be good to address it.

@dabrahams
Copy link
Contributor

dabrahams commented Aug 16, 2022

Perhaps the correct fix is to somehow cause the next/prior members to be omitted when they're impossible to represent, just like they're omitted for bool? I expect that's possible somehow via some template specialization magic.

Well, that's what I investigated, and my (ill-informed) conclusion is that it's not possible. The problem is that the the only expressions that try to create the representation (static_cast<test>(-1)) are not constant expressions, and they're well-typed. I hope somebody proves me wrong, but I'm certainly out of ideas.

@shafik
Copy link

shafik commented Aug 23, 2022

If the intent is that the enum should be able to handle values outside the enumerator values then perhaps making it have a fixed underlying type better represents the intent?

@dabrahams
Copy link
Contributor

I don't think that's the intent, but it is a decent workaround for the problem. I don't believe the intent is actually realizable, but like I said, I no longer really know C++, so I might be wrong.

@ecatmur
Copy link
Contributor

ecatmur commented Nov 16, 2022

the static const trick works: https://godbolt.org/z/KrhdzqYbx

enum test { zero, one };
template<class E, E a>
E const k = static_cast<E>(a - 1);
template<class T, T> struct S {};
template<class> int f();
int g() { return f<S<test, k<test, zero>>>(); }

this means that going all the way back to the EDG implementation/workaround actually "fixes" it: https://godbolt.org/z/8bTerz3WM

#define __EDG_VERSION__ 242
#include <boost/mpl/integral_c.hpp>
enum test { zero, one };
boost::mpl::integral_c<test, zero> m;

pdimov added a commit to boostorg/numeric_conversion that referenced this issue Nov 16, 2022
tdf-gerrit pushed a commit to LibreOffice/core that referenced this issue Jan 5, 2023
<https://dev-www.libreoffice.org/src/boost_1_81_0.tar.xz> has been generated (on
Fedora 37) with

> $ wget https://boostorg.jfrog.io/artifactory/main/release/1.81.0/source/boost_1_81_0.tar.bz2
> $ printf '71feeed900fbccca04a3b4f2f84a7c217186f28a940ed8b7ed4725986baf99fa boost_1_81_0.tar.bz2' | sha256sum -c # cf. <https://www.boost.org/users/history/version_1_81_0.html>
> boost_1_81_0.tar.bz2: OK
> $ external/boost/repack_tarball.sh boost_1_81_0.tar.bz2
> Unpacking boost_1_81_0.tar.bz2 ...
> Removing unnecessary files ...
> Creating boost_1_81_0.tar.xz ...
> Cleaning up ...
> 1deb0a5a9e33a6626fcaa1d2efd4c0e74ca2b0eea87c1559e3917f3066b633d6  boost_1_81_0.tar.xz
> Done.

* external/boost/windows-no-utf8-locales.patch.0, introduced with
  f046fed "Don't ever attempt to initialise a
  std::locale with a UTF-8 locale on Windows", was presumably obsoleted by
  <boostorg/locale@f45adfc>
  "Use UTF-16 <-> UTF-8 codecvt on Windows".

* external/boost/libc++.patch.0 was obsoleted by
  <boostorg/config@f0af4a9>
  "The std lib unary/binary_function base classes are deprecated/removed from
  libcpp15."

* external/boost/0001-Change-mpl-integral_c-to-boost-integral_constant-to-.patch.2
  was obsoleted by
  <boostorg/numeric_conversion@50a1eae>
  "Change mpl::integral_c to boost::integral_constant to avoid Clang 16 errors
  when constructing out of range enums (refs #24, boostorg/mpl#69)".

* external/boost/0001-Avoid-boost-phoenix-placeholders-uarg1.10-ODR-violat.patch.2
  is needed to e.g. avoid
> ./.libs/libetonyek_internal.a(libetonyek_internal_la-KEY1DivElement.o):(.bss+0x3e): multiple definition of `boost::phoenix::placeholders::uarg1'; ./.libs/libetonyek_internal.a(libetonyek_internal_la-IWORKFormula.o):(.bss+0x3e): first defined here
  etc. while building ExternalProject_libetonyek, caused by
  <boostorg/phoenix@8b6a9c2>
  "std::tuple support (Resolving #103) (#104)".

Change-Id: I48773166d0c50f2850d8bb37fa6215d9e5c0d51d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145044
Tested-by: Jenkins
Reviewed-by: Tor Lillqvist <[email protected]>
smuzaffar added a commit to cms-externals/boost that referenced this issue Aug 9, 2023
…a9b90724323ef8f2a67e7984a.patch

From 50a1eae942effb0a9b90724323ef8f2a67e7984a Mon Sep 17 00:00:00 2001
From: Peter Dimov <[email protected]>
Date: Wed, 16 Nov 2022 10:43:31 +0200
Subject: [PATCH] Change mpl::integral_c to boost::integral_constant to avoid
 Clang 16 errors when constructing out of range enums (refs #24,
 boostorg/mpl#69)
@smeenai
Copy link

smeenai commented Oct 16, 2023

Was there any progress here? Clang landed llvm/llvm-project#67528 which makes this an error by default even in system headers. We can turn off the warning for now, but that option will be removed in a future Clang release, so this will need to be addressed before then.

@carlosgalvezp
Copy link

Hi! Any progress? What is the ETA for fixing? Next Clang release in about 6 months will turn the warning into a non-suppressable hard error.

ecatmur added a commit to ecatmur/mpl that referenced this issue Nov 24, 2023
Trying to form next/prior in constant evaluation may be ill-formed; see boostorg#69
@kencu
Copy link

kencu commented Dec 20, 2023

we are running into this issue now on MacPorts. current boost builds are failing with the now-default compiler, clang-16.

various patches are being suggested, versions of the ones listed in this PR, but if at all possible, we'd like to go with the one that will be finally integrated into boost.

@EduPonz
Copy link

EduPonz commented Feb 17, 2024

We have hit the same issue (see here. It seems that macports/macports-ports#21839 does not fix it for us.

@rpopescu
Copy link

Does anyone know what the latest status is, for example, which is the earliest version of boost where this is fixed?

tagging @pdimov with thanks!

pdimov added a commit that referenced this issue Jun 17, 2024
@pdimov
Copy link
Member

pdimov commented Jun 18, 2024

It will be fixed in the next release, 1.86.

@rpopescu
Copy link

Thank you!

@Artalus
Copy link

Artalus commented Aug 21, 2024

We are currently unable to update our Boost to 1.86 - but can patch and rebuild the version we currently use, and would like to backport the needed changes locally, to build our 1.75 with newer Clang. I checked the history of this issue, and it seems that the combination of

does fix the build error for us. Since we are using Conan to provide third-party libraries, I also thought it might be a good idea to share such patch with a bigger audience.
@pdimov apologies, but could you maybe confirm if this patch is indeed sufficient for a fix, and does not miss anything not mentioned in this thread?

@pdimov
Copy link
Member

pdimov commented Aug 21, 2024

I think that these two patches are sufficient, yes.

vincefn added a commit to vincefn/objcryst that referenced this issue Aug 24, 2024
ktrushin pushed a commit to percona/percona-server-mongodb that referenced this issue Nov 2, 2024
Trying to form next/prior in constant evaluation may be ill-formed; see boostorg/mpl#69

Note: the patch source is
boostorg/mpl#77

Please also see boostorg/mpl#69
ktrushin pushed a commit to percona/percona-server-mongodb that referenced this issue Nov 2, 2024
…errors when constructing out of range enums (refs #24, boostorg/mpl#69)

Note: the patch source is
boostorg/numeric_conversion@50a1eae

Please also see boostorg/mpl#69
ktrushin pushed a commit to percona/percona-server-mongodb that referenced this issue Nov 4, 2024
Trying to form next/prior in constant evaluation may be ill-formed; see boostorg/mpl#69

Note: the patch source is
boostorg/mpl#77

Please also see boostorg/mpl#69
ktrushin pushed a commit to percona/percona-server-mongodb that referenced this issue Nov 4, 2024
…errors when constructing out of range enums (refs #24, boostorg/mpl#69)

Note: the patch source is
boostorg/numeric_conversion@50a1eae

Please also see boostorg/mpl#69
stephengtuggy added a commit to stephengtuggy/Vega-Strike-Engine-Source that referenced this issue Jan 2, 2025
…lds are failing; build using gcc instead of clang on Rocky Linux 9.5 due to boostorg/mpl#69
jeking3 pushed a commit to ABBAPOH/mpl that referenced this issue Jan 3, 2025
jeking3 pushed a commit to ABBAPOH/mpl that referenced this issue Jan 3, 2025
Trying to form next/prior in constant evaluation may be ill-formed; see boostorg#69
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet