nickdesaulniers created this revision.
nickdesaulniers added reviewers: void, jyknight, jyu2, efriedma.
nickdesaulniers requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

When performing CFG based analyses, don't forget to check the child
statements of an asm goto, such as the expressions used for
inputs+outputs.

Fixes: https://github.com/llvm/llvm-project/issues/51024
Fixes: https://github.com/ClangBuiltLinux/linux/issues/1439


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D116059

Files:
  clang/lib/Analysis/CFG.cpp
  clang/lib/Analysis/UninitializedValues.cpp
  clang/test/Analysis/asm-goto.cpp

Index: clang/test/Analysis/asm-goto.cpp
===================================================================
--- clang/test/Analysis/asm-goto.cpp
+++ clang/test/Analysis/asm-goto.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_analyze_cc1  -triple i386-pc-linux-gnu -analyzer-checker=debug.DumpCFG %s 2>&1 | FileCheck %s
-// RUN: %clang_analyze_cc1  -triple x86_64-pc-linux-gnu -analyzer-checker=debug.DumpCFG %s 2>&1 | FileCheck %s
+// RUN: %clang_analyze_cc1 -triple i386-pc-linux-gnu -analyzer-checker=debug.DumpCFG %s 2>&1 | FileCheck %s
+// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu -analyzer-checker=debug.DumpCFG %s 2>&1 | FileCheck %s
 
 int foo(int cond)
 {
@@ -17,11 +17,13 @@
 // CHECK-NEXT: Succs (1): B0
 
 // CHECK-LABEL: label_true
+// CHECK-NEXT: cond
+// CHECK-NEXT: [B3.1]
 // CHECK-NEXT: asm goto
+// CHECK-NEXT: T: [B3.3]
 // CHECK-NEXT: Preds (2): B3 B4
 // CHECK-NEXT: Succs (3): B2 B3 B1
 
-
 int bar(int cond)
 {
   asm goto("testl %0, %0; jne %l1;" :: "r"(cond)::L1, L2);
@@ -32,7 +34,10 @@
 }
 
 // CHECK: [B4]
+// CHECK-NEXT: cond
+// CHECK-NEXT: [B4.1]
 // CHECK-NEXT: asm goto
+// CHECK-NEXT: T: [B4.3]
 // CHECK-NEXT: Preds (1): B5
 // CHECK-NEXT: Succs (3): B3 B2 B1
 
@@ -48,6 +53,22 @@
 }
 
 // CHECK-LABEL: A1
+// CHECK-NEXT: n
+// CHECK-NEXT: [B4.1]
 // CHECK-NEXT: asm goto
+// CHECK-NEXT: T: [B4.3]
 // CHECK-NEXT: Preds (2): B5 B4
 // CHECK-NEXT: Succs (5): B3 B4 B2 B1 B5
+
+void baz(void)
+{
+  asm goto("" :: "r"(1 ? 2 : 0 << -1) :: error);
+error:;
+}
+
+// CHECK: [B2]
+// CHECK-NEXT: 1: [B5.2] ? [B3.1] : [B4.4]
+// CHECK-NEXT: 2: asm goto ("" :  : "r" ([B2.1]) :  : error);
+// CHECK-NEXT: T: [B2.2]
+// CHECK-NEXT: Preds (2): B3 B4
+// CHECK-NEXT: Succs (1): B1
Index: clang/lib/Analysis/UninitializedValues.cpp
===================================================================
--- clang/lib/Analysis/UninitializedValues.cpp
+++ clang/lib/Analysis/UninitializedValues.cpp
@@ -820,10 +820,10 @@
       Ex = stripCasts(C, UO->getSubExpr());
 
     if (const VarDecl *VD = findVar(Ex).getDecl())
-      if (vals[VD] != Initialized)
-        // If the variable isn't initialized by the time we get here, then we
-        // mark it as potentially uninitialized for those cases where it's used
-        // on an indirect path, where it's not guaranteed to be defined.
+      if (vals[VD] == Initialized)
+        // If the variable is initialized by the time we get here, then we mark
+        // it as potentially uninitialized for those cases where it's used on
+        // an indirect path, where it's not guaranteed to be defined.
         vals[VD] = MayUninitialized;
   }
 }
Index: clang/lib/Analysis/CFG.cpp
===================================================================
--- clang/lib/Analysis/CFG.cpp
+++ clang/lib/Analysis/CFG.cpp
@@ -3340,23 +3340,23 @@
 CFGBlock *CFGBuilder::VisitGCCAsmStmt(GCCAsmStmt *G, AddStmtChoice asc) {
   // Goto is a control-flow statement.  Thus we stop processing the current
   // block and create a new one.
+  if (G->isAsmGoto()) {
+    if (Block) {
+      Succ = Block;
+      if (badCFG)
+        return nullptr;
+    }
 
-  if (!G->isAsmGoto())
-    return VisitStmt(G, asc);
-
-  if (Block) {
-    Succ = Block;
-    if (badCFG)
-      return nullptr;
+    Block = createBlock();
+    Block->setTerminator(G);
+    // We will backpatch this block later for all the labels.
+    BackpatchBlocks.push_back(JumpSource(Block, ScopePos));
+    // Save "Succ" in BackpatchBlocks. In the backpatch processing, "Succ" is
+    // used to avoid adding "Succ" again.
+    BackpatchBlocks.push_back(JumpSource(Succ, ScopePos));
   }
-  Block = createBlock();
-  Block->setTerminator(G);
-  // We will backpatch this block later for all the labels.
-  BackpatchBlocks.push_back(JumpSource(Block, ScopePos));
-  // Save "Succ" in BackpatchBlocks. In the backpatch processing, "Succ" is
-  // used to avoid adding "Succ" again.
-  BackpatchBlocks.push_back(JumpSource(Succ, ScopePos));
-  return Block;
+
+  return VisitStmt(G, asc);
 }
 
 CFGBlock *CFGBuilder::VisitForStmt(ForStmt *F) {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to