From 355a9fe26a6dec89680ddf713dd5bc7a671b298a Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Sun, 19 Sep 2010 21:21:25 +0000 Subject: [PATCH] Implement -Wunused-label. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@114315 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/Stmt.h | 8 +++++++- include/clang/Basic/DiagnosticSemaKinds.td | 2 ++ lib/Sema/SemaDecl.cpp | 5 ++++- lib/Sema/SemaExpr.cpp | 6 +++++- lib/Sema/SemaStmt.cpp | 1 + lib/Serialization/ASTReaderStmt.cpp | 1 + lib/Serialization/ASTWriterStmt.cpp | 1 + test/Sema/warn-unused-label.c | 8 ++++++++ test/Sema/warn-unused-value.c | 4 ++-- 9 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 test/Sema/warn-unused-label.c diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index 856a14c51a..0bb257b2e0 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -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()); } diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index b0dcf320d5..9508c913ec 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -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, DefaultIgnore; def err_goto_into_protected_scope : Error<"goto into protected scope">; def err_switch_into_protected_scope : Error< diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 51b5ae91d6..0b3e60f82a 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -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(); diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 4bd596b672..4000984448 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -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(); diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 47ea4f2c25..24489544e0 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -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)); } diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp index 6e8ad4fc44..7b0845d5e7 100644 --- a/lib/Serialization/ASTReaderStmt.cpp +++ b/lib/Serialization/ASTReaderStmt.cpp @@ -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++]); } diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp index 7a5b9497a8..edd8002d47 100644 --- a/lib/Serialization/ASTWriterStmt.cpp +++ b/lib/Serialization/ASTWriterStmt.cpp @@ -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; } diff --git a/test/Sema/warn-unused-label.c b/test/Sema/warn-unused-label.c new file mode 100644 index 0000000000..b5979be264 --- /dev/null +++ b/test/Sema/warn-unused-label.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -fsyntax-only -Wunused-label -verify %s + +void f() { + a: + goto a; + b: // expected-warning{{unused}} + return; +} diff --git a/test/Sema/warn-unused-value.c b/test/Sema/warn-unused-value.c index 7c36b6983e..876eb9e482 100644 --- a/test/Sema/warn-unused-value.c +++ b/test/Sema/warn-unused-value.c @@ -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}} }