second half of indirect jump checking: make sure that any
address taken labels are in function scope llvm-svn: 69499
This commit is contained in:
parent
0bf2dd2ed4
commit
c67540501f
|
@ -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<
|
||||
|
|
|
@ -2988,7 +2988,7 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned ParentScope) {
|
|||
if (isa<LabelStmt>(S) || isa<DefaultStmt>(S) || isa<CaseStmt>(S)) {
|
||||
LabelAndGotoScopes[S] = ParentScope;
|
||||
} else if (isa<GotoStmt>(S) || isa<SwitchStmt>(S) ||
|
||||
isa<IndirectGotoStmt>(S)) {
|
||||
isa<IndirectGotoStmt>(S) || isa<AddrLabelExpr>(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<IndirectGotoStmt>(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<IndirectGotoStmt>(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<AddrLabelExpr>(Jump) && "Unknown jump type");
|
||||
LabelStmt *TheLabel = cast<AddrLabelExpr>(Jump)->getLabel();
|
||||
|
||||
while (GotoScope != 0) {
|
||||
S.Diag(Scopes[GotoScope].Loc, Scopes[GotoScope].Diag);
|
||||
GotoScope = Scopes[GotoScope].ParentScope;
|
||||
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.
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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}}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue