[cfe-dev] K&R style argument lists and the type system
Chris Lattner
clattner at apple.com
Mon Aug 25 22:43:07 PDT 2008
On Aug 25, 2008, at 4:08 PM, Eli Friedman wrote:
> Consider the following testcase:
> int a() {return 0;}
> int b() {return a(1);}
>
> Calling b has undefined behavior per C99, but no diagnostics are
> required.
Right. I think that we should type functions with no arguments or
with an identifier list as FunctionTypeNoProto *always*. To issue the
(not required but prefered) diagnostic in this case, we should do two
checks:
1) is the callee compatible with the argument list (yes)
2) if the callee has a FunctionTypeNoProto type, and if it's body is
available, look at the body to see how many arguments it really had,
does it match up with the call site (no)
> Consider the following testcase:
> int a(int);
> int a() {return 0;}
> This is a constraint violation per C99.
Right, the sequence of events should be:
1) parse the declaration, "a" gets type "int(int)"
2) parse the definition which has type "int()"
3) merge the two types, giving "int(int)"
4) since it is a definition, verify that the actual argument list
matches the merged type.
> We currently map a() to FunctionTypeNoProto, and this has roughly the
> right behavior when we don't merge types. However, by adding merge
> types, we conclude that a() has type a(int), which is clearly wrong,
> and leads to crashes trying to access non-existent parameter
> declarations. But if we instead map a() to a FunctionTypeProto with
> no parameters, we incorrectly error out on the first example.
I think that the problem basically boils down to the fact that we
handle these:
int a() {}
int b(x) int x; {}
as FunctionTypeProto instead of FunctionTypeNoProto. Even though we
can "see" that 'a' takes no arguments, C doesn't let us take this into
consideration for its type. These should both really be
FunctionTypeNoProto.
>
> And actually, we already have this problem for cases like the
> following, which are less common:
> int a(x,y) int x,y; {return x+y;}
> int b() {return a(1,2,3);}
>
> Any ideas for how to solve this? We could always map definitions
> identifier-lists to FunctionTypeNoProto,
Yep, I agree with Steve that this is the best approach.
> but that means a good chunk
> of additional code to check type-merging doesn't do bad stuff to a
> definition and allow CodeGen to synthesize the type of such a function
> definition properly.
I'm not sure what you mean by this?
> Another possibility would be to add a flag to
> FunctionTypeProto which signifies whether the type comes from an
> identifier list; however, I have no idea where to add such a flag.
I think it would be better to make the compatibility check handle
FunctionTypeNoProto to see if it has a definition. As "value add", it
could look at the body to see if the body has arguments that are
incompatible with a call.
-Chris
More information about the cfe-dev
mailing list