Open Quuxplusone opened 5 years ago
Bugzilla Link | PR40039 |
Status | NEW |
Importance | P enhancement |
Reported by | Yuxuan Shui (yshuiv7@gmail.com) |
Reported on | 2018-12-15 16:07:36 -0800 |
Last modified on | 2018-12-19 09:47:01 -0800 |
Version | trunk |
Hardware | PC Linux |
CC | dblaikie@gmail.com, llvm-bugs@lists.llvm.org, neeilans@live.com, richard-llvm@metafoo.co.uk |
Fixed by commit(s) | |
Attachments | |
Blocks | |
Blocked by | |
See also |
The two prior diagnostics describe what Clang is thinking:
<source>:8:8: warning: type specifier missing, defaults to 'int' [-Wimplicit-
int]
asdf (*func2)(int *);
^
<source>:8:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-
int]
asdf (*func2)(int *);
^
So Clang thinks the only way this could parse is if you forgot a type-specifier
in two places, and (following C tradition) assumes you missed an 'int'. So it's
imagining you wrote:
int asdf(int *func2)(int *);
... which declares asdf as a function taking an int* and returning a function
of type 'int (int *)'.
In this case it'd be better to diagnose that the type 'asdf' is unknown, which
is what Clang does in C++ mode, but we appear to intentionally(?) support
implicit int here as an extension, which makes it challenging to treat this as
anything other than the above (ill-formed but syntactically valid) function
declaration.
I'm leaving this open because I'd like for us to do better diagnosing this, but
realistically I think the only way that's going to happen is if we remove the
'implicit int' extension in the above case.
> we appear to intentionally(?) support implicit int here as an extension
For clarity: the "here" here is in a function parameter, in a context where no
specifier is present at all. It seems reasonable to support implicit int in a
function return type when no specifiers are present, because that's valid when
defining a function in at least some modes (GCC also permits such invalid
code). And in the case where another specifier is present, the declaration
would be valid in C89 (eg, "int f(register *param);" declares f as taking an
"int *"). But there is no language mode in which you can use "int f(*p);" to
declare a function taking an "int*".
I see. If we have to keep this error message, we can still add a note telling the user what might be wrong (I.e. they missed a type declaration)
BTW, GCC and clang have different opinions on how to parse this:
asdf (*qwer);
GCC:
<source>:1:7: error: expected declaration specifiers or '...' before '*' token
asdf (*qwer);
^
clang:
<source>:1:8: warning: type specifier missing, defaults to 'int' [-Wimplicit-
int]
asdf (*a);
^
<source>:1:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-
int]
asdf (*a);
^
It is actually a bit weirder:
asdf (a);
Does not parse in clang, because:
<source>:3:5: error: a parameter list without types is only allowed in a
function definition
But clang happily accepts
asdf (*a);
And asdf(a) parses in gcc as a functino declaration.