llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.03k stars 11.96k forks source link

Boost test accumulators/valarray.cpp fails to compile with LLVM headers. #58788

Open edfvogel opened 2 years ago

edfvogel commented 2 years ago

I am using the latest LLVM on Cygwin. I have also downloaded Boost 1.79.0.

When I try to compile the Boost test accumulators/test/valarray.cpp it will compile if I use the g++ headers, but not if I add -stdlib=libc++.

Here is a reduced example called t.cpp:

#include <valarray>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/numeric/functional/valarray.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/weighted_mean.hpp>

using namespace boost;
using namespace accumulators;

template<typename T>
void is_equal(std::valarray<T> const &left, std::valarray<T> const &right)
{
}

void test_stat()
{
  //  std::valarray<double>(6.,3);
  typedef std::valarray<int> sample_t;
  accumulator_set<sample_t, stats<tag::weighted_mean(immediate)>, int>
    acc2(sample = sample_t(0,3));
  is_equal(std::valarray<double>(6.,3), weighted_mean(acc2));
}

Assuming that boost_1_79_0 is put in the area boost_1_79_0. A cut paste will look like:

$ clang++ -c -Iboost_1_79_0 -w  t.cpp
$ clang++ -c -Iboost_1_79_0 -w -stdlib=libc++ t.cpp
In file included from t.cpp:5:
boost_1_79_0/boost/accumulators/statistics/weighted_mean.hpp:73:13: error: no
      matching constructor for initialization of
      'boost::accumulators::impl::immediate_weighted_mean_impl<std::__1::valarray<int>,
      int, boost::accumulators::tag::sample>::result_type'
      (aka 'valarray<double>')
          : mean(
            ^
boost_1_79_0/boost/accumulators/framework/depends_on.hpp:326:17: note: in
      instantiation of function template specialization
      'boost::accumulators::impl::immediate_weighted_mean_impl<std::__1::valarray<int>,
<Remaining message removed>

Not an important issue, but I thought I would report it.

Thank you in advance for your time.

Ed Vogel

chrisbadger commented 1 year ago

I debugged an issue similar to this, and I think it may be related to libc++ using a proxy type (std::__val_expr<...>) for the return type of some of std::valarray's overloaded binary operators (e.g. operator/). This proxy type is allowed by the standard but Boost might not be handling it correctly.

In at least in one other case, I think the proxy type is subverting Boost's typeof system, which has to explicitly register types/templates for them to work. See boosts' libs/typeof/inclue/boost/typeof/std/valarray.hpp, which registers types such as std::valarray and std::slice, but not any proxy types. This can lead to uses of Boost's incomplete primary template encode_type_impl, which may trickle down into SFINAE errors elsewhere.