https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90397

            Bug ID: 90397
           Summary: Incompatibility with clang-tidy on std::variant
           Product: gcc
           Version: 9.1.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: philip.salvaggio at mac dot com
  Target Milestone: ---

Created attachment 46315
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=46315&action=edit
Minimal example

Since upgrading to GCC 9.1.1, I am getting the following errors when running
clang-tidy (8.0.0) on this minimal example. Not sure whether this is a bug in
the libstdc++ headers or in clang, but it seems to be related to the noexcept
specifier on __get(). The code compiles fine with g++.


#include <variant>

int main() {
  std::variant<int, double> v;
  v = 5;

  int i = std::get<int>(v);
  return 0;
}

In order to reproduce from the zipped folder:

mkdir build && cd build
cmake ..
make
clang-tidy ../example.cpp

give the following errors for me.


[build]$ clang-tidy ../example.cpp
6 errors generated.
Error while processing /home/fedora/example/build/../example.cpp.
/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/variant:266:10:
error: cannot cast 'const std::variant<int, double>' to its private base class
'std::__detail::__variant::_Variant_storage<true, int, double>'
[clang-diagnostic-error]
                              std::forward<_Variant>(__v)._M_u);
                              ^
/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/variant:1610:35:
note: in instantiation of function template specialization
'std::__detail::__variant::__get<0, const std::variant<int, double> &>'
requested here
      return __detail::__variant::__get<_Np>(__v);
                                  ^
/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/variant:1359:11:
note: in instantiation of function template specialization 'std::get<0, int,
double>' requested here
            std::get<__index>(*this) = std::forward<_Tp>(__rhs);
                 ^
/home/fedora/example/example.cpp:5:5: note: in instantiation of function
template specialization 'std::variant<int, double>::operator=<int>' requested
here
  v = 5;
    ^
/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/variant:1220:7:
note: constrained by private inheritance here
    : private __detail::__variant::_Variant_base<_Types...>,
      ^
/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/variant:266:10:
error: cannot cast 'std::variant<int, double>' to its private base class
'std::__detail::__variant::_Variant_storage<true, int, double>'
[clang-diagnostic-error]
                              std::forward<_Variant>(__v)._M_u);
                              ^
/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/variant:1588:35:
note: in instantiation of function template specialization
'std::__detail::__variant::__get<0, std::variant<int, double> &>' requested
here
      return __detail::__variant::__get<_Np>(__v);
                                  ^
/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/variant:1061:19:
note: in instantiation of function template specialization 'std::get<0, int,
double>' requested here
      return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(__v);
                  ^
/home/fedora/example/example.cpp:7:16: note: in instantiation of function
template specialization 'std::get<int, int, double>' requested here
  int i = std::get<int>(v);
               ^
/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/variant:1220:7:
note: constrained by private inheritance here
    : private __detail::__variant::_Variant_base<_Types...>,
      ^
/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/variant:266:38:
error: '_M_u' is a private member of
'std::__detail::__variant::_Variant_storage<true, int, double>'
[clang-diagnostic-error]
                              std::forward<_Variant>(__v)._M_u);
                                                          ^
/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/variant:1220:7:
note: constrained by private inheritance here
    : private __detail::__variant::_Variant_base<_Types...>,
      ^
/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/variant:453:34:
note: member is declared here
      _Variadic_union<_Types...> _M_u;
                                 ^
/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/variant:1359:31:
error: cannot assign to return value because function 'get<0, int, double>'
returns a const value [clang-diagnostic-error]
            std::get<__index>(*this) = std::forward<_Tp>(__rhs);
                                     ^
/home/fedora/example/example.cpp:5:5: note: in instantiation of function
template specialization 'std::variant<int, double>::operator=<int>' requested
here
  v = 5;
    ^
/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/variant:134:15:
note: function 'get<0, int, double>' which returns const-qualified type 'const
variant_alternative_t<0UL, variant<int, double> > &' (aka 'const int &')
declared here
    constexpr variant_alternative_t<_Np, variant<_Types...>> const&
              ^
/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/variant:1559:55:
error: '__get' is missing exception specification 'noexcept'
[clang-diagnostic-error]
        friend constexpr decltype(auto) __detail::__variant::__get(_Vp&& __v);
                                                             ^
/home/fedora/example/example.cpp:4:29: note: in instantiation of template class
'std::variant<int, double>' requested here
  std::variant<int, double> v;
                            ^
/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/variant:263:5:
note: previous declaration is here
    __get(_Variant&& __v) noexcept
    ^
Found compiler error(s).

Reply via email to