On 07/07/2014 01:53, Nico Weber wrote:
Author: nico
Date: Sun Jul  6 17:53:19 2014
New Revision: 212422

URL:http://llvm.org/viewvc/llvm-project?rev=212422&view=rev
Log:
Sema: Check that __leave is contained in a __try block.

Give scope a SEHTryScope bit, set that in ParseSEHTry(), and let Sema
walk the scope chain to find the SEHTry parent on __leave statements.
(They are rare enough that it seems better to do the walk instead of
giving Scope a SEHTryParent pointer -- this is similar to AtCatchScope.)

Modified:
     cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
     cfe/trunk/include/clang/Sema/Scope.h
     cfe/trunk/lib/Parse/ParseStmt.cpp
     cfe/trunk/lib/Sema/Scope.cpp
     cfe/trunk/lib/Sema/SemaStmt.cpp
     cfe/trunk/test/Sema/__try.c
     cfe/trunk/test/SemaCXX/__try.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL:http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=212422&r1=212421&r2=212422&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sun Jul  6 17:53:19 
2014
@@ -5155,6 +5155,8 @@ def err_need_header_before_ms_uuidof : E
    "you need to include <guiddef.h> before using the '__uuidof' operator">;
  def err_ms___leave_unimplemented : Error<
    "__leave support not implemented yet">;
+def err_ms___leave_not_in___try : Error<
+  "'__leave' statement not in __try block">;
  def err_uuidof_without_guid : Error<
    "cannot call operator __uuidof on a type with no GUID">;
  def err_uuidof_with_multiple_guids : Error<

The triple underscores don't add much here, how about just 'err_ms_leave_not_in_try' and 'err_ms_leave_unimplemented' to match the style of others like 'like the err_uuidof_without_guid' immediately below?


Modified: cfe/trunk/include/clang/Sema/Scope.h
URL:http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Scope.h?rev=212422&r1=212421&r2=212422&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Scope.h (original)
+++ cfe/trunk/include/clang/Sema/Scope.h Sun Jul  6 17:53:19 2014
@@ -114,6 +114,9 @@ public:
/// This scope corresponds to an enum.
      EnumScope = 0x40000,
+
+    /// This scope corresponds to a SEH try.
+    SEHTryScope = 0x80000,
    };
  private:
    /// The parent scope for this scope.  This is null for the translation-unit
@@ -398,6 +401,9 @@ public:
    /// \brief Determine whether this scope is a C++ 'try' block.
    bool isTryScope() const { return getFlags() & Scope::TryScope; }
+ /// \brief Determine whether this scope is a SEH '__try' block.
+  bool isSEHTryScope() const { return getFlags() & Scope::SEHTryScope; }
+
    /// containedInPrototypeScope - Return true if this or a parent scope
    /// is a FunctionPrototypeScope.
    bool containedInPrototypeScope() const;

Modified: cfe/trunk/lib/Parse/ParseStmt.cpp
URL:http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=212422&r1=212421&r2=212422&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseStmt.cpp (original)
+++ cfe/trunk/lib/Parse/ParseStmt.cpp Sun Jul  6 17:53:19 2014
@@ -427,7 +427,8 @@ StmtResult Parser::ParseSEHTryBlockCommo
    if(Tok.isNot(tok::l_brace))
      return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);
- StmtResult TryBlock(ParseCompoundStatement());
+  StmtResult TryBlock(ParseCompoundStatement(/*isStmtExpr=*/false,
+                      Scope::DeclScope | Scope::SEHTryScope));
    if(TryBlock.isInvalid())
      return TryBlock;
Modified: cfe/trunk/lib/Sema/Scope.cpp
URL:http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Scope.cpp?rev=212422&r1=212421&r2=212422&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Scope.cpp (original)
+++ cfe/trunk/lib/Sema/Scope.cpp Sun Jul  6 17:53:19 2014
@@ -182,6 +182,9 @@ void Scope::dumpImpl(raw_ostream &OS) co
      } else if (Flags & FnTryCatchScope) {
        OS << "FnTryCatchScope";
        Flags &= ~FnTryCatchScope;
+    } else if (Flags & SEHTryScope) {
+      OS << "SEHTryScope";
+      Flags &= ~SEHTryScope;
      } else if (Flags & OpenMPDirectiveScope) {
        OS << "OpenMPDirectiveScope";
        Flags &= ~OpenMPDirectiveScope;

Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
URL:http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=212422&r1=212421&r2=212422&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Sun Jul  6 17:53:19 2014
@@ -3279,6 +3279,12 @@ Sema::ActOnSEHFinallyBlock(SourceLocatio
StmtResult
  Sema::ActOnSEHLeaveStmt(SourceLocation Loc, Scope *CurScope) {
+  Scope *SEHTryParent = CurScope;
+  while (SEHTryParent && !SEHTryParent->isSEHTryScope())
+    SEHTryParent = SEHTryParent->getParent();
+  if (!SEHTryParent)
+    return StmtError(Diag(Loc, diag::err_ms___leave_not_in___try));
+
    return StmtError(Diag(Loc, diag::err_ms___leave_unimplemented));
  }
Modified: cfe/trunk/test/Sema/__try.c
URL:http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/__try.c?rev=212422&r1=212421&r2=212422&view=diff
==============================================================================
--- cfe/trunk/test/Sema/__try.c (original)
+++ cfe/trunk/test/Sema/__try.c Sun Jul  6 17:53:19 2014
@@ -172,26 +172,23 @@ void TEST() {
  }
void test___leave() {

Since this is a sema test, how about naming it after the semantics being tested -- void test_seh_leave_stmt() ?

Alp.


-  // FIXME: should say "__leave stmt not in __try block":
-  __leave; // expected-error{{not implemented yet}}
+  __leave; // expected-error{{'__leave' statement not in __try block}}
+
    __try {
      // FIXME: should be fine
      __leave; // expected-error{{not implemented yet}}
      // FIXME: should say "expected ';' after __leave statement"
      __leave 4; // expected-error{{not implemented yet}} 
expected-warning{{expression result unused}}
    } __except(1) {
-    // FIXME: should say "__leave stmt not in __try block":
-    __leave; // expected-error{{not implemented yet}}
+    __leave; // expected-error{{'__leave' statement not in __try block}}
    }
__try {
      // FIXME: should be fine
      __leave; // expected-error{{not implemented yet}}
    } __finally {
-    // FIXME: should say "__leave stmt not in __try block":
-    __leave; // expected-error{{not implemented yet}}
+    __leave; // expected-error{{'__leave' statement not in __try block}}
    }
-  // FIXME: should say "__leave stmt not in __try block":
-  __leave; // expected-error{{not implemented yet}}
+  __leave; // expected-error{{'__leave' statement not in __try block}}
  }
Modified: cfe/trunk/test/SemaCXX/__try.cpp
URL:http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/__try.cpp?rev=212422&r1=212421&r2=212422&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/__try.cpp (original)
+++ cfe/trunk/test/SemaCXX/__try.cpp Sun Jul  6 17:53:19 2014
@@ -83,8 +83,7 @@ void test___leave() {
    // Clang accepts try with __finally. MSVC doesn't. (Maybe a Borland thing?)
    // __leave in mixed blocks isn't supported.
    try {
-    // FIXME: should say "__leave stmt not in __try block":
-    __leave; // expected-error{{not implemented yet}}
+    __leave; // expected-error{{'__leave' statement not in __try block}}
    } __finally {
    }
  }


_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

--
http://www.nuanti.com
the browser experts

_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to