From b5cf1ea6f410f72290b9c7767a63717a944c7a8f Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 19 Apr 2009 01:16:06 +0000 Subject: [PATCH] second half of indirect jump checking: make sure that any address taken labels are in function scope git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69499 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 3 ++ lib/Sema/SemaDecl.cpp | 42 ++++++++++++++++------ test/Sema/scope-check.c | 9 +++-- 3 files changed, 41 insertions(+), 13 deletions(-) diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 9b9b2a1d39..8ee940310b 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -836,6 +836,9 @@ def err_switch_into_protected_scope : Error< "illegal switch case into protected scope">; def err_indirect_goto_in_protected_scope : Error< "illegal indirect goto in protected scope, unknown effect on scopes">; +def err_addr_of_label_in_protected_scope : Error< + "address taken of label in protected scope, jump to it would have " + "unknown effect on scope">; def note_protected_by_vla_typedef : Note< "jump bypasses initialization of VLA typedef">; def note_protected_by_vla : Note< diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 2aaa1bc940..3a1217a839 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -2988,7 +2988,7 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned ParentScope) { if (isa(S) || isa(S) || isa(S)) { LabelAndGotoScopes[S] = ParentScope; } else if (isa(S) || isa(S) || - isa(S)) { + isa(S) || isa(S)) { // Remember both what scope a goto is in as well as the fact that we have // it. This makes the second scan not have to walk the AST again. LabelAndGotoScopes[S] = ParentScope; @@ -3082,19 +3082,41 @@ void JumpScopeChecker::VerifyJumps() { } + unsigned DiagnosticScope; + // We don't know where an indirect goto goes, require that it be at the // top level of scoping. - assert(isa(Jump)); - assert(LabelAndGotoScopes.count(Jump) &&"Jump didn't get added to scopes?"); - unsigned GotoScope = LabelAndGotoScopes[Jump]; - if (GotoScope == 0) continue; - S.Diag(Jump->getLocStart(), diag::err_indirect_goto_in_protected_scope); + if (IndirectGotoStmt *IG = dyn_cast(Jump)) { + assert(LabelAndGotoScopes.count(Jump) && + "Jump didn't get added to scopes?"); + unsigned GotoScope = LabelAndGotoScopes[IG]; + if (GotoScope == 0) continue; // indirect jump is ok. + S.Diag(IG->getGotoLoc(), diag::err_indirect_goto_in_protected_scope); + DiagnosticScope = GotoScope; + } else { + // We model &&Label as a jump for purposes of scope tracking. We actually + // don't care *where* the address of label is, but we require the *label + // itself* to be in scope 0. If it is nested inside of a VLA scope, then + // it is possible for an indirect goto to illegally enter the VLA scope by + // indirectly jumping to the label. + assert(isa(Jump) && "Unknown jump type"); + LabelStmt *TheLabel = cast(Jump)->getLabel(); + + assert(LabelAndGotoScopes.count(TheLabel) && + "Referenced label didn't get added to scopes?"); + unsigned LabelScope = LabelAndGotoScopes[TheLabel]; + if (LabelScope == 0) continue; // Addr of label is ok. - while (GotoScope != 0) { - S.Diag(Scopes[GotoScope].Loc, Scopes[GotoScope].Diag); - GotoScope = Scopes[GotoScope].ParentScope; + S.Diag(Jump->getLocStart(), diag::err_addr_of_label_in_protected_scope); + DiagnosticScope = LabelScope; + } + + // Report all the things that would be skipped over by this &&label or + // indirect goto. + while (DiagnosticScope != 0) { + S.Diag(Scopes[DiagnosticScope].Loc, Scopes[DiagnosticScope].Diag); + DiagnosticScope = Scopes[DiagnosticScope].ParentScope; } - continue; } } diff --git a/test/Sema/scope-check.c b/test/Sema/scope-check.c index 4605e02b88..83b84777a9 100644 --- a/test/Sema/scope-check.c +++ b/test/Sema/scope-check.c @@ -136,14 +136,17 @@ void test9(int n, void *P) { goto *P; // ok. L2: ; - int a[n]; // expected-note {{jump bypasses initialization of variable length array}} + int a[n]; // expected-note 2 {{jump bypasses initialization of variable length array}} L3: +L4: goto *P; // expected-error {{illegal indirect goto in protected scope, unknown effect on scopes}} + goto L3; // ok + goto L4; // ok void *Ptrs[] = { - &&L2, - &&L3 // FIXME: Not Ok. + &&L2, // Ok. + &&L3 // expected-error {{address taken of label in protected scope, jump to it would have unknown effect on scope}} }; } -- 2.40.0