aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2011-03-27 20:35:59 +0000
committerChandler Carruth <chandlerc@gmail.com>2011-03-27 20:35:59 +0000
commit349894ec70777da4f8fe714670aca43acd2e844e (patch)
tree0910810a130c24a414ddaa11f8da1d19b22c1fcc
parent7ba8f522f32d37dc86e54b3c202a3f30bc1685d0 (diff)
Add tests for the uninitialized checks added in r128376. Also clean up
and flesh out the existing uninitialized testing for field initializers. The tests come from Richard's original patch, but I've cleaned them up a bit and ordered them more naturally. Also, I added a test for the most simple base case: int x = x; And it turns out we miss this one! =[ That and another bad FIXME on the field initializer checking are left in the test. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@128394 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--test/SemaCXX/uninitialized.cpp53
1 files changed, 42 insertions, 11 deletions
diff --git a/test/SemaCXX/uninitialized.cpp b/test/SemaCXX/uninitialized.cpp
index 26202fbccc..13ea9688ef 100644
--- a/test/SemaCXX/uninitialized.cpp
+++ b/test/SemaCXX/uninitialized.cpp
@@ -1,14 +1,45 @@
// RUN: %clang_cc1 -fsyntax-only -Wall -Wuninitialized -verify %s
-// Previously this triggered a warning on the sizeof(fieldB), indicating
-// a use of an uninitialized value.
-class Rdar8610363_A {
- int fieldA;
-public:
- Rdar8610363_A(int a);
-};
-class Rdar8610363_B {
- Rdar8610363_A fieldB;
-public:
- Rdar8610363_B(int b) : fieldB(sizeof(fieldB)) {} // no-warning
+int foo(int x);
+int bar(int* x);
+int boo(int& x);
+int far(const int& x);
+
+// Test self-references within initializers which are guaranteed to be
+// uninitialized.
+int a = a; // FIXME: This doesn't warn!? Seems it doesn't cast 'a' to an RValue.
+int b = b + 1; // expected-warning {{variable 'b' is uninitialized when used within its own initialization}}
+int c = (c + c); // expected-warning 2 {{variable 'c' is uninitialized when used within its own initialization}}
+void test() {
+ int d = ({ d + d ;}); // expected-warning 2 {{variable 'd' is uninitialized when used within its own initialization}}
+}
+int e = static_cast<long>(e) + 1; // expected-warning {{variable 'e' is uninitialized when used within its own initialization}}
+int f = foo(f); // expected-warning {{variable 'f' is uninitialized when used within its own initialization}}
+
+// Thes don't warn as they don't require the value.
+int g = sizeof(g);
+void* ptr = &ptr;
+int h = bar(&h);
+int i = boo(i);
+int j = far(j);
+int k = __alignof__(k);
+
+// Also test similar constructs in a field's initializer.
+struct S {
+ int x;
+ void *ptr;
+
+ S(bool (*)[1]) : x(x) {} // expected-warning {{field is uninitialized when used here}}
+ S(bool (*)[2]) : x(x + 1) {} // expected-warning {{field is uninitialized when used here}}
+ S(bool (*)[3]) : x(x + x) {} // expected-warning {{field is uninitialized when used here}}
+ S(bool (*)[4]) : x(static_cast<long>(x) + 1) {} // expected-warning {{field is uninitialized when used here}}
+ S(bool (*)[5]) : x(foo(x)) {} // FIXME: This should warn!
+
+ // These don't actually require the value of x and so shouldn't warn.
+ S(char (*)[1]) : x(sizeof(x)) {} // rdar://8610363
+ S(char (*)[2]) : ptr(&ptr) {}
+ S(char (*)[3]) : x(__alignof__(x)) {}
+ S(char (*)[4]) : x(bar(&x)) {}
+ S(char (*)[5]) : x(boo(x)) {}
+ S(char (*)[6]) : x(far(x)) {}
};