+2011-06-01 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ * objc-act.c (objc_decl_method_attributes): Implement nonnull
+ attribute for Objective-C methods.
+
2011-05-21 Nicola Pero <nicola.pero@meta-innovation.com>
* config-lang.in (gtfiles): Updated order of files to fix building
filtered_attributes = chainon (filtered_attributes,
new_attribute);
}
+ else if (is_attribute_p ("nonnull", name))
+ {
+ /* We need to fixup all the argument indexes by adding 2
+ for the two hidden arguments of an Objective-C method
+ invocation, similat to what we do above for the
+ "format" attribute. */
+ /* FIXME: This works great in terms of implementing the
+ functionality, but the warnings that are produced by
+ nonnull do mention the argument index (while the
+ format ones don't). For example, you could get
+ "warning: null argument where non-null required
+ (argument 3)". Now in that message, "argument 3"
+ includes the 2 hidden arguments; it would be much
+ more friendly to call it "argument 1", as that would
+ be consistent with __attribute__ ((nonnnull (1))).
+ To do this, we'd need to have the C family code that
+ checks the arguments know about adding/removing 2 to
+ the argument index ... or alternatively we could
+ maybe store the "printable" argument index in
+ addition to the actual argument index ? Some
+ refactoring is needed to do this elegantly. */
+ tree new_attribute = copy_node (attribute);
+ tree argument = TREE_VALUE (attribute);
+ while (argument != NULL_TREE)
+ {
+ /* Get the value of the argument and add 2. */
+ tree number = TREE_VALUE (argument);
+ if (number
+ && TREE_CODE (number) == INTEGER_CST
+ && TREE_INT_CST_HIGH (number) == 0
+ && TREE_INT_CST_LOW (number) != 0)
+ {
+ TREE_VALUE (argument)
+ = build_int_cst (integer_type_node,
+ TREE_INT_CST_LOW (number) + 2);
+ }
+ argument = TREE_CHAIN (argument);
+ }
+
+ filtered_attributes = chainon (filtered_attributes,
+ new_attribute);
+ }
else
warning (OPT_Wattributes, "%qE attribute directive ignored", name);
}
+2011-06-01 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ * objc.dg/attributes/method-nonnull-1.m: New test.
+ * obj-c++.dg/attributes/method-nonnull-1.mm: New test.
+
2011-05-31 Tobias Burnus <burnus@net-b.de>
PR fortran/18918
--- /dev/null
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, May 2011. */
+/* { dg-do compile } */
+/* { dg-options "-Wall" } */
+
+#include <objc/objc.h>
+#include <stdlib.h>
+
+@interface MyArray
+{
+ Class isa;
+}
++ (void) addObject: (id)object __attribute__ ((nonnull));
+- (void) addObject: (id)object __attribute__ ((nonnull));
+
++ (void) insertObject: (id)object atIndex: (size_t)index __attribute__ ((nonnull (1)));
+- (void) insertObject: (id)object atIndex: (size_t)index __attribute__ ((nonnull (1)));
+
++ (void) insertObject: (id)object atIndex: (size_t)index andObject: (id)anotherObject atIndex: (size_t)anotherIndex __attribute__ ((nonnull (1, 3)));
+- (void) insertObject: (id)object atIndex: (size_t)index andObject: (id)anotherObject atIndex: (size_t)anotherIndex __attribute__ ((nonnull (1, 3)));
+
+/* Test the behaviour with invalid code. */
++ (void) removeObject: (id)object __attribute__ ((nonnull (0))); /* { dg-error "out-of-range" } */
+- (void) removeObject: (id)object __attribute__ ((nonnull (0))); /* { dg-error "out-of-range" } */
+
++ (void) removeObject: (id)object __attribute__ ((nonnull (2))); /* { dg-error "out-of-range" } */
+- (void) removeObject: (id)object __attribute__ ((nonnull (2))); /* { dg-error "out-of-range" } */
+
++ (void) removeObjectAtIndex: (size_t)object __attribute__ ((nonnull (1))); /* { dg-error "non-pointer operand" } */
+- (void) removeObjectAtIndex: (size_t)object __attribute__ ((nonnull (1))); /* { dg-error "non-pointer operand" } */
+
++ (void) removeObject: (id)object __attribute__ ((nonnull (MyArray))); /* { dg-error "" } */
+- (void) removeObject: (id)object __attribute__ ((nonnull (MyArray))); /* { dg-error "" } */
+@end
+
+void test (MyArray *object)
+{
+ [object addObject: object];
+ [object addObject: nil]; /* { dg-warning "null argument where non-null required" } */
+
+ [object insertObject: object atIndex: 4];
+ [object insertObject: nil atIndex: 4]; /* { dg-warning "null argument where non-null required" } */
+
+ [object insertObject: object atIndex: 2 andObject: object atIndex: 3];
+ [object insertObject: nil atIndex: 2 andObject: object atIndex: 3]; /* { dg-warning "null argument where non-null required" } */
+ [object insertObject: object atIndex: 2 andObject: nil atIndex: 3]; /* { dg-warning "null argument where non-null required" } */
+}
--- /dev/null
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, May 2011. */
+/* { dg-do compile } */
+/* { dg-options "-Wall" } */
+
+#include <objc/objc.h>
+#include <stdlib.h>
+
+@interface MyArray
+{
+ Class isa;
+}
++ (void) addObject: (id)object __attribute__ ((nonnull));
+- (void) addObject: (id)object __attribute__ ((nonnull));
+
++ (void) insertObject: (id)object atIndex: (size_t)index __attribute__ ((nonnull (1)));
+- (void) insertObject: (id)object atIndex: (size_t)index __attribute__ ((nonnull (1)));
+
++ (void) insertObject: (id)object atIndex: (size_t)index andObject: (id)anotherObject atIndex: (size_t)anotherIndex __attribute__ ((nonnull (1, 3)));
+- (void) insertObject: (id)object atIndex: (size_t)index andObject: (id)anotherObject atIndex: (size_t)anotherIndex __attribute__ ((nonnull (1, 3)));
+
+/* Test the behaviour with invalid code. */
++ (void) removeObject: (id)object __attribute__ ((nonnull (0))); /* { dg-error "out-of-range" } */
+- (void) removeObject: (id)object __attribute__ ((nonnull (0))); /* { dg-error "out-of-range" } */
+
++ (void) removeObject: (id)object __attribute__ ((nonnull (2))); /* { dg-error "out-of-range" } */
+- (void) removeObject: (id)object __attribute__ ((nonnull (2))); /* { dg-error "out-of-range" } */
+
++ (void) removeObjectAtIndex: (size_t)object __attribute__ ((nonnull (1))); /* { dg-error "non-pointer operand" } */
+- (void) removeObjectAtIndex: (size_t)object __attribute__ ((nonnull (1))); /* { dg-error "non-pointer operand" } */
+
++ (void) removeObject: (id)object __attribute__ ((nonnull (MyArray))); /* { dg-error "invalid operand" } */
+- (void) removeObject: (id)object __attribute__ ((nonnull (MyArray))); /* { dg-error "invalid operand" } */
+@end
+
+void test (MyArray *object)
+{
+ [object addObject: object];
+ [object addObject: nil]; /* { dg-warning "null argument where non-null required" } */
+
+ [object insertObject: object atIndex: 4];
+ [object insertObject: nil atIndex: 4]; /* { dg-warning "null argument where non-null required" } */
+
+ [object insertObject: object atIndex: 2 andObject: object atIndex: 3];
+ [object insertObject: nil atIndex: 2 andObject: object atIndex: 3]; /* { dg-warning "null argument where non-null required" } */
+ [object insertObject: object atIndex: 2 andObject: nil atIndex: 3]; /* { dg-warning "null argument where non-null required" } */
+}