[cfe-commits] r39509 - in /cfe/cfe/trunk: AST/StmtPrinter.cpp Sema/Sema.h Sema/SemaDecl.cpp Sema/SemaStmt.cpp include/clang/AST/Stmt.h include/clang/Basic/DiagnosticKinds.def
clattner at cs.uiuc.edu
clattner at cs.uiuc.edu
Wed Jul 11 09:45:07 PDT 2007
Author: clattner
Date: Wed Jul 11 11:45:07 2007
New Revision: 39509
URL: http://llvm.org/viewvc/llvm-project?rev=39509&view=rev
Log:
Change GotoStmt's to have a pointer to the LabelStmt instead of a pointer to
the label identifier. Handle fwd references etc. This allows us to detect
uses of undefined labels and label redefinitions, such as:
t.c:2:12: error: redefinition of label 'abc'
abc: ; abc:
^
t.c:2:3: error: previous definition is here
abc: ; abc:
^
t.c:12:12: error: use of undeclared label 'hijl'
goto hijl;
^
Modified:
cfe/cfe/trunk/AST/StmtPrinter.cpp
cfe/cfe/trunk/Sema/Sema.h
cfe/cfe/trunk/Sema/SemaDecl.cpp
cfe/cfe/trunk/Sema/SemaStmt.cpp
cfe/cfe/trunk/include/clang/AST/Stmt.h
cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
Modified: cfe/cfe/trunk/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/StmtPrinter.cpp?rev=39509&r1=39508&r2=39509&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/StmtPrinter.cpp (original)
+++ cfe/cfe/trunk/AST/StmtPrinter.cpp Wed Jul 11 11:45:07 2007
@@ -211,7 +211,7 @@
}
void StmtPrinter::VisitGotoStmt(GotoStmt *Node) {
- Indent() << "goto " << Node->getLabel()->getName() << "\n";
+ Indent() << "goto " << Node->getLabel()->getLabel()->getName() << ";\n";
}
void StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) {
Modified: cfe/cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/Sema.h?rev=39509&r1=39508&r2=39509&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/Sema.h (original)
+++ cfe/cfe/trunk/Sema/Sema.h Wed Jul 11 11:45:07 2007
@@ -16,6 +16,7 @@
#define LLVM_CLANG_AST_SEMA_H
#include "clang/Parse/Action.h"
+#include "llvm/ADT/DenseMap.h"
#include <vector>
#include <string>
@@ -34,6 +35,7 @@
class LexerToken;
class IntegerLiteral;
class ArrayType;
+ class LabelStmt;
/// Sema - This implements semantic analysis and AST building for C.
class Sema : public Action {
@@ -50,6 +52,11 @@
/// all but the last decl will be entered into this. This is used by the
/// ASTStreamer.
std::vector<Decl*> &LastInGroupList;
+
+ /// LabelMap - This is a mapping from label identifiers to the LabelStmt for
+ /// it (which acts like the label decl in some ways). Forward referenced
+ /// labels have a LabelStmt created for them with a null location & SubStmt.
+ DenseMap<IdentifierInfo*, LabelStmt*> LabelMap;
public:
Sema(Preprocessor &pp, ASTContext &ctxt, std::vector<Decl*> &prevInGroup);
Modified: cfe/cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaDecl.cpp?rev=39509&r1=39508&r2=39509&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaDecl.cpp Wed Jul 11 11:45:07 2007
@@ -472,6 +472,30 @@
assert(FD == CurFunctionDecl && "Function parsing confused");
CurFunctionDecl = 0;
+
+ // Verify and clean out per-function state.
+
+ // Check goto/label use.
+ for (DenseMap<IdentifierInfo*, LabelStmt*>::iterator I = LabelMap.begin(),
+ E = LabelMap.end(); I != E; ++I) {
+ // 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 (I->second->getSubStmt() == 0) {
+ LabelStmt *L = I->second;
+ // Emit error.
+ Diag(L->getIdentLoc(), diag::err_undeclared_label_use,
+ L->getLabel()->getName());
+
+ // At this point, we have gotos that use the bogus label. Stitch it into
+ // the function body so that they aren't leaked and that the AST is well
+ // formed.
+ L->setSubStmt(new NullStmt(L->getIdentLoc()));
+ cast<CompoundStmt>((Stmt*)Body)->push_back(L);
+ }
+ }
+ LabelMap.clear();
+
return FD;
}
Modified: cfe/cfe/trunk/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaStmt.cpp?rev=39509&r1=39508&r2=39509&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/SemaStmt.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaStmt.cpp Wed Jul 11 11:45:07 2007
@@ -15,6 +15,7 @@
#include "clang/AST/Stmt.h"
#include "clang/AST/Expr.h"
#include "clang/Parse/Scope.h"
+#include "clang/Lex/IdentifierTable.h"
#include "clang/Basic/Diagnostic.h"
using namespace llvm;
using namespace clang;
@@ -53,7 +54,28 @@
Action::StmtResult
Sema::ParseLabelStmt(SourceLocation IdentLoc, IdentifierInfo *II,
SourceLocation ColonLoc, StmtTy *SubStmt) {
- return new LabelStmt(II, (Stmt*)SubStmt);
+ // Look up the record for this label identifier.
+ LabelStmt *&LabelDecl = LabelMap[II];
+
+ // If not forward referenced or defined already, just create a new LabelStmt.
+ if (LabelDecl == 0)
+ return LabelDecl = new LabelStmt(IdentLoc, II, (Stmt*)SubStmt);
+
+ assert(LabelDecl->getLabel() == II && "Label mismatch!");
+
+ // Otherwise, this label was either forward reference or multiply defined. If
+ // multiply defined, reject it now.
+ if (LabelDecl->getSubStmt()) {
+ Diag(IdentLoc, diag::err_redefinition_of_label, II->getName());
+ Diag(LabelDecl->getIdentLoc(), diag::err_previous_definition);
+ return (Stmt*)SubStmt;
+ }
+
+ // Otherwise, this label was forward declared, and we just found its real
+ // definition. Fill in the forward definition and return it.
+ LabelDecl->setIdentLoc(IdentLoc);
+ LabelDecl->setSubStmt((Stmt*)SubStmt);
+ return LabelDecl;
}
Action::StmtResult
@@ -89,7 +111,14 @@
Action::StmtResult
Sema::ParseGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
IdentifierInfo *LabelII) {
- return new GotoStmt(LabelII);
+ // Look up the record for this label identifier.
+ LabelStmt *&LabelDecl = LabelMap[LabelII];
+
+ // If we haven't seen this label yet, create a forward reference.
+ if (LabelDecl == 0)
+ LabelDecl = new LabelStmt(LabelLoc, LabelII, 0);
+
+ return new GotoStmt(LabelDecl);
}
Action::StmtResult
Sema::ParseIndirectGotoStmt(SourceLocation GotoLoc,SourceLocation StarLoc,
Modified: cfe/cfe/trunk/include/clang/AST/Stmt.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/AST/Stmt.h?rev=39509&r1=39508&r2=39509&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Stmt.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Stmt.h Wed Jul 11 11:45:07 2007
@@ -90,6 +90,8 @@
body_iterator body_begin() { return Body.begin(); }
body_iterator body_end() { return Body.end(); }
+ void push_back(Stmt *S) { Body.push_back(S); }
+
virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) {
return T->getStmtClass() == CompoundStmtClass;
@@ -131,15 +133,20 @@
};
class LabelStmt : public Stmt {
+ SourceLocation IdentLoc;
IdentifierInfo *Label;
Stmt *SubStmt;
public:
- LabelStmt(IdentifierInfo *label, Stmt *substmt)
- : Stmt(LabelStmtClass), Label(label), SubStmt(substmt) {}
+ LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt)
+ : Stmt(LabelStmtClass), IdentLoc(IL), Label(label), SubStmt(substmt) {}
+ SourceLocation getIdentLoc() const { return IdentLoc; }
IdentifierInfo *getLabel() { return Label; }
Stmt *getSubStmt() { return SubStmt; }
+ void setIdentLoc(SourceLocation L) { IdentLoc = L; }
+ void setSubStmt(Stmt *SS) { SubStmt = SS; }
+
virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) {
return T->getStmtClass() == LabelStmtClass;
@@ -257,11 +264,11 @@
/// GotoStmt - This represents a direct goto.
///
class GotoStmt : public Stmt {
- IdentifierInfo *Label;
+ LabelStmt *Label;
public:
- GotoStmt(IdentifierInfo *label) : Stmt(GotoStmtClass), Label(label) {}
+ GotoStmt(LabelStmt *label) : Stmt(GotoStmtClass), Label(label) {}
- IdentifierInfo *getLabel() { return Label; }
+ LabelStmt *getLabel() { return Label; }
virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) {
Modified: cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=39509&r1=39508&r2=39509&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:45:07 2007
@@ -470,6 +470,11 @@
DIAG(err_array_size_non_int, ERROR,
"size of array has non-integer type '%0'")
+DIAG(err_redefinition_of_label, ERROR,
+ "redefinition of label '%0'")
+DIAG(err_undeclared_label_use, ERROR,
+ "use of undeclared label '%0'")
+
DIAG(warn_implicit_function_decl, WARNING,
"implicit declaration of function '%0'")
DIAG(ext_implicit_function_decl, EXTENSION,
More information about the cfe-commits
mailing list