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

            Bug ID: 90314
           Summary: clang gives error about exception specification in
                    declaration not matching definition after change in
                    move.h
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: peter.smith at linaro dot org
  Target Milestone: ---

The following error message was found by a CI job that builds spec2k6 with
master clang, using a master gcc sysroot for the libraries. It can be
reproduced with the following source file:

#include <algorithm>

void func(void) {
    int a = 5, b = 3;
    std::swap(a, b);
}

With a libcstd++ built including the change:
> commit 744a3010791fbd97718a3f51e9c9b2512f6d3f3e
> Author: redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>
> Date:   Mon Apr 29 13:25:38 2019 +0000
> 
>    Use _GLIBCXX_NOEXCEPT_IF for std::swap
> 
>            * include/bits/move.h (swap(T&, T&), swap(T (&)[N], T (&)[N])): Use
>            _GLIBCXX_NOEXCEPT_IF to simplify declarations.
> 
>    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@270650 
> 138bc75d-0d04-0410-961f-82ee72b054a4

The error message I get is:
/work/gnu/gcc/install_gcc/include/c++/10.0.0/bits/move.h:185:5: error: 
      exception specification in declaration does not match previous
declaration
    swap(_Tp& __a, _Tp& __b)
    ^
/work/gnu/gcc/install_gcc/include/c++/10.0.0/type_traits:2531:5: note: previous
      declaration is here
    swap(_Tp&, _Tp&)
    ^

The error message unfortunately truncates the exception specification which is
what clang is complaining about. The preprocessed source of each is:

    swap(_Tp& __a, _Tp& __b)
    noexcept((__and_<is_nothrow_move_constructible<_Tp>,
is_nothrow_move_assignable<_Tp>>::value))

and:

    swap(_Tp&, _Tp&)
    noexcept(__and_<is_nothrow_move_constructible<_Tp>,
             is_nothrow_move_assignable<_Tp>>::value);

The difference is the extra parentheses in
noexcept((__and_<is_nothrow_move_constructible<_Tp>,
is_nothrow_move_assignable<_Tp>>::value))

The error can be reproduced in clang with a much simpler example.

I'm not 100% sure on whether extra parentheses are considered as non-matching
in the standard, so I don't know whether this is a problem in clang or
libstdc++. I've raised https://bugs.llvm.org/show_bug.cgi?id=41705 on clang to
see if the error message can be tuned. I'm raising it here to see if a matching
change can be made to the exception specification in type_traits as even if
clang is fixed there will be plenty of older versions in use.

Reply via email to