On 02/13/2018 08:59 AM, Michael Matz wrote:
On Mon, 12 Feb 2018, Martin Sebor wrote:
Removing noreturn from the whitelist means having to prevent
the attribute from causing conflicts with the attributes on
the blacklist. E.g., in this:
template <class T> [[malloc]] void* allocate (int);
template <> [[noreturn]] void* allocate<void> (int);
Marking a function having a return type as noreturn doesn't make sense.
No, that's certainly not so in general(*). It makes sense
when a function cannot meaningfully be implemented to honor
its broader API contract (this applies to overloads, virtual
functions, and also template specializations). In the example
above, the author of the allocate template may wish to have it
allocate and initialize an array of T which can only be
implemented for non-void types so they define allocate like
template <class T>
allocate (int n)
return new T[n];
throw "cannot allocate void arrays";
Defining a specialization that differs from a primary or vice
versa is a common idiom that I don't want to force users to
As I already mentioned, this idiom has a parallel in object
oriented code (as opposed to in generic code) where a "pure"
virtual functions are declared to return a non-void type and
defined to exit/throw/abort, or not defined at all (i.e.,
the same as abort). In these case, warning would on calls
to such functions would be helpful the same that warning
on noreturn functions
So a warning in this case is actually a good thing.
A warning is only useful if it detects a bug or suggests
a potential improvement. The bug Jason is concerned about
having the warning detect involves changing the allocate
specialization in the future to return a value without
removing the noreturn atttribute. But that bug doesn't
exist with the implementation above and is already diagnosed
with the changed implementation, so there is no reason to
warn for it now.
No other use case/concern where a warning on the above might
be useful has been brought up so, AFAICS, the only instances
of the warning will be false positives.
And changing the
return type to void (so that noreturn makes sense) makes it not a
specialization anymore (or alternatively if the primary is also changed to
void then malloc doesn't make sense anymore).
Exactly. The only way to suppress the warning is to either
remove the attributes from the primary, or duplicate them
on the specialization. Neither approach would be correct
because neither would reflect the property of the declaration
it's applied to.
[*] There are a number of practical examples that show where
noreturn is useful with non-void return types. The common ones
involve overloads of APIs with an expected signature that are
not/cannot be implemented to return a value. See the cfe-dev
for one such example. For another one see N4226 where applying
noreturn to main was considered sufficiently useful to justify
a C++ proposal for an enhancement. (AFAIK, the proposal hasn't
yet been accepted.