summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Naroff <snaroff@apple.com>2009-03-13 16:03:38 +0000
committerSteve Naroff <snaroff@apple.com>2009-03-13 16:03:38 +0000
commitcfb6cf4c021e41db7b36b7909296798d955e8123 (patch)
treea63259f07ce81c4b2fa9557976fd752b87c565e9
parent87710ca527f624ef0c5b4c5e2fbf1474e4eac219 (diff)
downloadbcm5719-llvm-cfb6cf4c021e41db7b36b7909296798d955e8123.tar.gz
bcm5719-llvm-cfb6cf4c021e41db7b36b7909296798d955e8123.zip
Reimplement fix for <rdar://problem/6451399> problems with labels and blocks.
This solution is much simpler (and doesn't add any per-scope overhead, which concerned Chris). The only downside is the LabelMap is now declared in two places (Sema and BlockSemaInfo). My original fix tried to unify the LabelMap in "Scope" (which would support nested functions in general). In any event, this fixes the bug given the current language definition. If/when we decide to support GCC style nested functions, this will need to be tweaked. llvm-svn: 66896
-rw-r--r--clang/lib/Sema/Sema.h5
-rw-r--r--clang/lib/Sema/SemaExpr.cpp3
-rw-r--r--clang/lib/Sema/SemaStmt.cpp5
-rw-r--r--clang/test/Sema/block-labels.c17
4 files changed, 27 insertions, 3 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
index b403a8ba1d1..d49efdddb19 100644
--- a/clang/lib/Sema/Sema.h
+++ b/clang/lib/Sema/Sema.h
@@ -2310,6 +2310,11 @@ struct BlockSemaInfo {
/// return types, if any, in the block body.
Type *ReturnType;
+ /// 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.
+ llvm::DenseMap<IdentifierInfo*, LabelStmt*> LabelMap;
+
/// PrevBlockInfo - If this is nested inside another block, this points
/// to the outer block.
BlockSemaInfo *PrevBlockInfo;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 9f915fc7f97..8324d8d4727 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -4336,7 +4336,8 @@ Sema::ExprResult Sema::ActOnAddrLabel(SourceLocation OpLoc,
SourceLocation LabLoc,
IdentifierInfo *LabelII) {
// Look up the record for this label identifier.
- LabelStmt *&LabelDecl = LabelMap[LabelII];
+ LabelStmt *&LabelDecl = CurBlock ? CurBlock->LabelMap[LabelII] :
+ LabelMap[LabelII];
// If we haven't seen this label yet, create a forward reference. It
// will be validated and/or cleaned up in ActOnFinishFunctionBody.
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index f8e225540bc..96e59f0f82b 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -170,7 +170,7 @@ Sema::ActOnLabelStmt(SourceLocation IdentLoc, IdentifierInfo *II,
SourceLocation ColonLoc, StmtArg subStmt) {
Stmt *SubStmt = static_cast<Stmt*>(subStmt.release());
// Look up the record for this label identifier.
- LabelStmt *&LabelDecl = LabelMap[II];
+ LabelStmt *&LabelDecl = CurBlock ? CurBlock->LabelMap[II] : LabelMap[II];
// If not forward referenced or defined already, just create a new LabelStmt.
if (LabelDecl == 0)
@@ -676,7 +676,8 @@ Sema::ActOnGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
return StmtError(Diag(GotoLoc, diag::err_goto_in_block));
// Look up the record for this label identifier.
- LabelStmt *&LabelDecl = LabelMap[LabelII];
+ LabelStmt *&LabelDecl = CurBlock ? CurBlock->LabelMap[LabelII] :
+ LabelMap[LabelII];
// If we haven't seen this label yet, create a forward reference.
if (LabelDecl == 0)
diff --git a/clang/test/Sema/block-labels.c b/clang/test/Sema/block-labels.c
index e69de29bb2d..15e6f61cede 100644
--- a/clang/test/Sema/block-labels.c
+++ b/clang/test/Sema/block-labels.c
@@ -0,0 +1,17 @@
+// RUN: clang %s -verify -fblocks -fsyntax-only
+
+int a() {
+ A:if (1) xx();
+ return ^{A:return 1;}();
+}
+int b() {
+ A: return ^{int a; A:return 1;}();
+}
+
+int d() {
+ A: return ^{int a; A: a = ^{int a; A:return 1;}() + ^{int b; A:return 2;}(); return a; }();
+}
+
+int c() {
+ goto A; return ^{ A:return 1;}(); // expected-error {{use of undeclared label 'A'}}
+}
OpenPOWER on IntegriCloud