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