[clang] 8d902f2 - [clang] Force AttributedStmtClass to not be scope parents (#125370)

via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 11 05:53:28 PST 2025


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;
+    }
+}


        


More information about the cfe-commits mailing list