What to do with noreturn (& other) function types

Seems that __attribute__((noreturn)) and probably some other attributes, form part of the function type as far as C++ language semantics are concerned - but not as far as name mangling (at least on itanium) is concerned.

So, for instance:

template<typename T>
struct t1 { };
void f() __attribute__((noreturn));
void g();
t1<decltype(f)> v1;
t1<decltype(g)> v2;

Produces two distinct types in the DWARF representation and at the language level like this:

void f1(decltype(f));
void f2() {
  f1(g); // fails to compile: error: no matching function for call to 'f1'
         // note:  candidate function not viable: no known conversion from 'void ()' to 'decltype(f) *' (aka 'void (*)() __attribute__((noreturn))') for 1st argument
}

(the inverse would be OK - a noreturn function type is implicitly convertible to an un-attributed (possibly-but-not-necessarily noreturning) function type)

But try to /define/ (declarations are OK) two overloads, and at least on Itanium, that’s not possible:

nrt2.cpp:8:6: error: definition with same mangled name '_Z2f1PFvvE' as another definition
void f1(decltype(g)) { }
     ^
nrt2.cpp:7:6: note: previous definition is here
void f1(decltype(f)) { }
     ^

I guess the answer is we should model this as we do today, as separate types. It does present a slight wrinkle for the Simplified Template Names work - since we don’t encode “noreturn” in a function type - so that’s probably an issue we should fix (seems there is a DWARF attribute, DW_AT_noreturn we can use for it - would need to add that to the DISubroutineType, etc) - though I’m not planning on doing that right away.

For now I’ll just not simplify templates that include parameters that have the noreturn attribute.

Yeah, ended up committing the workaround for simplified template names here: DebugInfo: Classify noreturn function types as non-reconstructible · llvm/llvm-project@7b498be · GitHub

At some point it’d probably be good to fix this and include the noreturn attribute on the SubroutineType - maybe in a flags field or the like.