aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNicola Pero <nicola.pero@meta-innovation.com>2010-12-29 21:52:00 +0000
committerNicola Pero <nicola@gcc.gnu.org>2010-12-29 21:52:00 +0000
commit37153b1e0743ba79cc6d86b92e843995ab015755 (patch)
tree28dcffe9c04ce1bede7dfe150127f4b08af4251b /gcc
parent9fdc58ded7f2bdaa25e8019ea85442f58e4683ad (diff)
downloadgcc-37153b1e0743ba79cc6d86b92e843995ab015755.zip
gcc-37153b1e0743ba79cc6d86b92e843995ab015755.tar.gz
gcc-37153b1e0743ba79cc6d86b92e843995ab015755.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/objc/ChangeLog8
-rw-r--r--gcc/objc/objc-act.c75
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/obj-c++.dg/sync-3.mm128
-rw-r--r--gcc/testsuite/objc.dg/sync-3.m128
5 files changed, 323 insertions, 22 deletions
diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog
index d5da4ce..5523829 100644
--- a/gcc/objc/ChangeLog
+++ b/gcc/objc/ChangeLog
@@ -1,5 +1,13 @@
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
* objc-act.h (PROPERTY_REF_DEPRECATED_GETTER): New.
* objc-tree.def (PROPERTY_REF): Increased the number of operands
diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
index 57f0460..47f3fbc 100644
--- a/gcc/objc/objc-act.c
+++ b/gcc/objc/objc-act.c
@@ -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)
-{
- tree args, call;
-
- /* 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);
-
- /* 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);
-
- /* 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 ();
+objc_build_synchronized (location_t start_locus, tree object_expr, tree body)
+{
+ /* 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;
+
+ /* 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;
+
+ /* 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);
+
+ /* 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 ();
+ }
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 49cf9fc..9019f79 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/obj-c++.dg/sync-3.mm b/gcc/testsuite/obj-c++.dg/sync-3.mm
new file mode 100644
index 0000000..95def43
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/sync-3.mm
@@ -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;
+}
diff --git a/gcc/testsuite/objc.dg/sync-3.m b/gcc/testsuite/objc.dg/sync-3.m
new file mode 100644
index 0000000..5cee890
--- /dev/null
+++ b/gcc/testsuite/objc.dg/sync-3.m
@@ -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;
+}