change Scope::WithinElse to be a normal scope flag, widen the
fields to two 16-bit values instead of using bitfields.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@101020 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Parse/Scope.h b/include/clang/Parse/Scope.h
index fe860ff..6d1a93c 100644
--- a/include/clang/Parse/Scope.h
+++ b/include/clang/Parse/Scope.h
@@ -72,7 +72,11 @@
/// ObjCMethodScope - This scope corresponds to an Objective-C method body.
/// It always has FnScope and DeclScope set as well.
- ObjCMethodScope = 0x400
+ ObjCMethodScope = 0x400,
+
+ /// ElseScope - This scoep corresponds to an 'else' scope of an if/then/else
+ /// statement.
+ ElseScope = 0x800
};
private:
/// The parent scope for this scope. This is null for the translation-unit
@@ -81,15 +85,11 @@
/// Depth - This is the depth of this scope. The translation-unit scope has
/// depth 0.
- unsigned Depth : 16;
+ unsigned short Depth;
/// Flags - This contains a set of ScopeFlags, which indicates how the scope
/// interrelates with other control flow statements.
- unsigned Flags : 11;
-
- /// WithinElse - Whether this scope is part of the "else" branch in
- /// its parent ControlScope.
- bool WithinElse : 1;
+ unsigned short Flags;
/// FnParent - If this scope has a parent scope that is a function body, this
/// pointer is non-null and points to it. This is used for label processing.
@@ -144,6 +144,7 @@
/// getFlags - Return the flags for this scope.
///
unsigned getFlags() const { return Flags; }
+ void setFlags(unsigned F) { Flags = F; }
/// isBlockScope - Return true if this scope does not correspond to a
/// closure.
@@ -272,12 +273,6 @@
return getFlags() & Scope::AtCatchScope;
}
- /// isWithinElse - Whether we are within the "else" of the
- /// ControlParent (if any).
- bool isWithinElse() const { return WithinElse; }
-
- void setWithinElse(bool WE) { WithinElse = WE; }
-
typedef UsingDirectivesTy::iterator udir_iterator;
typedef UsingDirectivesTy::const_iterator const_udir_iterator;
@@ -307,7 +302,6 @@
AnyParent = Parent;
Depth = AnyParent ? AnyParent->Depth+1 : 0;
Flags = ScopeFlags;
- WithinElse = false;
if (AnyParent) {
FnParent = AnyParent->FnParent;
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index b208c50..9b22270 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -643,6 +643,7 @@
if (Tok.is(tok::kw_else)) {
ElseLoc = ConsumeToken();
+ ElseStmtLoc = Tok.getLocation();
// C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if
// there is no compound stmt. C90 does not have this clause. We only do
@@ -656,12 +657,14 @@
ParseScope InnerScope(this, Scope::DeclScope,
C99orCXX && Tok.isNot(tok::l_brace));
- bool WithinElse = CurScope->isWithinElse();
- CurScope->setWithinElse(true);
- ElseStmtLoc = Tok.getLocation();
+ // Regardless of whether or not InnerScope actually pushed a scope, set the
+ // ElseScope flag for the innermost scope so we can diagnose use of the if
+ // condition variable in C++.
+ unsigned OldFlags = CurScope->getFlags();
+ CurScope->setFlags(OldFlags | Scope::ElseScope);
ElseStmt = ParseStatement();
- CurScope->setWithinElse(WithinElse);
-
+ CurScope->setFlags(OldFlags);
+
// Pop the 'else' scope if needed.
InnerScope.Exit();
}
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 2630059..d6f1358 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -1105,16 +1105,15 @@
// Warn about constructs like:
// if (void *X = foo()) { ... } else { X }.
// In the else block, the pointer is always false.
-
if (Var->isDeclaredInCondition() && Var->getType()->isScalarType()) {
Scope *CheckS = S;
while (CheckS && CheckS->getControlParent()) {
- if (CheckS->isWithinElse() &&
+ if ((CheckS->getFlags() & Scope::ElseScope) &&
CheckS->getControlParent()->isDeclScope(DeclPtrTy::make(Var))) {
ExprError(Diag(NameLoc, diag::warn_value_always_zero)
<< Var->getDeclName()
- << (Var->getType()->isPointerType()? 2 :
- Var->getType()->isBooleanType()? 1 : 0));
+ << (Var->getType()->isPointerType() ? 2 :
+ Var->getType()->isBooleanType() ? 1 : 0));
break;
}
diff --git a/test/CXX/stmt.stmt/stmt.select/p3.cpp b/test/CXX/stmt.stmt/stmt.select/p3.cpp
index e674f97..31de685 100644
--- a/test/CXX/stmt.stmt/stmt.select/p3.cpp
+++ b/test/CXX/stmt.stmt/stmt.select/p3.cpp
@@ -9,3 +9,11 @@
int x; // expected-error{{redefinition of 'x'}}
}
}
+
+
+void h() {
+ if (int x = f()) // expected-note 2{{previous definition}}
+ int x; // expected-error{{redefinition of 'x'}}
+ else
+ int x; // expected-error{{redefinition of 'x'}}
+}
\ No newline at end of file