This is an archive of the discontinued LLVM Phabricator instance.

Un-revert "[coroutines][PR40978] Emit error for co_yield within catch block"
ClosedPublic

Authored by modocache on Mar 24 2019, 2:20 PM.

Details

Summary

https://reviews.llvm.org/D59076 added a new coroutine error that
prevented users from using 'co_await' or 'co_yield' within a exception
handler. However, it was reverted in https://reviews.llvm.org/rC356774
because it caused a regression in nested scopes in C++ catch statements,
as documented by https://bugs.llvm.org/show_bug.cgi?id=41171.

The issue was due to an incorrect use of a clang::ParseScope. To fix:

  1. Add a regression test for catch statement parsing that mimics the bug report from https://bugs.llvm.org/show_bug.cgi?id=41171.
  2. Re-apply the coroutines error patch from https://reviews.llvm.org/D59076, but this time with the correct ParseScope behavior.

Diff Detail

Event Timeline

modocache created this revision.Mar 24 2019, 2:20 PM
Herald added a project: Restricted Project. · View Herald TranscriptMar 24 2019, 2:20 PM
riccibruno added inline comments.Mar 24 2019, 3:59 PM
lib/Parse/ParseStmt.cpp
2293

Just to make sure I understood the problem correctly, the issue was that you passed ScopeFlags to ParseCompoundStatement(). This override the default flags which are Scope::DeclScope | Scope::CompoundStmtScope. In particular now ParseCompoundStatement() was done as if in the controlling scope of an if statement. Now as per [basic.scope.block]/p4:

Names declared in the init-statement, the for-range-declaration, and in the condition of if, while, for, and switch statements are local to the if, while, for, or switch statement (including the controlled statement), and shall not be redeclared in a subsequent condition of that statement nor in the outermost block (or, for the if statement, any of the outermost blocks) of the controlled statement; see 9.4.

This caused the declaration in the compound statement to be detected as erroneous. Indeed the following worked just fine.

void f() {
    try {}
    catch (...) {
        int i;
        {
            {
                int i;
            }
        }
    }
}

Does this make sense or I am completely off base here ?

modocache added inline comments.Mar 24 2019, 4:05 PM
lib/Parse/ParseStmt.cpp
2293

That's exactly my understanding, yes! In fact thank you for the clear explanation.

riccibruno accepted this revision.Mar 24 2019, 4:25 PM

Great! Since this already received one round of reviews I guess this looks okay.

test/SemaCXX/exceptions.cpp
25

I am wondering if there is already a test which checks systematically that a declaration which shadows another declaration is valid/invalid. I am not seeing such a systematic test, but it might be a nice addition (though that it clearly out of scope for this patch)

This revision is now accepted and ready to land.Mar 24 2019, 4:25 PM

Thank you for the review!

test/SemaCXX/exceptions.cpp
25

That's a good point. I was very surprised when I learned that my original patch had broken the lookup behavior described in https://bugs.llvm.org/show_bug.cgi?id=41171 but still passed all the tests in check-clang. I'll try to follow up this patch with some more comprehensive tests.

This revision was automatically updated to reflect the committed changes.