[PATCH] fix for bug 7857 - incomplete type as array parameter in C mode

Hi,

Last week I raised CR 7857. Basically clang rejects the following code
in C mode (-x -c):
typedef struct type TYPE;
void foo(TYPE p); <=== incomplete type error.

After reading the C99 spec, clang is probably right to reject that
code. Comeau also rejects it in strict mode (but accept it in relaxed
mode).
But both gcc and msvc accept the above code.
This error is preventing clang from compile <Windows.h> in C mode.

Here is a tentative patch to get around the problem.
What I did is to issue a warning instead of an error when
    - within function prototype scope
AND
    - building an array type of type T
AND
    - T is an incomplete struct type.

At least the warning won't prevent the compilation from succeeding.

is that ok?

incomplete_struct_array_param.patch (2.37 KB)

Index: lib/Sema/SemaType.cpp

Erm, this fix doesn't affect C++ at all... and the testcase in
question is perfectly legal C++, as far as I can tell.

-Eli

if (T->isFunctionType()) {

The getCurScope()->isFunctionPrototypeScope() check doesn't ensure that this is the type of a parameter; it only means that we're within a parameter list. For example, this would allow something like:

I am not sure what the goal of T->isFunctionType() is. At this point,
T is the type on which the array is built on. We want to check if it
is an incomplete struct not if it is a function type.

   typedef struct X X;
   template&lt;typename T&gt; struct A \{ \};
   void f\(A&lt;X\[\]&gt;\);

which we don't want.

The code will only be executed while compiling C code.

I am okay with the general direction of downgrading this to a warning for function declarations (not definitions), but only in the narrow case of a parameter of array type.

Any reason why that warning shoudn't apply to function definitions? I
did some testing and both msvc and gcc will accept an incomplete
struct array type even on a function definition parameter. As long you
don't use it in way that requires the definition.

For example you can write

typedef struct Type TYPE;
void bar(TYPE a);
void foo(TYPE a)
{
    bar(a);
}

But even if we wanted to emit the warning just for function
prototypes, I don't think it is easily possible with the current
design. The check to determine that we are parsing a function
definition is only done after the whole declarator has been parsed. I
couldn't find a way to check that the prototype is part of definition
at the point where the Array type is being built.

Just to clarify, recent gcc versions reject the construct in question.

-Eli