xref: /llvm-project/clang/test/Analysis/asm.cpp (revision 8d661fd9fd50fe4be9a9d5a8cc8f52f23925e7f6)
1 // RUN: %clang_analyze_cc1 -triple=x86_64-unknown-unknown \
2 // RUN:      -analyzer-checker debug.ExprInspection,core -Wno-error=invalid-gnu-asm-cast -w %s -verify
3 
4 int clang_analyzer_eval(int);
5 void clang_analyzer_dump(int);
6 void clang_analyzer_dump_ptr(void *);
7 
8 int global;
9 void testRValueOutput() {
10   int origVal = global;
11   __asm__("" : "=r"(((int)(global))));  // don't crash on rvalue output operand
12   int newVal = global; // Value "after" the invalidation.
13   clang_analyzer_eval(origVal == newVal); // expected-warning{{TRUE}} expected-warning{{FALSE}}
14 }
15 
16 void *MyMemcpy(void *d, const void *s, const int n) {
17   asm volatile (
18     "cld\n rep movsb\n"
19     :: "S" (s), "D" (d), "c" (n) : "memory"
20   );
21   return d;
22 }
23 
24 void testInlineAsmMemcpy(void)
25 {
26     int a, b = 10, c;
27     MyMemcpy(&a, &b, sizeof(b));
28     c = a; // no-warning
29 }
30 
31 void testInlineAsmMemcpyArray(void)
32 {
33     int a[10], b[10] = {}, c;
34     MyMemcpy(&a, &b, sizeof(b));
35     c = a[8]; // no-warning
36 }
37 
38 void testInlineAsmMemcpyUninit(void)
39 {
40     int a[10], b[10] = {}, c;
41     MyMemcpy(&a[1], &b[1], sizeof(b) - sizeof(b[1]));
42     c = a[0]; // FIXME: should be warning about uninitialized value, but invalidateRegions() also
43               // invalidates super region.
44 }
45 
46 void testInlineAsmMemcpyUninitLoop(const void *src, unsigned long len)
47 {
48     int a[10], c;
49     unsigned long toCopy = sizeof(a) < len ? sizeof(a) : len;
50 
51     MyMemcpy(a, src, toCopy);
52 
53     // Use index 1, since before use of invalidateRegions in VisitGCCAsmStmt, engine bound unknown SVal only to
54     // first element.
55     c = a[1]; // no-warning
56 }
57 
58 void testAsmWithVoidPtrArgument()
59 {
60   extern void *globalVoidPtr;
61   clang_analyzer_dump(*(int *)globalVoidPtr); // expected-warning-re {{reg_${{[0-9]+}}<int Element{SymRegion{reg_${{[0-9]+}}<void * globalVoidPtr>},0 S64b,int}>}}
62   clang_analyzer_dump_ptr(globalVoidPtr); // expected-warning-re {{&SymRegion{reg_${{[0-9]+}}<void * globalVoidPtr>}}}
63   asm ("" : : "a"(globalVoidPtr)); // no crash
64   clang_analyzer_dump(*(int *)globalVoidPtr); // expected-warning {{derived_}}
65   clang_analyzer_dump_ptr(globalVoidPtr); // expected-warning-re {{&SymRegion{reg_${{[0-9]+}}<void * globalVoidPtr>}}}
66 }
67