Doubt on a couple of warnings on deleted functions

Hello.

Consider this:

$ cat example.cpp
void func(int x) = delete;
$ clang++ -std=c++11 -fsyntax-only -Wunused-parameter -Wmissing-prototypes example.cpp
example.cpp:1:6: warning: no previous prototype for function 'func' [-Wmissing-prototypes]
void func(int x) = delete;
     ^
example.cpp:1:15: warning: unused parameter 'x' [-Wunused-parameter]
void func(int x) = delete;
              ^
2 warnings generated.

The two warnings seems false positives:

1) why does it warn about a missing prototype? One can't add a prototype because
he'll get this error:

error: deleted definition must be first declaration
void func(int x) = delete;

So, the deleted definition is acting like a prototype itself, doesn't it? I think the warning
is wrong.

2) Does it make sense to warn about an unused parameter on a deleted definition?
Of course is unused, but it can't be used anyway.
This force the programmer to avoid parameters name, like:
void func(int) = delete;
but this can reduce readability and it seems to me there's no reason to force it.

Note that these warnings pop up only on free functions. Deleted member functions
don't generate these warnings in these cases.

Does it make sense to fix these issues?

This mail is a part of a more general effort of mine to be able to warning-less include
(with -Weverything, more or less) the LLVM headers that I use in my project.
I think (and hope) more will follow.

Thanks,
Nicola

Yep
Both of these sound like bugs and should be able to be fixed just by checking for a non-deleted definition. I’m not sure if there’s a particular function to test that.

The unused variable one might crop up in defaulted functions too, in which case we’ll want to check for a user provided definition.

Yep
Both of these sound like bugs and should be able to be fixed just by
checking for a non-deleted definition. I'm not sure if there's a particular
function to test that.

I think the first warning is entirely appropriate. The point of this
warning is that every external linkage function should be declared in a
header file; it'd help if the warning suggested something like 'mark this
function 'static' if it's not intended to be used in other files' or
similar.

The unused variable one might crop up in defaulted functions too, in which
case we'll want to check for a user provided definition.

I agree on both counts. The same warning is visible here:

struct S { S(const S&s); }; S::S(const S&s) = default;

Yep
Both of these sound like bugs and should be able to be fixed just by
checking for a non-deleted definition. I'm not sure if there's a particular
function to test that.

I think the first warning is entirely appropriate. The point of this
warning is that every external linkage function should be declared in a
header file; it'd help if the warning suggested something like 'mark this
function 'static' if it's not intended to be used in other files' or
similar.

The unused variable one might crop up in defaulted functions too, in
which case we'll want to check for a user provided definition.

I agree on both counts. The same warning is visible here:

struct S { S(const S&s); }; S::S(const S&s) = default;

... hmm, no, user-provided isn't the right check; the above function *is*
user-provided.

Yep
Both of these sound like bugs and should be able to be fixed just by
checking for a non-deleted definition. I'm not sure if there's a particular
function to test that.

I think the first warning is entirely appropriate. The point of this warning
is that every external linkage function should be declared in a header file;

Sure, but how would you declare the deleted function in a header file
separate from its delete definition?

What you put in the header file is "void func() = delete;" and that's
where the warning fires, isn't it?

Yep
Both of these sound like bugs and should be able to be fixed just by
checking for a non-deleted definition. I’m not sure if there’s a particular
function to test that.

I think the first warning is entirely appropriate. The point of this warning
is that every external linkage function should be declared in a header file;

Sure, but how would you declare the deleted function in a header file
separate from its delete definition?

What you put in the header file is “void func() = delete;” and that’s
where the warning fires, isn’t it?

No, the warning fires if the first declaration of an externally visible function is in the main source file.

>>
>> Yep
>> Both of these sound like bugs and should be able to be fixed just by
>> checking for a non-deleted definition. I'm not sure if there's a
>> particular
>> function to test that.
>
> I think the first warning is entirely appropriate. The point of this
> warning
> is that every external linkage function should be declared in a header
> file;

Sure, but how would you declare the deleted function in a header file
separate from its delete definition?

What you put in the header file is "void func() = delete;" and that's
where the warning fires, isn't it?

No, the warning fires if the first declaration of an externally visible
function is in the main source file.

That doesn't seem to be consistent with what I'm seeing:

$ cat deleted.h
void func() = delete;
$ cat deleted.cpp
#include "deleted.h"
$ clang++-tot deleted.cpp -Wmissing-prototypes -fsyntax-only -std=c++11
In file included from deleted.cpp:1:
./deleted.h:1:6: warning: no previous prototype for function 'func'
[-Wmissing-prototypes]
void func() = delete;
     ^
1 warning generated.

>
>>
>> >>
>> >> Yep
>> >> Both of these sound like bugs and should be able to be fixed just by
>> >> checking for a non-deleted definition. I'm not sure if there's a
>> >> particular
>> >> function to test that.
>> >
>> > I think the first warning is entirely appropriate. The point of this
>> > warning
>> > is that every external linkage function should be declared in a header
>> > file;
>>
>> Sure, but how would you declare the deleted function in a header file
>> separate from its delete definition?
>>
>> What you put in the header file is "void func() = delete;" and that's
>> where the warning fires, isn't it?
>
> No, the warning fires if the first declaration of an externally visible
> function is in the main source file.

That doesn't seem to be consistent with what I'm seeing:

$ cat deleted.h
void func() = delete;
$ cat deleted.cpp
#include "deleted.h"
$ clang++-tot deleted.cpp -Wmissing-prototypes -fsyntax-only -std=c++11
In file included from deleted.cpp:1:
./deleted.h:1:6: warning: no previous prototype for function 'func'
[-Wmissing-prototypes]
void func() = delete;
     ^
1 warning generated.

That's definitely a bug! =)

Looks like one issue is that isInlined() is incorrectly returning false for
deleted functions. An issue in the opposite direction is that there's no
'main source file' check (a forward declaration in the main source file
suppresses the warning, and really shouldn't).

(This warning also seems to be confused about whether it's looking for a C
function missing an explicit prototype and a C++ function missing a
previous declaration.)