зеркало из https://github.com/microsoft/clang-1.git
add support for goto checking and @synchronized blocks,
rdar://6810106 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69667 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
62f86c4555
Коммит
46c3c4ba78
|
@ -1410,10 +1410,12 @@ public:
|
||||||
ObjCAtSynchronizedStmt(SourceLocation atSynchronizedLoc, Stmt *synchExpr,
|
ObjCAtSynchronizedStmt(SourceLocation atSynchronizedLoc, Stmt *synchExpr,
|
||||||
Stmt *synchBody)
|
Stmt *synchBody)
|
||||||
: Stmt(ObjCAtSynchronizedStmtClass) {
|
: Stmt(ObjCAtSynchronizedStmtClass) {
|
||||||
SubStmts[SYNC_EXPR] = synchExpr;
|
SubStmts[SYNC_EXPR] = synchExpr;
|
||||||
SubStmts[SYNC_BODY] = synchBody;
|
SubStmts[SYNC_BODY] = synchBody;
|
||||||
AtSynchronizedLoc = atSynchronizedLoc;
|
AtSynchronizedLoc = atSynchronizedLoc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SourceLocation getAtSynchronizedLoc() const { return AtSynchronizedLoc; }
|
||||||
|
|
||||||
const CompoundStmt *getSynchBody() const {
|
const CompoundStmt *getSynchBody() const {
|
||||||
return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]);
|
return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]);
|
||||||
|
|
|
@ -868,6 +868,8 @@ def note_protected_by_objc_catch : Note<
|
||||||
"jump bypasses initialization of @catch block">;
|
"jump bypasses initialization of @catch block">;
|
||||||
def note_protected_by_objc_finally : Note<
|
def note_protected_by_objc_finally : Note<
|
||||||
"jump bypasses initialization of @finally block">;
|
"jump bypasses initialization of @finally block">;
|
||||||
|
def note_protected_by_objc_synchronized : Note<
|
||||||
|
"jump bypasses initialization of @synchronized block">;
|
||||||
|
|
||||||
def err_func_returning_array_function : Error<
|
def err_func_returning_array_function : Error<
|
||||||
"function cannot return array or function type %0">;
|
"function cannot return array or function type %0">;
|
||||||
|
|
|
@ -168,6 +168,22 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned ParentScope) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Disallow jumps into the protected statement of an @synchronized, but
|
||||||
|
// allow jumps into the object expression it protects.
|
||||||
|
if (ObjCAtSynchronizedStmt *AS = dyn_cast<ObjCAtSynchronizedStmt>(SubStmt)){
|
||||||
|
// Recursively walk the AST for the @synchronized object expr, it is
|
||||||
|
// evaluated in the normal scope.
|
||||||
|
BuildScopeInformation(AS->getSynchExpr(), ParentScope);
|
||||||
|
|
||||||
|
// Recursively walk the AST for the @synchronized part, protected by a new
|
||||||
|
// scope.
|
||||||
|
Scopes.push_back(GotoScope(ParentScope,
|
||||||
|
diag::note_protected_by_objc_synchronized,
|
||||||
|
AS->getAtSynchronizedLoc()));
|
||||||
|
BuildScopeInformation(AS->getSynchBody(), Scopes.size()-1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Recursively walk the AST.
|
// Recursively walk the AST.
|
||||||
BuildScopeInformation(SubStmt, ParentScope);
|
BuildScopeInformation(SubStmt, ParentScope);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1090,6 +1090,8 @@ Sema::ActOnObjCAtThrowStmt(SourceLocation AtLoc, ExprArg expr,Scope *CurScope) {
|
||||||
Action::OwningStmtResult
|
Action::OwningStmtResult
|
||||||
Sema::ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, ExprArg SynchExpr,
|
Sema::ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, ExprArg SynchExpr,
|
||||||
StmtArg SynchBody) {
|
StmtArg SynchBody) {
|
||||||
|
CurFunctionNeedsScopeChecking = true;
|
||||||
|
|
||||||
return Owned(new (Context) ObjCAtSynchronizedStmt(AtLoc,
|
return Owned(new (Context) ObjCAtSynchronizedStmt(AtLoc,
|
||||||
static_cast<Stmt*>(SynchExpr.release()),
|
static_cast<Stmt*>(SynchExpr.release()),
|
||||||
static_cast<Stmt*>(SynchBody.release())));
|
static_cast<Stmt*>(SynchBody.release())));
|
||||||
|
|
|
@ -44,6 +44,16 @@ L3: ;
|
||||||
} @catch (C *c) { // expected-note {{jump bypasses initialization of @catch block}}
|
} @catch (C *c) { // expected-note {{jump bypasses initialization of @catch block}}
|
||||||
L8: ;
|
L8: ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// rdar://6810106
|
||||||
|
id X;
|
||||||
|
goto L9; // expected-error{{illegal goto into protected scope}}
|
||||||
|
goto L10; // ok
|
||||||
|
@synchronized // expected-note {{jump bypasses initialization of @synchronized block}}
|
||||||
|
( ({ L10: ; X; })) {
|
||||||
|
L9:
|
||||||
|
;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void test2(int a) {
|
void test2(int a) {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче