nickdesaulniers updated this revision to Diff 397983.
nickdesaulniers added a comment.
This revision is now accepted and ready to land.
- MOAR TESTS RAWR!!1one
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D116059/new/
https://reviews.llvm.org/D116059
Files:
clang/lib/Analysis/CFG.cpp
clang/lib/Analysis/UninitializedValues.cpp
clang/test/Analysis/asm-goto.cpp
clang/test/Analysis/uninit-asm-goto.cpp
clang/test/Sema/array-bounds-ptr-arith.c
Index: clang/test/Sema/array-bounds-ptr-arith.c
===================================================================
--- clang/test/Sema/array-bounds-ptr-arith.c
+++ clang/test/Sema/array-bounds-ptr-arith.c
@@ -37,3 +37,15 @@
RDar11387038_B *pRDar11387038_B;
struct RDar11387038* y = &(*pRDar11387038_B->x)->z[4];
}
+
+void pr51682 (void) {
+ int arr [1];
+ switch (0) {
+ case 0:
+ break;
+ case 1:
+ asm goto (""::"r"(arr[42] >> 1)::failed); // no-warning
+ break;
+ }
+failed:;
+}
Index: clang/test/Analysis/uninit-asm-goto.cpp
===================================================================
--- clang/test/Analysis/uninit-asm-goto.cpp
+++ clang/test/Analysis/uninit-asm-goto.cpp
@@ -3,19 +3,19 @@
// test1: Expect no diagnostics
int test1(int x) {
int y;
- asm goto("nop" : "=r"(y) : "r"(x) : : err);
+ asm goto("" : "=r"(y) : "r"(x) : : err);
return y;
err:
return -1;
}
int test2(int x) {
- int y; // expected-warning {{variable 'y' is used uninitialized whenever its declaration is reached}} \
- // expected-note {{initialize the variable}}
+ int y; // expected-warning {{variable 'y' is used uninitialized whenever its declaration is reached}}
+ // expected-note@-1 {{initialize the variable}}
if (x < 42)
- asm volatile goto("testl %0, %0; testl %1, %2; jne %l3" : "+S"(x), "+D"(y) : "r"(x) :: indirect_1, indirect_2);
+ asm goto("" : "+S"(x), "+D"(y) : "r"(x) :: indirect_1, indirect_2);
else
- asm volatile goto("testl %0, %1; testl %2, %3; jne %l5" : "+S"(x), "+D"(y) : "r"(x), "r"(y) :: indirect_1, indirect_2);
+ asm goto("" : "+S"(x), "+D"(y) : "r"(x), "r"(y) :: indirect_1, indirect_2);
return x + y;
indirect_1:
return -42;
@@ -24,9 +24,9 @@
}
int test3(int x) {
- int y; // expected-warning {{variable 'y' is used uninitialized whenever its declaration is reached}} \
- // expected-note {{initialize the variable}}
- asm goto("xorl %1, %0; jmp %l2" : "=&r"(y) : "r"(x) : : fail);
+ int y; // expected-warning {{variable 'y' is used uninitialized whenever its declaration is reached}}
+ // expected-note@-1 {{initialize the variable}}
+ asm goto("" : "=&r"(y) : "r"(x) : : fail);
normal:
y += x;
return y;
@@ -38,20 +38,20 @@
}
int test4(int x) {
- int y; // expected-warning {{variable 'y' is used uninitialized whenever its declaration is reached}} \
- // expected-note {{initialize the variable}}
+ int y; // expected-warning {{variable 'y' is used uninitialized whenever its declaration is reached}}
+ // expected-note@-1 {{initialize the variable}}
goto forward;
backward:
return y; // expected-note {{uninitialized use occurs here}}
forward:
- asm goto("# %0 %1 %2" : "=r"(y) : "r"(x) : : backward);
+ asm goto("" : "=r"(y) : "r"(x) : : backward);
return y;
}
// test5: Expect no diagnostics
int test5(int x) {
int y;
- asm volatile goto("testl %0, %0; testl %1, %2; jne %l3" : "+S"(x), "+D"(y) : "r"(x) :: indirect, fallthrough);
+ asm goto("" : "+S"(x), "+D"(y) : "r"(x) :: indirect, fallthrough);
fallthrough:
return y;
indirect:
@@ -63,9 +63,30 @@
unsigned int val;
// See through casts and unary operators.
- asm goto("nop" : "=r" (*(unsigned int *)(&val)) ::: indirect);
+ asm goto("" : "=r" (*(unsigned int *)(&val)) ::: indirect);
*x = val;
return 0;
indirect:
return -1;
}
+
+int test7(int z) {
+ int x; // expected-warning {{variable 'x' is used uninitialized whenever its declaration is reached}}
+ // expected-note@-1 {{initialize the variable 'x' to silence this warning}}
+ if (z)
+ asm goto ("":"=r"(x):::A1,A2);
+ return 0;
+ A1:
+ A2:
+ return x; // expected-note {{uninitialized use occurs here}}
+}
+
+int test8() {
+ int x = 0; // expected-warning {{variable 'x' is used uninitialized whenever its declaration is reached}}
+ // expected-note@-1 {{variable 'x' is declared here}}
+ asm goto ("":"=r"(x):::A1,A2);
+ return 0;
+ A1:
+ A2:
+ return x; // expected-note {{uninitialized use occurs here}}
+}
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,12 @@
// CHECK-NEXT: Succs (1): B0
// CHECK-LABEL: label_true
-// CHECK-NEXT: asm goto
+// CHECK-NEXT: cond
+// CHECK-NEXT: [B3.1]
+// CHECK-NEXT: T: asm goto
// 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 +33,9 @@
}
// CHECK: [B4]
-// CHECK-NEXT: asm goto
+// CHECK-NEXT: cond
+// CHECK-NEXT: [B4.1]
+// CHECK-NEXT: T: asm goto
// CHECK-NEXT: Preds (1): B5
// CHECK-NEXT: Succs (3): B3 B2 B1
@@ -48,6 +51,20 @@
}
// CHECK-LABEL: A1
-// CHECK-NEXT: asm goto
+// CHECK-NEXT: n
+// CHECK-NEXT: [B4.1]
+// CHECK-NEXT: T: asm goto
// 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: T: asm goto ("" : : "r" ([B2.1]) : : error);
+// 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
@@ -819,12 +819,11 @@
while (const auto *UO = dyn_cast<UnaryOperator>(Ex))
Ex = stripCasts(C, UO->getSubExpr());
+ // Mark the variable as potentially uninitialized for those cases where
+ // it's used on an indirect path, where it's not guaranteed to be
+ // defined.
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.
- vals[VD] = MayUninitialized;
+ vals[VD] = MayUninitialized;
}
}
Index: clang/lib/Analysis/CFG.cpp
===================================================================
--- clang/lib/Analysis/CFG.cpp
+++ clang/lib/Analysis/CFG.cpp
@@ -3354,7 +3354,7 @@
// 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 VisitChildren(G);
}
CFGBlock *CFGBuilder::VisitForStmt(ForStmt *F) {
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits