зеркало из https://github.com/microsoft/clang-1.git
Implement -Wunused-label.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@114315 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
d2827af6f9
Коммит
355a9fe26a
|
@ -561,10 +561,11 @@ class LabelStmt : public Stmt {
|
|||
IdentifierInfo *Label;
|
||||
Stmt *SubStmt;
|
||||
SourceLocation IdentLoc;
|
||||
bool Used : 1;
|
||||
public:
|
||||
LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt)
|
||||
: Stmt(LabelStmtClass), Label(label),
|
||||
SubStmt(substmt), IdentLoc(IL) {}
|
||||
SubStmt(substmt), IdentLoc(IL), Used(false) {}
|
||||
|
||||
// \brief Build an empty label statement.
|
||||
explicit LabelStmt(EmptyShell Empty) : Stmt(LabelStmtClass, Empty) { }
|
||||
|
@ -578,6 +579,11 @@ public:
|
|||
void setIdentLoc(SourceLocation L) { IdentLoc = L; }
|
||||
void setSubStmt(Stmt *SS) { SubStmt = SS; }
|
||||
|
||||
/// \brief Whether this label was used.
|
||||
/// FIXME: Check "used" attribute (requires storing label attributes).
|
||||
bool isUsed() const { return Used; }
|
||||
void setUsed(bool U = true) { Used = U; }
|
||||
|
||||
virtual SourceRange getSourceRange() const {
|
||||
return SourceRange(IdentLoc, SubStmt->getLocEnd());
|
||||
}
|
||||
|
|
|
@ -1899,6 +1899,8 @@ def warn_missing_braces : Warning<
|
|||
|
||||
def err_redefinition_of_label : Error<"redefinition of label '%0'">;
|
||||
def err_undeclared_label_use : Error<"use of undeclared label '%0'">;
|
||||
def warn_unused_label : Warning<"unused label '%0'">,
|
||||
InGroup<UnusedLabel>, DefaultIgnore;
|
||||
|
||||
def err_goto_into_protected_scope : Error<"goto into protected scope">;
|
||||
def err_switch_into_protected_scope : Error<
|
||||
|
|
|
@ -5028,8 +5028,11 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
|
|||
// Verify that we have no forward references left. If so, there was a goto
|
||||
// or address of a label taken, but no definition of it. Label fwd
|
||||
// definitions are indicated with a null substmt.
|
||||
if (L->getSubStmt() != 0)
|
||||
if (L->getSubStmt() != 0) {
|
||||
if (!L->isUsed())
|
||||
Diag(L->getIdentLoc(), diag::warn_unused_label) << L->getName();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Emit error.
|
||||
Diag(L->getIdentLoc(), diag::err_undeclared_label_use) << L->getName();
|
||||
|
|
|
@ -6871,6 +6871,7 @@ ExprResult Sema::ActOnAddrLabel(SourceLocation OpLoc,
|
|||
if (LabelDecl == 0)
|
||||
LabelDecl = new (Context) LabelStmt(LabLoc, LabelII, 0);
|
||||
|
||||
LabelDecl->setUsed();
|
||||
// Create the AST node. The address of a label always has type 'void*'.
|
||||
return Owned(new (Context) AddrLabelExpr(OpLoc, LabLoc, LabelDecl,
|
||||
Context.getPointerType(Context.VoidTy)));
|
||||
|
@ -7355,8 +7356,11 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
|
|||
|
||||
// Verify that we have no forward references left. If so, there was a goto
|
||||
// or address of a label taken, but no definition of it.
|
||||
if (L->getSubStmt() != 0)
|
||||
if (L->getSubStmt() != 0) {
|
||||
if (!L->isUsed())
|
||||
Diag(L->getIdentLoc(), diag::warn_unused_label) << L->getName();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Emit error.
|
||||
Diag(L->getIdentLoc(), diag::err_undeclared_label_use) << L->getName();
|
||||
|
|
|
@ -994,6 +994,7 @@ Sema::ActOnGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
|
|||
if (LabelDecl == 0)
|
||||
LabelDecl = new (Context) LabelStmt(LabelLoc, LabelII, 0);
|
||||
|
||||
LabelDecl->setUsed();
|
||||
return Owned(new (Context) GotoStmt(LabelDecl, GotoLoc, LabelLoc));
|
||||
}
|
||||
|
||||
|
|
|
@ -219,6 +219,7 @@ void ASTStmtReader::VisitLabelStmt(LabelStmt *S) {
|
|||
S->setID(Reader.GetIdentifierInfo(Record, Idx));
|
||||
S->setSubStmt(Reader.ReadSubStmt());
|
||||
S->setIdentLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
|
||||
S->setUsed(Record[Idx++]);
|
||||
Reader.RecordLabelStmt(S, Record[Idx++]);
|
||||
}
|
||||
|
||||
|
|
|
@ -213,6 +213,7 @@ void ASTStmtWriter::VisitLabelStmt(LabelStmt *S) {
|
|||
Writer.AddIdentifierRef(S->getID(), Record);
|
||||
Writer.AddStmt(S->getSubStmt());
|
||||
Writer.AddSourceLocation(S->getIdentLoc(), Record);
|
||||
Record.push_back(S->isUsed());
|
||||
Record.push_back(Writer.GetLabelID(S));
|
||||
Code = serialization::STMT_LABEL;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -Wunused-label -verify %s
|
||||
|
||||
void f() {
|
||||
a:
|
||||
goto a;
|
||||
b: // expected-warning{{unused}}
|
||||
return;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify -Wunused-value %s
|
||||
// RUN: %clang_cc1 -fsyntax-only -verify -Wunused-value -Wunused-label %s
|
||||
// RUN: %clang_cc1 -fsyntax-only -verify -Wunused %s
|
||||
// RUN: %clang_cc1 -fsyntax-only -verify -Wall %s
|
||||
|
||||
|
@ -53,7 +53,7 @@ void pr4806() {
|
|||
*pi; // expected-warning {{expression result unused}}
|
||||
*pj;
|
||||
|
||||
foo_label:
|
||||
foo_label: // expected-warning {{unused label}}
|
||||
i; // expected-warning {{expression result unused}}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче