mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-27 12:56:08 +00:00
Labels (and case statement) don't create independent scope parents for the
purposes of the jump checker. Also extend Ted's iteration fix to labels. Fixes PR7789. llvm-svn: 110082
This commit is contained in:
parent
460a356bf6
commit
4a33fa95c0
@ -1855,9 +1855,9 @@ def warn_missing_braces : Warning<
|
|||||||
def err_redefinition_of_label : Error<"redefinition of label '%0'">;
|
def err_redefinition_of_label : Error<"redefinition of label '%0'">;
|
||||||
def err_undeclared_label_use : Error<"use of undeclared label '%0'">;
|
def err_undeclared_label_use : Error<"use of undeclared label '%0'">;
|
||||||
|
|
||||||
def err_goto_into_protected_scope : Error<"illegal goto into protected scope">;
|
def err_goto_into_protected_scope : Error<"goto into protected scope">;
|
||||||
def err_switch_into_protected_scope : Error<
|
def err_switch_into_protected_scope : Error<
|
||||||
"illegal switch case into protected scope">;
|
"switch case is in protected scope">;
|
||||||
def err_indirect_goto_without_addrlabel : Error<
|
def err_indirect_goto_without_addrlabel : Error<
|
||||||
"indirect goto in function with no address-of-label expressions">;
|
"indirect goto in function with no address-of-label expressions">;
|
||||||
def warn_indirect_goto_in_protected_scope : Warning<
|
def warn_indirect_goto_in_protected_scope : Warning<
|
||||||
|
@ -180,22 +180,6 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned ParentScope) {
|
|||||||
|
|
||||||
// If we found a label, remember that it is in ParentScope scope.
|
// If we found a label, remember that it is in ParentScope scope.
|
||||||
switch (S->getStmtClass()) {
|
switch (S->getStmtClass()) {
|
||||||
case Stmt::LabelStmtClass:
|
|
||||||
case Stmt::DefaultStmtClass:
|
|
||||||
LabelAndGotoScopes[S] = ParentScope;
|
|
||||||
break;
|
|
||||||
case Stmt::CaseStmtClass: {
|
|
||||||
// Specially handle CaseStmts since they can nest each other in the
|
|
||||||
// AST and blow out the stack when we walk them.
|
|
||||||
CaseStmt *CS = cast<CaseStmt>(S);
|
|
||||||
do {
|
|
||||||
LabelAndGotoScopes[CS] = ParentScope;
|
|
||||||
S = CS; // 'CS' is the new current statement (if it isn't already).
|
|
||||||
CS = dyn_cast<CaseStmt>(CS->getSubStmt());
|
|
||||||
} while (CS);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Stmt::AddrLabelExprClass:
|
case Stmt::AddrLabelExprClass:
|
||||||
IndirectJumpTargets.push_back(cast<AddrLabelExpr>(S)->getLabel());
|
IndirectJumpTargets.push_back(cast<AddrLabelExpr>(S)->getLabel());
|
||||||
break;
|
break;
|
||||||
@ -235,6 +219,24 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned ParentScope) {
|
|||||||
Stmt *SubStmt = *CI;
|
Stmt *SubStmt = *CI;
|
||||||
if (SubStmt == 0) continue;
|
if (SubStmt == 0) continue;
|
||||||
|
|
||||||
|
// Cases, labels, and defaults aren't "scope parents". It's also
|
||||||
|
// important to handle these iteratively instead of recursively in
|
||||||
|
// order to avoid blowing out the stack.
|
||||||
|
while (true) {
|
||||||
|
Stmt *Next;
|
||||||
|
if (isa<CaseStmt>(SubStmt))
|
||||||
|
Next = cast<CaseStmt>(SubStmt)->getSubStmt();
|
||||||
|
else if (isa<DefaultStmt>(SubStmt))
|
||||||
|
Next = cast<DefaultStmt>(SubStmt)->getSubStmt();
|
||||||
|
else if (isa<LabelStmt>(SubStmt))
|
||||||
|
Next = cast<LabelStmt>(SubStmt)->getSubStmt();
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
|
||||||
|
LabelAndGotoScopes[SubStmt] = ParentScope;
|
||||||
|
SubStmt = Next;
|
||||||
|
}
|
||||||
|
|
||||||
// If this is a declstmt with a VLA definition, it defines a scope from here
|
// If this is a declstmt with a VLA definition, it defines a scope from here
|
||||||
// to the end of the containing context.
|
// to the end of the containing context.
|
||||||
if (DeclStmt *DS = dyn_cast<DeclStmt>(SubStmt)) {
|
if (DeclStmt *DS = dyn_cast<DeclStmt>(SubStmt)) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=gnu99 %s -Wno-unreachable-code
|
// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=gnu99 %s -Wno-unreachable-code
|
||||||
|
|
||||||
int test1(int x) {
|
int test1(int x) {
|
||||||
goto L; // expected-error{{illegal goto into protected scope}}
|
goto L; // expected-error{{goto into protected scope}}
|
||||||
int a[x]; // expected-note {{jump bypasses initialization of variable length array}}
|
int a[x]; // expected-note {{jump bypasses initialization of variable length array}}
|
||||||
int b[x]; // expected-note {{jump bypasses initialization of variable length array}}
|
int b[x]; // expected-note {{jump bypasses initialization of variable length array}}
|
||||||
L:
|
L:
|
||||||
@ -9,7 +9,7 @@ int test1(int x) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int test2(int x) {
|
int test2(int x) {
|
||||||
goto L; // expected-error{{illegal goto into protected scope}}
|
goto L; // expected-error{{goto into protected scope}}
|
||||||
typedef int a[x]; // expected-note {{jump bypasses initialization of VLA typedef}}
|
typedef int a[x]; // expected-note {{jump bypasses initialization of VLA typedef}}
|
||||||
L:
|
L:
|
||||||
return sizeof(a);
|
return sizeof(a);
|
||||||
@ -18,14 +18,14 @@ int test2(int x) {
|
|||||||
void test3clean(int*);
|
void test3clean(int*);
|
||||||
|
|
||||||
int test3() {
|
int test3() {
|
||||||
goto L; // expected-error{{illegal goto into protected scope}}
|
goto L; // expected-error{{goto into protected scope}}
|
||||||
int a __attribute((cleanup(test3clean))); // expected-note {{jump bypasses initialization of variable with __attribute__((cleanup))}}
|
int a __attribute((cleanup(test3clean))); // expected-note {{jump bypasses initialization of variable with __attribute__((cleanup))}}
|
||||||
L:
|
L:
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
int test4(int x) {
|
int test4(int x) {
|
||||||
goto L; // expected-error{{illegal goto into protected scope}}
|
goto L; // expected-error{{goto into protected scope}}
|
||||||
int a[x]; // expected-note {{jump bypasses initialization of variable length array}}
|
int a[x]; // expected-note {{jump bypasses initialization of variable length array}}
|
||||||
test4(x);
|
test4(x);
|
||||||
L:
|
L:
|
||||||
@ -50,7 +50,7 @@ void test7(int x) {
|
|||||||
switch (x) {
|
switch (x) {
|
||||||
case 1: ;
|
case 1: ;
|
||||||
int a[x]; // expected-note {{jump bypasses initialization of variable length array}}
|
int a[x]; // expected-note {{jump bypasses initialization of variable length array}}
|
||||||
case 2: // expected-error {{illegal switch case into protected scope}}
|
case 2: // expected-error {{switch case is in protected scope}}
|
||||||
a[1] = 2;
|
a[1] = 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -58,17 +58,17 @@ void test7(int x) {
|
|||||||
|
|
||||||
int test8(int x) {
|
int test8(int x) {
|
||||||
// For statement.
|
// For statement.
|
||||||
goto L2; // expected-error {{illegal goto into protected scope}}
|
goto L2; // expected-error {{goto into protected scope}}
|
||||||
for (int arr[x]; // expected-note {{jump bypasses initialization of variable length array}}
|
for (int arr[x]; // expected-note {{jump bypasses initialization of variable length array}}
|
||||||
; ++x)
|
; ++x)
|
||||||
L2:;
|
L2:;
|
||||||
|
|
||||||
// Statement expressions.
|
// Statement expressions.
|
||||||
goto L3; // expected-error {{illegal goto into protected scope}}
|
goto L3; // expected-error {{goto into protected scope}}
|
||||||
int Y = ({ int a[x]; // expected-note {{jump bypasses initialization of variable length array}}
|
int Y = ({ int a[x]; // expected-note {{jump bypasses initialization of variable length array}}
|
||||||
L3: 4; });
|
L3: 4; });
|
||||||
|
|
||||||
goto L4; // expected-error {{illegal goto into protected scope}}
|
goto L4; // expected-error {{goto into protected scope}}
|
||||||
{
|
{
|
||||||
int A[x], // expected-note {{jump bypasses initialization of variable length array}}
|
int A[x], // expected-note {{jump bypasses initialization of variable length array}}
|
||||||
B[x]; // expected-note {{jump bypasses initialization of variable length array}}
|
B[x]; // expected-note {{jump bypasses initialization of variable length array}}
|
||||||
@ -91,7 +91,7 @@ int test8(int x) {
|
|||||||
int A[x], B = ({ if (x)
|
int A[x], B = ({ if (x)
|
||||||
goto L7;
|
goto L7;
|
||||||
else
|
else
|
||||||
goto L8; // expected-error {{illegal goto into protected scope}}
|
goto L8; // expected-error {{goto into protected scope}}
|
||||||
4; }),
|
4; }),
|
||||||
C[x]; // expected-note {{jump bypasses initialization of variable length array}}
|
C[x]; // expected-note {{jump bypasses initialization of variable length array}}
|
||||||
L8:; // bad
|
L8:; // bad
|
||||||
@ -103,7 +103,7 @@ int test8(int x) {
|
|||||||
goto L9;
|
goto L9;
|
||||||
else
|
else
|
||||||
// FIXME:
|
// FIXME:
|
||||||
goto L10; // fixme-error {{illegal goto into protected scope}}
|
goto L10; // fixme-error {{goto into protected scope}}
|
||||||
4; })];
|
4; })];
|
||||||
L10:; // bad
|
L10:; // bad
|
||||||
}
|
}
|
||||||
@ -123,7 +123,7 @@ int test8(int x) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Statement expressions 2.
|
// Statement expressions 2.
|
||||||
goto L1; // expected-error {{illegal goto into protected scope}}
|
goto L1; // expected-error {{goto into protected scope}}
|
||||||
return x == ({
|
return x == ({
|
||||||
int a[x]; // expected-note {{jump bypasses initialization of variable length array}}
|
int a[x]; // expected-note {{jump bypasses initialization of variable length array}}
|
||||||
L1:
|
L1:
|
||||||
@ -151,14 +151,14 @@ L4:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void test10(int n, void *P) {
|
void test10(int n, void *P) {
|
||||||
goto L0; // expected-error {{illegal goto into protected scope}}
|
goto L0; // expected-error {{goto into protected scope}}
|
||||||
typedef int A[n]; // expected-note {{jump bypasses initialization of VLA typedef}}
|
typedef int A[n]; // expected-note {{jump bypasses initialization of VLA typedef}}
|
||||||
L0:
|
L0:
|
||||||
|
|
||||||
goto L1; // expected-error {{illegal goto into protected scope}}
|
goto L1; // expected-error {{goto into protected scope}}
|
||||||
A b, c[10]; // expected-note 2 {{jump bypasses initialization of variable length array}}
|
A b, c[10]; // expected-note 2 {{jump bypasses initialization of variable length array}}
|
||||||
L1:
|
L1:
|
||||||
goto L2; // expected-error {{illegal goto into protected scope}}
|
goto L2; // expected-error {{goto into protected scope}}
|
||||||
A d[n]; // expected-note {{jump bypasses initialization of variable length array}}
|
A d[n]; // expected-note {{jump bypasses initialization of variable length array}}
|
||||||
L2:
|
L2:
|
||||||
return;
|
return;
|
||||||
@ -171,7 +171,7 @@ void test11(int n) {
|
|||||||
case 2:
|
case 2:
|
||||||
case 3:;
|
case 3:;
|
||||||
int Arr[n]; // expected-note {{jump bypasses initialization of variable length array}}
|
int Arr[n]; // expected-note {{jump bypasses initialization of variable length array}}
|
||||||
case 4: // expected-error {{illegal switch case into protected scope}}
|
case 4: // expected-error {{switch case is in protected scope}}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -185,7 +185,7 @@ void test12(int n) {
|
|||||||
L1:
|
L1:
|
||||||
goto L2;
|
goto L2;
|
||||||
L2:
|
L2:
|
||||||
goto L3; // expected-error {{illegal goto into protected scope}}
|
goto L3; // expected-error {{goto into protected scope}}
|
||||||
int Arr[n]; // expected-note {{jump bypasses initialization of variable length array}}
|
int Arr[n]; // expected-note {{jump bypasses initialization of variable length array}}
|
||||||
L3:
|
L3:
|
||||||
goto L4;
|
goto L4;
|
||||||
|
@ -133,3 +133,21 @@ namespace test7 {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PR7789
|
||||||
|
namespace test8 {
|
||||||
|
void test1(int c) {
|
||||||
|
switch (c) {
|
||||||
|
case 0:
|
||||||
|
int x = 56; // expected-note {{jump bypasses variable initialization}}
|
||||||
|
case 1: // expected-error {{switch case is in protected scope}}
|
||||||
|
x = 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test2() {
|
||||||
|
goto l2; // expected-error {{goto into protected scope}}
|
||||||
|
l1: int x = 5; // expected-note {{jump bypasses variable initialization}}
|
||||||
|
l2: x++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user