In gcc/objc/: 2010-12-29 Nicola Pero <nicola.pero@meta-innovation.com>
In gcc/objc/: 2010-12-29 Nicola Pero <nicola.pero@meta-innovation.com> PR objc/47118 * objc-act.c (objc_build_synchronized): Check the argument of @synchronized and emit an appropriate error if it is not a valid Objective-C object. Deal gracefully with that case. Updated comments and variable names. In gcc/testsuite/: 2010-12-29 Nicola Pero <nicola.pero@meta-innovation.com> PR objc/47118 * objc.dg/sync-3.m: New. * obj-c++.dg/sync-3.mm: New. From-SVN: r168326
This commit is contained in:
parent
9fdc58ded7
commit
37153b1e07
5 changed files with 319 additions and 18 deletions
|
@ -1,3 +1,11 @@
|
|||
2010-12-29 Nicola Pero <nicola.pero@meta-innovation.com>
|
||||
|
||||
PR objc/47118
|
||||
* objc-act.c (objc_build_synchronized): Check the argument of
|
||||
@synchronized and emit an appropriate error if it is not a valid
|
||||
Objective-C object. Deal gracefully with that case. Updated
|
||||
comments and variable names.
|
||||
|
||||
2010-12-29 Nicola Pero <nicola.pero@meta-innovation.com>
|
||||
|
||||
PR objc/47075
|
||||
|
|
|
@ -5630,28 +5630,59 @@ objc_build_throw_stmt (location_t loc, tree throw_expr)
|
|||
}
|
||||
|
||||
tree
|
||||
objc_build_synchronized (location_t start_locus, tree mutex, tree body)
|
||||
objc_build_synchronized (location_t start_locus, tree object_expr, tree body)
|
||||
{
|
||||
tree args, call;
|
||||
/* object_expr should never be NULL; but in case it is, convert it to
|
||||
error_mark_node. */
|
||||
if (object_expr == NULL)
|
||||
object_expr = error_mark_node;
|
||||
|
||||
/* First lock the mutex. */
|
||||
mutex = save_expr (mutex);
|
||||
args = tree_cons (NULL, mutex, NULL);
|
||||
call = build_function_call (input_location,
|
||||
objc_sync_enter_decl, args);
|
||||
SET_EXPR_LOCATION (call, start_locus);
|
||||
add_stmt (call);
|
||||
/* Validate object_expr. If not valid, set it to error_mark_node. */
|
||||
if (object_expr != error_mark_node)
|
||||
{
|
||||
if (!objc_type_valid_for_messaging (TREE_TYPE (object_expr), true))
|
||||
{
|
||||
error_at (start_locus, "%<@synchronized%> argument is not an object");
|
||||
object_expr = error_mark_node;
|
||||
}
|
||||
}
|
||||
|
||||
if (object_expr == error_mark_node)
|
||||
{
|
||||
/* If we found an error, we simply ignore the '@synchronized'.
|
||||
Compile the body so we can keep going with minimal
|
||||
casualties. */
|
||||
return add_stmt (body);
|
||||
}
|
||||
else
|
||||
{
|
||||
tree call;
|
||||
tree args;
|
||||
|
||||
/* Build the mutex unlock. */
|
||||
args = tree_cons (NULL, mutex, NULL);
|
||||
call = build_function_call (input_location,
|
||||
objc_sync_exit_decl, args);
|
||||
SET_EXPR_LOCATION (call, input_location);
|
||||
/* objc_sync_enter (object_expr); */
|
||||
object_expr = save_expr (object_expr);
|
||||
args = tree_cons (NULL, object_expr, NULL);
|
||||
call = build_function_call (input_location,
|
||||
objc_sync_enter_decl, args);
|
||||
SET_EXPR_LOCATION (call, start_locus);
|
||||
add_stmt (call);
|
||||
|
||||
/* Put the that and the body in a TRY_FINALLY. */
|
||||
objc_begin_try_stmt (start_locus, body);
|
||||
objc_build_finally_clause (input_location, call);
|
||||
return objc_finish_try_stmt ();
|
||||
/* Build "objc_sync_exit (object_expr);" but do not add it yet;
|
||||
it goes inside the @finalize() clause. */
|
||||
args = tree_cons (NULL, object_expr, NULL);
|
||||
call = build_function_call (input_location,
|
||||
objc_sync_exit_decl, args);
|
||||
SET_EXPR_LOCATION (call, input_location);
|
||||
|
||||
/* @try { body; } */
|
||||
objc_begin_try_stmt (start_locus, body);
|
||||
|
||||
/* @finally { objc_sync_exit (object_expr); } */
|
||||
objc_build_finally_clause (input_location, call);
|
||||
|
||||
/* End of try statement. */
|
||||
return objc_finish_try_stmt ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2010-12-29 Nicola Pero <nicola.pero@meta-innovation.com>
|
||||
|
||||
PR objc/47118
|
||||
* objc.dg/sync-3.m: New.
|
||||
* obj-c++.dg/sync-3.mm: New.
|
||||
|
||||
2010-12-29 Janus Weil <janus@gcc.gnu.org>
|
||||
|
||||
PR fortran/46838
|
||||
|
|
128
gcc/testsuite/obj-c++.dg/sync-3.mm
Normal file
128
gcc/testsuite/obj-c++.dg/sync-3.mm
Normal file
|
@ -0,0 +1,128 @@
|
|||
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
|
||||
/* { dg-options "-fobjc-exceptions" } */
|
||||
/* { dg-do compile } */
|
||||
|
||||
/* Test that the compiler is checking the argument of @synchronized(),
|
||||
and produce errors when invalid types are used. */
|
||||
|
||||
#include <objc/objc.h>
|
||||
|
||||
@interface MyObject
|
||||
{
|
||||
Class isa;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation MyObject
|
||||
@end
|
||||
|
||||
@protocol MyProtocol;
|
||||
|
||||
typedef MyObject MyObjectTypedef;
|
||||
typedef MyObject *MyObjectPtrTypedef;
|
||||
typedef int intTypedef;
|
||||
|
||||
typedef struct { float x; float y; } point, *point_ptr;
|
||||
|
||||
int test (id object)
|
||||
{
|
||||
int dummy = 0;
|
||||
|
||||
{
|
||||
int x;
|
||||
@synchronized (x) /* { dg-error ".@synchronized. argument is not an object" } */
|
||||
{ dummy++; }
|
||||
}
|
||||
|
||||
{
|
||||
intTypedef x;
|
||||
@synchronized (x) /* { dg-error ".@synchronized. argument is not an object" } */
|
||||
{ dummy++; }
|
||||
}
|
||||
|
||||
{
|
||||
int *x;
|
||||
@synchronized (x) /* { dg-error ".@synchronized. argument is not an object" } */
|
||||
{ dummy++; }
|
||||
}
|
||||
|
||||
{
|
||||
point x;
|
||||
@synchronized (x) /* { dg-error ".@synchronized. argument is not an object" } */
|
||||
{ dummy++; }
|
||||
}
|
||||
|
||||
{
|
||||
point_ptr x;
|
||||
@synchronized (x) /* { dg-error ".@synchronized. argument is not an object" } */
|
||||
{ dummy++; }
|
||||
}
|
||||
|
||||
{
|
||||
id x;
|
||||
@synchronized (x) /* Ok */
|
||||
{ dummy++; }
|
||||
}
|
||||
|
||||
{
|
||||
id <MyProtocol> x;
|
||||
@synchronized (x) /* Ok */
|
||||
{ dummy++; }
|
||||
}
|
||||
|
||||
{
|
||||
MyObject *x;
|
||||
@synchronized (x) /* Ok */
|
||||
{ dummy++; }
|
||||
}
|
||||
|
||||
{
|
||||
MyObject <MyProtocol> *x;
|
||||
@synchronized (x) /* Ok */
|
||||
{ dummy++; }
|
||||
}
|
||||
|
||||
{
|
||||
static MyObject *x;
|
||||
@synchronized (x) /* Ok */
|
||||
{ dummy++; }
|
||||
}
|
||||
|
||||
{
|
||||
MyObjectTypedef *x;
|
||||
@synchronized (x) /* Ok */
|
||||
{ dummy++; }
|
||||
}
|
||||
|
||||
{
|
||||
MyObjectTypedef <MyProtocol> *x;
|
||||
@synchronized (x) /* Ok */
|
||||
{ dummy++; }
|
||||
}
|
||||
|
||||
{
|
||||
MyObjectPtrTypedef x;
|
||||
@synchronized (x) /* Ok */
|
||||
{ dummy++; }
|
||||
}
|
||||
|
||||
{
|
||||
Class x;
|
||||
@synchronized (x) /* Ok */
|
||||
{ dummy++; }
|
||||
}
|
||||
|
||||
@synchronized (1) /* { dg-error ".@synchronized. argument is not an object" } */
|
||||
{ dummy++; }
|
||||
|
||||
@synchronized ("Test") /* { dg-error ".@synchronized. argument is not an object" } */
|
||||
{ dummy++; }
|
||||
|
||||
@synchronized () /* { dg-error "expected" } */
|
||||
{ dummy++; }
|
||||
|
||||
@synchronized (int) /* { dg-error "expected" } */
|
||||
{ dummy++; }
|
||||
|
||||
return dummy;
|
||||
}
|
128
gcc/testsuite/objc.dg/sync-3.m
Normal file
128
gcc/testsuite/objc.dg/sync-3.m
Normal file
|
@ -0,0 +1,128 @@
|
|||
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */
|
||||
/* { dg-options "-fobjc-exceptions" } */
|
||||
/* { dg-do compile } */
|
||||
|
||||
/* Test that the compiler is checking the argument of @synchronized(),
|
||||
and produce errors when invalid types are used. */
|
||||
|
||||
#include <objc/objc.h>
|
||||
|
||||
@interface MyObject
|
||||
{
|
||||
Class isa;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation MyObject
|
||||
@end
|
||||
|
||||
@protocol MyProtocol;
|
||||
|
||||
typedef MyObject MyObjectTypedef;
|
||||
typedef MyObject *MyObjectPtrTypedef;
|
||||
typedef int intTypedef;
|
||||
|
||||
typedef struct { float x; float y; } point, *point_ptr;
|
||||
|
||||
int test (id object)
|
||||
{
|
||||
int dummy = 0;
|
||||
|
||||
{
|
||||
int x;
|
||||
@synchronized (x) /* { dg-error ".@synchronized. argument is not an object" } */
|
||||
{ dummy++; }
|
||||
}
|
||||
|
||||
{
|
||||
intTypedef x;
|
||||
@synchronized (x) /* { dg-error ".@synchronized. argument is not an object" } */
|
||||
{ dummy++; }
|
||||
}
|
||||
|
||||
{
|
||||
int *x;
|
||||
@synchronized (x) /* { dg-error ".@synchronized. argument is not an object" } */
|
||||
{ dummy++; }
|
||||
}
|
||||
|
||||
{
|
||||
point x;
|
||||
@synchronized (x) /* { dg-error ".@synchronized. argument is not an object" } */
|
||||
{ dummy++; }
|
||||
}
|
||||
|
||||
{
|
||||
point_ptr x;
|
||||
@synchronized (x) /* { dg-error ".@synchronized. argument is not an object" } */
|
||||
{ dummy++; }
|
||||
}
|
||||
|
||||
{
|
||||
id x;
|
||||
@synchronized (x) /* Ok */
|
||||
{ dummy++; }
|
||||
}
|
||||
|
||||
{
|
||||
id <MyProtocol> x;
|
||||
@synchronized (x) /* Ok */
|
||||
{ dummy++; }
|
||||
}
|
||||
|
||||
{
|
||||
MyObject *x;
|
||||
@synchronized (x) /* Ok */
|
||||
{ dummy++; }
|
||||
}
|
||||
|
||||
{
|
||||
MyObject <MyProtocol> *x;
|
||||
@synchronized (x) /* Ok */
|
||||
{ dummy++; }
|
||||
}
|
||||
|
||||
{
|
||||
static MyObject *x;
|
||||
@synchronized (x) /* Ok */
|
||||
{ dummy++; }
|
||||
}
|
||||
|
||||
{
|
||||
MyObjectTypedef *x;
|
||||
@synchronized (x) /* Ok */
|
||||
{ dummy++; }
|
||||
}
|
||||
|
||||
{
|
||||
MyObjectTypedef <MyProtocol> *x;
|
||||
@synchronized (x) /* Ok */
|
||||
{ dummy++; }
|
||||
}
|
||||
|
||||
{
|
||||
MyObjectPtrTypedef x;
|
||||
@synchronized (x) /* Ok */
|
||||
{ dummy++; }
|
||||
}
|
||||
|
||||
{
|
||||
Class x;
|
||||
@synchronized (x) /* Ok */
|
||||
{ dummy++; }
|
||||
}
|
||||
|
||||
@synchronized (1) /* { dg-error ".@synchronized. argument is not an object" } */
|
||||
{ dummy++; }
|
||||
|
||||
@synchronized ("Test") /* { dg-error ".@synchronized. argument is not an object" } */
|
||||
{ dummy++; }
|
||||
|
||||
@synchronized () /* { dg-error "expected expression" } */
|
||||
{ dummy++; }
|
||||
|
||||
@synchronized (int) /* { dg-error "expected expression" } */
|
||||
{ dummy++; }
|
||||
|
||||
return dummy;
|
||||
}
|
Loading…
Add table
Reference in a new issue