[cfe-commits] r167650 - in /cfe/trunk: include/clang/Parse/Parser.h include/clang/Sema/Scope.h lib/Parse/ParseStmt.cpp lib/Sema/IdentifierResolver.cpp test/CXX/basic/basic.scope/basic.scope.local/p2.cpp

David Blaikie dblaikie at gmail.com
Fri Nov 9 17:04:23 PST 2012


Author: dblaikie
Date: Fri Nov  9 19:04:23 2012
New Revision: 167650

URL: http://llvm.org/viewvc/llvm-project?rev=167650&view=rev
Log:
PR14296: function parameter name collisions in function try/catch

C++11 3.3.3/2 "A parameter name shall not be redeclared in the outermost block
of the function definition nor in the outermost block of any handler associated
with a function-try-block."

It's not totally clear to me whether the "FIXME" case is covered by this, but
Richard Smith thinks it probably should be. It's just a bit more involved to
fix that case.

Added:
    cfe/trunk/test/CXX/basic/basic.scope/basic.scope.local/p2.cpp
Modified:
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/include/clang/Sema/Scope.h
    cfe/trunk/lib/Parse/ParseStmt.cpp
    cfe/trunk/lib/Sema/IdentifierResolver.cpp

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=167650&r1=167649&r2=167650&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Fri Nov  9 19:04:23 2012
@@ -1563,8 +1563,8 @@
   // C++ 6: Statements and Blocks
 
   StmtResult ParseCXXTryBlock();
-  StmtResult ParseCXXTryBlockCommon(SourceLocation TryLoc);
-  StmtResult ParseCXXCatchBlock();
+  StmtResult ParseCXXTryBlockCommon(SourceLocation TryLoc, bool FnTry = false);
+  StmtResult ParseCXXCatchBlock(bool FnCatch = false);
 
   //===--------------------------------------------------------------------===//
   // MS: SEH Statements and Blocks

Modified: cfe/trunk/include/clang/Sema/Scope.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Scope.h?rev=167650&r1=167649&r2=167650&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Scope.h (original)
+++ cfe/trunk/include/clang/Sema/Scope.h Fri Nov  9 19:04:23 2012
@@ -82,7 +82,13 @@
     SwitchScope = 0x800,
 
     /// TryScope - This is the scope of a C++ try statement.
-    TryScope = 0x1000
+    TryScope = 0x1000,
+
+    /// FnTryScope - This is the scope of a function-level C++ try scope.
+    FnTryScope = 0x3000,
+
+    /// FnCatchScope - This is the scope of a function-level C++ catch scope.
+    FnCatchScope = 0x4000
   };
 private:
   /// The parent scope for this scope.  This is null for the translation-unit

Modified: cfe/trunk/lib/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=167650&r1=167649&r2=167650&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseStmt.cpp (original)
+++ cfe/trunk/lib/Parse/ParseStmt.cpp Fri Nov  9 19:04:23 2012
@@ -2051,7 +2051,7 @@
   }
 
   SourceLocation LBraceLoc = Tok.getLocation();
-  StmtResult FnBody(ParseCXXTryBlockCommon(TryLoc));
+  StmtResult FnBody(ParseCXXTryBlockCommon(TryLoc, /*FnTry*/true));
   // If we failed to parse the try-catch, we just give the function an empty
   // compound statement as the body.
   if (FnBody.isInvalid()) {
@@ -2117,13 +2117,14 @@
 ///         'try' compound-statement seh-except-block
 ///         'try' compound-statment  seh-finally-block
 ///
-StmtResult Parser::ParseCXXTryBlockCommon(SourceLocation TryLoc) {
+StmtResult Parser::ParseCXXTryBlockCommon(SourceLocation TryLoc, bool FnTry) {
   if (Tok.isNot(tok::l_brace))
     return StmtError(Diag(Tok, diag::err_expected_lbrace));
   // FIXME: Possible draft standard bug: attribute-specifier should be allowed?
 
   StmtResult TryBlock(ParseCompoundStatement(/*isStmtExpr=*/false,
-                                             Scope::DeclScope|Scope::TryScope));
+                      Scope::DeclScope |
+                        (FnTry ? Scope::FnTryScope : Scope::TryScope)));
   if (TryBlock.isInvalid())
     return TryBlock;
 
@@ -2159,7 +2160,7 @@
     if (Tok.isNot(tok::kw_catch))
       return StmtError(Diag(Tok, diag::err_expected_catch));
     while (Tok.is(tok::kw_catch)) {
-      StmtResult Handler(ParseCXXCatchBlock());
+      StmtResult Handler(ParseCXXCatchBlock(FnTry));
       if (!Handler.isInvalid())
         Handlers.push_back(Handler.release());
     }
@@ -2183,7 +2184,7 @@
 ///         type-specifier-seq
 ///         '...'
 ///
-StmtResult Parser::ParseCXXCatchBlock() {
+StmtResult Parser::ParseCXXCatchBlock(bool FnCatch) {
   assert(Tok.is(tok::kw_catch) && "Expected 'catch'");
 
   SourceLocation CatchLoc = ConsumeToken();
@@ -2195,7 +2196,8 @@
   // C++ 3.3.2p3:
   // The name in a catch exception-declaration is local to the handler and
   // shall not be redeclared in the outermost block of the handler.
-  ParseScope CatchScope(this, Scope::DeclScope | Scope::ControlScope);
+  ParseScope CatchScope(this, Scope::DeclScope | Scope::ControlScope |
+                          (FnCatch ? Scope::FnCatchScope : 0));
 
   // exception-declaration is equivalent to '...' or a parameter-declaration
   // without default arguments.

Modified: cfe/trunk/lib/Sema/IdentifierResolver.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/IdentifierResolver.cpp?rev=167650&r1=167649&r2=167650&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/IdentifierResolver.cpp (original)
+++ cfe/trunk/lib/Sema/IdentifierResolver.cpp Fri Nov  9 19:04:23 2012
@@ -135,8 +135,13 @@
       // of the controlled statement.
       //
       assert(S->getParent() && "No TUScope?");
-      if (S->getParent()->getFlags() & Scope::ControlScope)
+      if (S->getFlags() & Scope::FnTryScope)
         return S->getParent()->isDeclScope(D);
+      if (S->getParent()->getFlags() & Scope::ControlScope) {
+        if (S->getParent()->getFlags() & Scope::FnCatchScope)
+          S = S->getParent();
+        return S->getParent()->isDeclScope(D);
+      }
     }
     return false;
   }

Added: cfe/trunk/test/CXX/basic/basic.scope/basic.scope.local/p2.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/basic/basic.scope/basic.scope.local/p2.cpp?rev=167650&view=auto
==============================================================================
--- cfe/trunk/test/CXX/basic/basic.scope/basic.scope.local/p2.cpp (added)
+++ cfe/trunk/test/CXX/basic/basic.scope/basic.scope.local/p2.cpp Fri Nov  9 19:04:23 2012
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fcxx-exceptions -fexceptions -verify %s
+
+void func1(int i) { // expected-note{{previous definition is here}}
+  int i; // expected-error{{redefinition of 'i'}}
+}
+
+void func2(int i) try { // expected-note{{previous definition is here}}
+  int i; // expected-error{{redefinition of 'i'}}
+} catch (...) {
+}
+
+void func3(int i) try { // FIXME: note {{previous definition is here}}
+} catch (int i) { // FIXME: error {{redefinition of 'i'}}
+}
+
+void func4(int i) try { // expected-note{{previous definition is here}}
+} catch (...) {
+  int i; // expected-error{{redefinition of 'i'}}
+}
+
+void func5() try {
+  int i;
+} catch (...) {
+  int j = i; // expected-error{{use of undeclared identifier 'i'}}
+}





More information about the cfe-commits mailing list