]> granicus.if.org Git - clang/commitdiff
Add tests for the uninitialized checks added in r128376. Also clean up
authorChandler Carruth <chandlerc@gmail.com>
Sun, 27 Mar 2011 20:35:59 +0000 (20:35 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Sun, 27 Mar 2011 20:35:59 +0000 (20:35 +0000)
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

test/SemaCXX/uninitialized.cpp

index 26202fbccc8176a423a1d5670c1c6bf3c9a039bd..13ea9688efe95635f1ac7ee89d9eeeab8becf4f3 100644 (file)
@@ -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)) {}
 };