llvm / llvm-project

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

Exception specifications should only be instantiated when the function is #9857

Closed llvmbot closed 11 years ago

llvmbot commented 13 years ago
Bugzilla Link 9485
Resolution FIXED
Resolved on Feb 23, 2013 23:49
Version trunk
OS All
Reporter LLVM Bugzilla Contributor
CC @DougGregor,@ismail,@zygoloid

Extended Description

Consider:

template void f1(T) throw(typename T::exception); template void f1(T, int = 0) throw(typename T::noitpecxe);

template void f2(T) noexcept(T::throws); template void f2(T, int = 0) noexcept(T::sworht);

void test() { f1(0); f2(0); }

The above test case can distinguish between the treatment of exception specifications during overload resolution and template instantiations. There are three possible outcomes: 1) The program fails with an ambiguity error. This is what the standard says should happen, because exception specifications are not part of the function type and thus are not instantiated during overload resolution, only when actually instantiating the function. So both templates are equally valid. This is what Comeau Online does. (For the throw() spec. Comeau doesn't yet support noexcept.) 2) The program fails with no available overloads. This is what would happen if the exception specification were a SFINAE context. This also happens to be what GCC 4.5 does. (Again, for throw(). I don't have handy access to GCC 4.6.) 3) The program generates errors when resolving the overloads, because int cannot be used on the left side of ::. This is what happens when the compiler instantiates the spec together with the type, but doesn't treat it as a SFINAE context.

Clang first produces the error from 3, but then also produces the error from 1.

DougGregor commented 12 years ago

It's not clear what C++98 is supposed to do here. I'm content with having it fixed in C++11 by the C++11 rules.

ec04fc15-fa35-46f2-80e1-5d271f2ef708 commented 12 years ago

Fixed for C++11 in r154886.

We still diagnose the instantiations in C++98 mode. I'm not sure whether that's correct.

DougGregor commented 13 years ago

So we want to suppress instantiation of the specification while only doing overload resolution.

Hmm ... this is going to be fun.

It's more fun than that :)

Essentially, instantiating the function declaration does not instantiate the exception specification. Rather, we instantiate the exception specification on demand when we need it, e.g.,

Basically, we'll end up instantiating the exception specification lazily.

llvmbot commented 13 years ago

So we want to suppress instantiation of the specification while only doing overload resolution.

Hmm ... this is going to be fun.

DougGregor commented 13 years ago

The direction the committee intends to go with this is to only instantiate the exception specification when it's needed, e.g., if there's a call to that function, or its address is taken, or 'noexcept' is asking whether it throws.