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

Douglas Gregor dgregor at apple.com
Wed Aug 18 07:43:36 PDT 2010


On Aug 18, 2010, at 3:18 AM, Francois Pichet wrote:

> 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.


Index: lib/Sema/SemaType.cpp
===================================================================
--- lib/Sema/SemaType.cpp	(revision 111356)
+++ lib/Sema/SemaType.cpp	(working copy)
@@ -641,11 +641,19 @@
       return QualType();
     
   } else {
-    // C99 6.7.5.2p1: If the element type is an incomplete or function type,
-    // reject it (e.g. void ary[7], struct foo ary[7], void ary[7]())
-    if (RequireCompleteType(Loc, T,
+    if (getCurScope()->isFunctionPrototypeScope() &&
+        T->isStructureType() && T->isIncompleteType()) {
+      // For GCC/MS compatibility, we allow array of incomplete struct
+      // type in function prototype scope. Just emit an warning. 
+      RequireCompleteType(Loc, T, 
+                          diag::warn_parameter_array_incomplete_struct_type);
+    } else {  
+      // C99 6.7.5.2p1: If the element type is an incomplete or function type,
+      // reject it (e.g. void ary[7], struct foo ary[7], void ary[7]())
+      if (RequireCompleteType(Loc, T,
                             diag::err_illegal_decl_array_incomplete_type))
-      return QualType();
+        return QualType();
+    }
   }
 
   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:

	typedef struct X X;
	template<typename T> struct A { };
	void f(A<X[]>);

which we don't want.

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.

	- Doug





More information about the cfe-dev mailing list