Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

Error during template instantiation in exception specification for defaulted functions #23382

Open Quuxplusone opened 9 years ago

Quuxplusone commented 9 years ago
Bugzilla Link PR23383
Status NEW
Importance P normal
Reported by Mattia Basaglia (mattia.basaglia@gmail.com)
Reported on 2015-04-30 15:10:56 -0700
Last modified on 2018-01-19 07:29:46 -0800
Version 3.6
Hardware PC Linux
CC bruno.cardoso@gmail.com, dgregor@apple.com, ditaliano@apple.com, jaak+llvm-bugs@ristioja.ee, keziahw@gmail.com, llvm-bugs@lists.llvm.org, richard-llvm@metafoo.co.uk, twoh@fb.com
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also
When defining exception specification in explicitly defaulted functions, it
appears that templates aren't expanded correctly and clang gives the error
"exception specification is not available until end of class definition".

If the same template has been already expanded the error doesn't occur.

The error occurs on clang 3.6 but not on 3.5.

Follows an example (note that only the first class causes the error):

struct something { static const bool value = true; };
template<class T> struct something_template { static const bool value = true; };

struct A_error {
    // This fails to compile
    A_error() noexcept(something_template<int>::value) = default;
};

// All of the following compile fine
struct A1 {
    A1() noexcept(1+1) = default;
};
struct A2 {
    A2() noexcept(something::value) = default;
};
struct A3 {
    void foo() noexcept(something_template<int>::value) {}
};
struct A4 {
    A4() noexcept(something_template<int>::value) {}
};
// Note: A5 is identical to A_error but it compiles fine
struct A5 {
    A5() noexcept(something_template<int>::value) = default;
};
Quuxplusone commented 8 years ago
The problem seems to be more general. I'm seeing the same error generated
incorrectly in a similar situation (tested with clang3.7).

This fails to compile:

#include <memory>
class Fail {
    Fail& operator=(Fail&&) noexcept(true) = default;
    std::unique_ptr<int> somePointer;
};

It works when noexcept is specified without (true). I'm not sure why the
template substitution for the unique_ptr has any constraints on the noexcept
specifications of the class that *owns* the unique_ptr, but syntactic
constraints are especially surprising.
Quuxplusone commented 7 years ago
The problem appears to still be happening on ToT:

-- t.cpp
template <class> struct something_template { static const bool value = true; };
struct A {
  A() noexcept(something_template<int>::value) = default;
};

$ clang -std=c++11 t.cpp -c
t.cpp:3:3: error: exception specification is not available until end of class
definition
  A() noexcept(something_template<int>::value) = default;
  ^
t.cpp:3:16: note: in instantiation of template class 'something_template<int>'
requested here
  A() noexcept(something_template<int>::value) = default;
               ^
1 error generated.