[cxx-abi-dev] manglings for exception specifications in function types

Jason Merrill jason at redhat.com
Wed Nov 2 19:39:45 UTC 2016


On Wed, Nov 2, 2016 at 2:19 PM, Richard Smith <richardsmith at google.com> wrote:
> On 2 November 2016 at 11:13, Jason Merrill <jason at redhat.com> wrote:
>>
>> On Sun, Oct 23, 2016 at 1:10 AM, Richard Smith <richardsmith at google.com>
>> wrote:
>> > On 11 October 2016 at 14:11, Richard Smith <richardsmith at google.com>
>> > wrote:
>> >>
>> >> Under
>> >>   http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0012r1.html
>> >>
>> >> the noexceptness of a function type is now part of the type. As a
>> >> result,
>> >> we need manglings for exception-specifications on function
>> >> pointer/reference
>> >> types:
>> >>
>> >> void f(void()) {}
>> >> void f(void() noexcept) {} // ok, overload not redefinition
>> >>
>> >> (It's not clear to me whether or not this was also necessary prior to
>> >> C++17 to handle dependent exception specifications that appear
>> >> lexically
>> >> within the parameter list of a function template, and actual
>> >> implementation
>> >> practice varies as to whether such exception specifications are
>> >> SFINAEable.)
>> >>
>> >> In order to handle overloading/SFINAE on exception specifications in
>> >> dependent cases, we need to be able to mangle not only "noexcept", but
>> >> also
>> >> "noexcept(expression)" and "throw(<types>)". Suggestion for manglings:
>> >>
>> >> <exception-spec> ::=
>> >>   nx  -- non-throwing exception specification
>> >>   nX <expression> E  -- computed (value-dependent) noexcept
>> >
>> > Minor correction: this should be mangled if instantiation-dependent, not
>> > only if value-dependent. It appears that SFINAE can happen here.
>> >
>> >>   tw <type>* E  -- throw (types)
>> >> <function-type> ::= [<CV-qualifiers>] [<exception-spec>] [Dx] F [Y]
>> >> <bare-function-type> [<ref-qualifier>] E
>> >>
>> >> In the case of throw(a, b, c), we could omit types that are neither
>> >> instantiation-dependent nor pack expansions (if that omits all types,
>> >> we can
>> >> use the 'nx' mangling instead), since C++17 says you can't overload on
>> >> the
>> >> actual types in the dynamic exception specification, and we otherwise
>> >> only
>> >> need them to be present if they might result in a substitution failure.
>> >>
>> >> Thoughts?
>>
>> I'm uncomfortable with adding new mangling for the intersection of a
>> new C++17 feature and a deprecated feature that just barely missed
>> being removed from C++17 (though we'll see what happens next week),
>> especially since you can't overload on it,
>
> Why not? [temp.over.link]/4 doesn't have any special case for exception
> specifications, so as far as I can see, this is valid:
>
> // If T has a nested type 'exception', the function might throw it.
> template<typename T> void f(void p() throw(typename T::exception)) { try {
> p(); } catch (...) { /*...*/ } }
> // Otherwise we can assume it doesn't throw anything.
> template<typename T> void f(void p() noexcept) { p(); }
>
> ... and will do SFINAE on the existence of a nested type 'exception' within
> T.

I suppose so, sigh.

I notice that with this specification,

void f (void (*p)() noexcept) { }

would mangle as

_Z1fPnxFvvE

which currently means

f(__int128*, long long, void ())

which is ill-formed, but I'd rather not require the demangler to recognize that.

Maybe Do, DO and Dw instead?

Jason


More information about the cxx-abi-dev mailing list