Commit 98ab0248 by Nicola Pero Committed by Nicola Pero

In gcc/objc/: 2011-06-01 Nicola Pero <nicola.pero@meta-innovation.com>

In gcc/objc/:
2011-06-01  Nicola Pero  <nicola.pero@meta-innovation.com>

	* objc-act.c (objc_decl_method_attributes): Implement nonnull
	attribute for Objective-C methods.

In gcc/testsuite/:
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.

From-SVN: r174520
parent 6807da97
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
......
......@@ -5042,6 +5042,48 @@ objc_decl_method_attributes (tree *node, tree attributes, int flags)
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
......
/* 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" } */
}
/* 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" } */
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment