Author: Yutong Zhu Date: 2025-02-11T08:53:19-05:00 New Revision: 8d902f2cb0bc8825bcde911897e99aadbd5d28e9
URL: https://github.com/llvm/llvm-project/commit/8d902f2cb0bc8825bcde911897e99aadbd5d28e9 DIFF: https://github.com/llvm/llvm-project/commit/8d902f2cb0bc8825bcde911897e99aadbd5d28e9.diff LOG: [clang] Force AttributedStmtClass to not be scope parents (#125370) Example from the issue: ```c++ void Func(int x) { switch (x) { [[likely]] case 0: case 1: int i = 3; case 2: break; } } ``` Clang checks if ``case 2`` can be reachable by checking its scope. The variable declaration should create a scope containing ``case 2``, but due to the structure of the AST, ``case 2`` gets the scope of the ``likely`` statement, but not ``int i = 3;``. Therefore, I changed this code to force attribute statement not to be scope parents. Fixes #84072 Added: clang/test/CXX/stmt.stmt/stmt.select/stmt.switch/p4.cpp Modified: clang/docs/ReleaseNotes.rst clang/lib/Sema/JumpDiagnostics.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 71cf8d48d2d57..369d9e9de7d16 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -129,6 +129,8 @@ Improvements to Clang's diagnostics which are supposed to only exist once per program, but may get duplicated when built into a shared library. - Fixed a bug where Clang's Analysis did not correctly model the destructor behavior of ``union`` members (#GH119415). +- A statement attribute applied to a ``case`` label no longer suppresses + 'bypassing variable initialization' diagnostics (#84072). Improvements to Clang's time-trace ---------------------------------- diff --git a/clang/lib/Sema/JumpDiagnostics.cpp b/clang/lib/Sema/JumpDiagnostics.cpp index ffbb9bc0bfe7c..edcfffa2b3894 100644 --- a/clang/lib/Sema/JumpDiagnostics.cpp +++ b/clang/lib/Sema/JumpDiagnostics.cpp @@ -597,15 +597,6 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, LabelAndGotoScopes[S] = ParentScope; break; - case Stmt::AttributedStmtClass: { - AttributedStmt *AS = cast<AttributedStmt>(S); - if (GetMustTailAttr(AS)) { - LabelAndGotoScopes[AS] = ParentScope; - MustTailStmts.push_back(AS); - } - break; - } - case Stmt::OpenACCComputeConstructClass: { unsigned NewParentScope = Scopes.size(); OpenACCComputeConstruct *CC = cast<OpenACCComputeConstruct>(S); @@ -649,7 +640,7 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, continue; } - // Cases, labels, and defaults aren't "scope parents". It's also + // Cases, labels, attributes, and defaults aren't "scope parents". It's also // important to handle these iteratively instead of recursively in // order to avoid blowing out the stack. while (true) { @@ -658,7 +649,13 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, Next = SC->getSubStmt(); else if (LabelStmt *LS = dyn_cast<LabelStmt>(SubStmt)) Next = LS->getSubStmt(); - else + else if (AttributedStmt *AS = dyn_cast<AttributedStmt>(SubStmt)) { + if (GetMustTailAttr(AS)) { + LabelAndGotoScopes[AS] = ParentScope; + MustTailStmts.push_back(AS); + } + Next = AS->getSubStmt(); + } else break; LabelAndGotoScopes[SubStmt] = ParentScope; diff --git a/clang/test/CXX/stmt.stmt/stmt.select/stmt.switch/p4.cpp b/clang/test/CXX/stmt.stmt/stmt.select/stmt.switch/p4.cpp new file mode 100644 index 0000000000000..e816da1803694 --- /dev/null +++ b/clang/test/CXX/stmt.stmt/stmt.select/stmt.switch/p4.cpp @@ -0,0 +1,11 @@ +// RUN: %clang -fsyntax-only -std=c++20 -Xclang -verify %s + +void Func(int x) { + switch (x) { + [[likely]] case 0: + case 1: + int i = 3; // expected-note {{jump bypasses variable initialization}} + case 2: // expected-error {{cannot jump from switch statement to this case label}} + break; + } +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits