From a868a203a18571d091e5d226f5f100d4440f3d94 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 21 Apr 2009 06:11:25 +0000 Subject: [PATCH] implement semantic analysis for @synchronized, fixing a crash on invalid rdar://6810940 - @synchronized has no sema checks git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69670 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 4 +- lib/Sema/SemaStmt.cpp | 9 +++ test/Parser/objc-try-catch-1.m | 5 +- test/SemaObjC/synchronized.m | 78 ++++------------------ test/SemaObjC/try-catch.m | 6 +- 5 files changed, 32 insertions(+), 70 deletions(-) diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index b270feccc8..acfc006738 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -1079,7 +1079,9 @@ def warn_bad_receiver_type : Warning< "casting it to 'id'">; def err_bad_receiver_type : Error<"bad receiver type %0">; def error_objc_throw_expects_object : Error< - "invalid %0 argument (expected an ObjC object type)">; + "@throw requires an Objective-C object type (%0 invalid)">; +def error_objc_synchronized_expects_object : Error< + "@synchronized requires an Objective-C object type (%0 invalid)">; def error_rethrow_used_outside_catch : Error< "@throw (rethrow) used outside of a @catch block">; def err_attribute_multiple_objc_gc : Error< diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 26cba5bec7..fb8a8ece43 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -1092,6 +1092,15 @@ Sema::ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, ExprArg SynchExpr, StmtArg SynchBody) { CurFunctionNeedsScopeChecking = true; + // Make sure the expression type is an ObjC pointer or "void *". + Expr *SyncExpr = static_cast(SynchExpr.get()); + if (!Context.isObjCObjectPointerType(SyncExpr->getType())) { + const PointerType *PT = SyncExpr->getType()->getAsPointerType(); + if (!PT || !PT->getPointeeType()->isVoidType()) + return StmtError(Diag(AtLoc, diag::error_objc_synchronized_expects_object) + << SyncExpr->getType() << SyncExpr->getSourceRange()); + } + return Owned(new (Context) ObjCAtSynchronizedStmt(AtLoc, static_cast(SynchExpr.release()), static_cast(SynchBody.release()))); diff --git a/test/Parser/objc-try-catch-1.m b/test/Parser/objc-try-catch-1.m index 2c41cac3ee..a8d37f0ab9 100644 --- a/test/Parser/objc-try-catch-1.m +++ b/test/Parser/objc-try-catch-1.m @@ -27,7 +27,10 @@ void * foo() return proc(); } @catch (Frob* ex) { - @throw 1,2; // expected-error {{invalid 'int' argument (expected an ObjC object type)}} + @throw 1,2; // expected-error {{@throw requires an Objective-C object type ('int' invalid)}} + } + @catch (float x) { // expected-error {{@catch parameter is not a pointer to an interface type}} + } @catch(...) { @throw (4,3,proc()); diff --git a/test/SemaObjC/synchronized.m b/test/SemaObjC/synchronized.m index d4914fd895..e8e668fd8b 100644 --- a/test/SemaObjC/synchronized.m +++ b/test/SemaObjC/synchronized.m @@ -1,75 +1,23 @@ // RUN: clang-cc -fsyntax-only -verify %s -typedef signed char BOOL; -typedef unsigned int NSUInteger; -typedef struct _NSZone NSZone; -@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; -@protocol NSObject -- (BOOL)isEqual:(id)object; -@end - -@protocol NSCopying -- (id)copyWithZone:(NSZone *)zone; -@end - -@protocol NSMutableCopying -- (id)mutableCopyWithZone:(NSZone *)zone; -@end - -@protocol NSCoding -- (void)encodeWithCoder:(NSCoder *)aCoder; -@end - -@interface NSObject {} @end - -typedef float CGFloat; -typedef struct { int a; } NSFastEnumerationState; - -@protocol NSFastEnumeration -- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len; -@end - -typedef unsigned short unichar; - -@interface NSString : NSObject -- (NSUInteger)length; -@end - -@interface NSSimpleCString : NSString {} @end - -@interface NSConstantString : NSSimpleCString @end - -extern void *_NSConstantStringClassReference; - -@interface NSDictionary : NSObject -- (NSUInteger)count; -@end - -@interface NSMutableDictionary : NSDictionary -- (void)removeObjectForKey:(id)aKey; -@end - -@class NSArray, NSSet, NSHashTable; - -@protocol PBXTrackableTask -- (float) taskPercentComplete; -- taskIdentifier; -@end - -@interface PBXTrackableTaskManager : NSObject { - NSMutableDictionary *_trackableTasks; -} -@end - -NSString *XCExecutableDebugTaskIdentifier = @"XCExecutableDebugTaskIdentifier"; +@class PBXTrackableTaskManager; @implementation PBXTrackableTaskManager - (id) init {} -- (void) unregisterTask:(id ) task { +- (void) unregisterTask:(id) task { @synchronized (self) { - id taskID = [task taskIdentifier]; - id task = [_trackableTasks objectForKey:taskID]; // expected-warning{{method '-objectForKey:' not found (return type defaults to 'id')}} + id taskID = [task taskIdentifier]; // expected-warning {{method '-taskIdentifier' not found (return type defaults to 'id')}} } } @end + +struct x { int a; } b; + +void test1() { + @synchronized (b) { // expected-error {{@synchronized requires an Objective-C object type ('struct x' invalid)}} + } + + @synchronized (42) { // expected-error {{@synchronized requires an Objective-C object type ('int' invalid)}} + } +} diff --git a/test/SemaObjC/try-catch.m b/test/SemaObjC/try-catch.m index bcb4e506d5..076eff5429 100644 --- a/test/SemaObjC/try-catch.m +++ b/test/SemaObjC/try-catch.m @@ -40,8 +40,8 @@ typedef struct _NSZone NSZone; int foo() { struct s { int a, b; } agg, *pagg; - @throw 42; // expected-error {{invalid 'int' argument (expected an ObjC object type)}} - @throw agg; // expected-error {{invalid 'struct s' argument (expected an ObjC object type)}} - @throw pagg; // expected-error {{invalid 'struct s *' argument (expected an ObjC object type)}} + @throw 42; // expected-error {{@throw requires an Objective-C object type ('int' invalid))}} + @throw agg; // expected-error {{@throw requires an Objective-C object type ('struct s' invalid)}} + @throw pagg; // expected-error {{@throw requires an Objective-C object type ('struct s *' invalid)}} @throw; // expected-error {{@throw (rethrow) used outside of a @catch block}} } -- 2.40.0