[analyzer] Accept references to variables declared "extern void" (C only).
In C, 'void' is treated like any other incomplete type, and though it is
never completed, you can cast the address of a void-typed variable to do
something useful. (In C++ it's illegal to declare a variable with void type.)
Previously we asserted on this code; now we just treat it like any other
incomplete type.
And speaking of incomplete types, we don't know their extent. Actually
check that in TypedValueRegion::getExtent, though that's not being used
by any checkers that are on by default.
llvm-svn: 182880
diff --git a/clang/test/Analysis/misc-ps.c b/clang/test/Analysis/misc-ps.c
index b302860..01cad15 100644
--- a/clang/test/Analysis/misc-ps.c
+++ b/clang/test/Analysis/misc-ps.c
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -disable-free -analyzer-eagerly-assume -analyzer-checker=core -analyzer-checker=deadcode -verify %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -disable-free -analyzer-eagerly-assume -analyzer-checker=core,deadcode,debug.ExprInspection -verify %s
+
+void clang_analyzer_eval(int);
int size_rdar9373039 = 1;
int foo_rdar9373039(const char *);
@@ -175,3 +177,17 @@
context->callback(uninitialized); // expected-warning {{uninitialized}}
}
+
+// PR16131: C permits variables to be declared extern void.
+static void PR16131(int x) {
+ extern void v;
+
+ int *ip = (int *)&v;
+ char *cp = (char *)&v;
+ clang_analyzer_eval(ip == cp); // expected-warning{{TRUE}}
+ // expected-warning@-1 {{comparison of distinct pointer types}}
+
+ *ip = 42;
+ clang_analyzer_eval(*ip == 42); // expected-warning{{TRUE}}
+ clang_analyzer_eval(*(int *)&v == 42); // expected-warning{{TRUE}}
+}