===================================================================
@@ -1,10 +1,19 @@
2011-02-20 Nicola Pero <nicola.pero@meta-innovation.com>
- * objc-gnu-runtime-abi-01.c (TARGET_64BIT): Removed. Removed
- usage of padding fields. Do not include tm.h.
- * objc-act.c (objc_write_global_declaration): Set input_location
- to BUILTINS_LOCATION while generating runtime metadata.
+ PR objc/47832
+ * objc-act.c (flexible_array_type_p): New.
+ (add_instance_variable): Produce an error if an instance variable
+ is of flexible array type.
+ (encode_array): Do not emit an error if encoding a flexible array
+ type while generating instance variables.
+2011-02-20 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ * objc-gnu-runtime-abi-01.c (TARGET_64BIT): Removed. Removed
+ usage of padding fields. Do not include tm.h.
+ * objc-act.c (objc_write_global_declaration): Set input_location
+ to BUILTINS_LOCATION while generating runtime metadata.
+
2011-01-20 Nicola Pero <nicola.pero@meta-innovation.com>
PR objc/47784
===================================================================
@@ -5925,6 +5925,49 @@ add_category (tree klass, tree category)
}
}
+/* TODO: The check for flexible array members in instance variables is
+ implemented only for ObjC, and it is implemented by using this
+ flexible_array_type_p() function, which is basically lifted from
+ c-decl.c. Is this the best way of doing the check ? */
+
+/* flexible_array_type_p() seems to crash the compiler when used in
+ ObjC++, so we disable the check in ObjC++. */
+#ifndef OBJCPLUS
+/* Determine whether TYPE is a structure with a flexible array member,
+ or a union containing such a structure (possibly recursively). These
+ are invalid as instance variable. */
+
+static bool
+flexible_array_type_p (tree type)
+{
+ tree x;
+ switch (TREE_CODE (type))
+ {
+ case RECORD_TYPE:
+ x = TYPE_FIELDS (type);
+ if (x == NULL_TREE)
+ return false;
+ while (DECL_CHAIN (x) != NULL_TREE)
+ x = DECL_CHAIN (x);
+ if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE
+ && TYPE_SIZE (TREE_TYPE (x)) == NULL_TREE
+ && TYPE_DOMAIN (TREE_TYPE (x)) != NULL_TREE
+ && TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (x))) == NULL_TREE)
+ return true;
+ return false;
+ case UNION_TYPE:
+ for (x = TYPE_FIELDS (type); x != NULL_TREE; x = DECL_CHAIN (x))
+ {
+ if (flexible_array_type_p (TREE_TYPE (x)))
+ return true;
+ }
+ return false;
+ default:
+ return false;
+ }
+}
+#endif
+
/* Called after parsing each instance variable declaration. Necessary to
preserve typedefs and implement public/private...
@@ -5958,6 +6001,27 @@ add_instance_variable (tree klass, objc_ivar_visib
return klass;
}
+ /* Also, reject a struct with a flexible array member. Ie,
+
+ struct A { int x; int[] y; };
+
+ @interface X
+ {
+ struct A instance_variable;
+ }
+ @end
+
+ is not valid as 'struct A' doesn't have a known size. */
+#ifndef OBJCPLUS
+ /* TODO: Implemented this check for ObjC++ too. */
+ if (flexible_array_type_p (field_type))
+ {
+ error ("instance variable %qs has unknown size", ivar_name);
+ /* Return class as is without adding this ivar. */
+ return klass;
+ }
+#endif
+
#ifdef OBJCPLUS
/* Check if the ivar being added has a non-POD C++ type. If so, we will
need to either (1) warn the user about it or (2) generate suitable
@@ -9926,27 +9990,23 @@ encode_array (tree type, int curtype, int format)
if (an_int_cst == NULL)
{
/* We are trying to encode an incomplete array. An incomplete
- array is forbidden as part of an instance variable. */
- if (generating_instance_variables)
- {
- /* TODO: Detect this error earlier. */
- error ("instance variable has unknown size");
- return;
- }
+ array is forbidden as part of an instance variable; but it
+ may occur if the instance variable is a pointer to such an
+ array. */
- /* So the only case in which an incomplete array could occur is
- if we are encoding the arguments or return value of a method.
- In that case, an incomplete array argument or return value
- (eg, -(void)display: (char[])string) is treated like a
- pointer because that is how the compiler does the function
- call. A special, more complicated case, is when the
- incomplete array is the last member of a struct (eg, if we
- are encoding "struct { unsigned long int a;double b[];}"),
- which is again part of a method argument/return value. In
- that case, we really need to communicate to the runtime that
- there is an incomplete array (not a pointer!) there. So, we
- detect that special case and encode it as a zero-length
- array.
+ /* So the only case in which an incomplete array could occur
+ (without being pointed to) is if we are encoding the
+ arguments or return value of a method. In that case, an
+ incomplete array argument or return value (eg,
+ -(void)display: (char[])string) is treated like a pointer
+ because that is how the compiler does the function call. A
+ special, more complicated case, is when the incomplete array
+ is the last member of a struct (eg, if we are encoding
+ "struct { unsigned long int a;double b[];}"), which is again
+ part of a method argument/return value. In that case, we
+ really need to communicate to the runtime that there is an
+ incomplete array (not a pointer!) there. So, we detect that
+ special case and encode it as a zero-length array.
Try to detect that we are part of a struct. We do this by
searching for '=' in the type encoding for the current type.
===================================================================
@@ -1,3 +1,8 @@
+2011-02-21 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ PR objc/47832
+ * objc.dg/type-size-4.m: New test.
+
2011-02-21 Jeff Law <law@redhat.com>
PR rtl-optimization/46178
===================================================================
@@ -10,11 +10,9 @@ typedef struct
@interface Test
{
- test_type c;
+ test_type c; /* { dg-error "instance variable .c. has unknown size" } */
}
@end
@implementation Test
@end
-
-/* { dg-error "instance variable has unknown size" "" { target *-*-* } 0 } */
===================================================================
@@ -0,0 +1,20 @@
+/* Allow ivars that are pointers to structs with an unknown size. */
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com> */
+/* PR objc/47832 */
+/* { dg-do compile } */
+
+typedef struct
+{
+ unsigned long int a;
+ double b[];
+} test_type;
+
+@interface Test
+{
+ /* This is fine. */
+ test_type *c;
+}
+@end
+
+@implementation Test
+@end