Switch labels over to using normal name lookup, instead of their
own weird little DenseMap. Hey look, we now emit unused label
warnings deterministically, amazing.
llvm-svn: 125813
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 98555d9..95ab5fa 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -674,6 +674,8 @@
return true;
}
+/// DiagnoseUnusedDecl - Emit warnings about declarations that are not used
+/// unless they are marked attr(unused).
void Sema::DiagnoseUnusedDecl(const NamedDecl *D) {
if (!ShouldDiagnoseUnusedDecl(D))
return;
@@ -689,6 +691,14 @@
Diag(D->getLocation(), DiagID) << D->getDeclName();
}
+static void CheckPoppedLabel(LabelDecl *L, Sema &S) {
+ // 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->getStmt() == 0)
+ S.Diag(L->getLocation(), diag::err_undeclared_label_use) <<L->getDeclName();
+}
+
void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
if (S->decl_empty()) return;
assert((S->getFlags() & (Scope::DeclScope | Scope::TemplateParamScope)) &&
@@ -708,6 +718,10 @@
if (!S->hasErrorOccurred())
DiagnoseUnusedDecl(D);
+ // If this was a forward reference to a label, verify it was defined.
+ if (LabelDecl *LD = dyn_cast<LabelDecl>(D))
+ CheckPoppedLabel(LD, *this);
+
// Remove this name from our lexical scope.
IdResolver.RemoveDecl(D);
}
@@ -5480,11 +5494,6 @@
}
// Verify and clean out per-function state.
-
- // Check goto/label use.
- FunctionScopeInfo *CurFn = getCurFunction();
- CurFn->checkLabelUse(Body, *this);
-
if (Body) {
// C++ constructors that have function-try-blocks can't have return
// statements in the handlers of that block. (C++ [except.handle]p14)