зеркало из https://github.com/microsoft/clang-1.git
correctly verify that default and case are in a switchstmt,
this fixes test/Sema/switch.c. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@40438 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
f063721c4b
Коммит
8a87e57beb
|
@ -55,7 +55,7 @@ Sema::ParseCaseStmt(SourceLocation CaseLoc, ExprTy *lhsval,
|
|||
SourceLocation DotDotDotLoc, ExprTy *rhsval,
|
||||
SourceLocation ColonLoc, StmtTy *subStmt) {
|
||||
Stmt *SubStmt = static_cast<Stmt*>(subStmt);
|
||||
Expr *LHSVal = ((Expr *)lhsval);
|
||||
Expr *LHSVal = ((Expr *)lhsval), *RHSVal = ((Expr *)rhsval);
|
||||
assert((LHSVal != 0) && "missing expression in case statement");
|
||||
|
||||
SourceLocation ExpLoc;
|
||||
|
@ -67,19 +67,19 @@ Sema::ParseCaseStmt(SourceLocation CaseLoc, ExprTy *lhsval,
|
|||
}
|
||||
|
||||
// GCC extension: The expression shall be an integer constant.
|
||||
Expr *RHSVal = ((Expr *)rhsval);
|
||||
if (RHSVal && !RHSVal->isIntegerConstantExpr(Context, &ExpLoc)) {
|
||||
Diag(ExpLoc, diag::err_case_label_not_integer_constant_expr,
|
||||
RHSVal->getSourceRange());
|
||||
return SubStmt;
|
||||
}
|
||||
|
||||
if (SwitchStack.empty()) {
|
||||
Diag(CaseLoc, diag::err_case_not_in_switch);
|
||||
return SubStmt;
|
||||
}
|
||||
|
||||
CaseStmt *CS = new CaseStmt(LHSVal, RHSVal, SubStmt);
|
||||
|
||||
assert(!SwitchStack.empty() && "missing push/pop in switch stack!");
|
||||
SwitchStmt *SS = SwitchStack.back();
|
||||
SS->addSwitchCase(CS);
|
||||
|
||||
SwitchStack.back()->addSwitchCase(CS);
|
||||
return CS;
|
||||
}
|
||||
|
||||
|
@ -87,18 +87,14 @@ Action::StmtResult
|
|||
Sema::ParseDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc,
|
||||
StmtTy *subStmt, Scope *CurScope) {
|
||||
Stmt *SubStmt = static_cast<Stmt*>(subStmt);
|
||||
Scope *S = CurScope->getBreakParent();
|
||||
|
||||
if (!S) {
|
||||
if (SwitchStack.empty()) {
|
||||
Diag(DefaultLoc, diag::err_default_not_in_switch);
|
||||
return SubStmt;
|
||||
}
|
||||
|
||||
DefaultStmt *DS = new DefaultStmt(DefaultLoc, SubStmt);
|
||||
|
||||
assert(!SwitchStack.empty() && "missing push/pop in switch stack!");
|
||||
SwitchStmt *SS = SwitchStack.back();
|
||||
SS->addSwitchCase(DS);
|
||||
SwitchStack.back()->addSwitchCase(DS);
|
||||
|
||||
return DS;
|
||||
}
|
||||
|
|
|
@ -655,6 +655,8 @@ DIAG(err_break_not_in_loop_or_switch, ERROR,
|
|||
"'break' statement not in loop or switch statement")
|
||||
DIAG(err_default_not_in_switch, ERROR,
|
||||
"'default' statement not in switch statement")
|
||||
DIAG(err_case_not_in_switch, ERROR,
|
||||
"'case' statement not in switch statement")
|
||||
DIAG(err_typecheck_return_incompatible, ERROR,
|
||||
"incompatible type returning '%1', expected '%0'")
|
||||
DIAG(ext_typecheck_return_pointer_int, EXTENSION,
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
// RUN: clang -parse-ast-check %s
|
||||
|
||||
|
||||
void f (int z) {
|
||||
while (z) {
|
||||
default: z--; // expected-error {{statement not in switch}}
|
||||
}
|
||||
}
|
||||
|
Загрузка…
Ссылка в новой задаче