Index: test/SemaCXX/uninitialized.cpp
===================================================================
--- test/SemaCXX/uninitialized.cpp	(revision 162493)
+++ test/SemaCXX/uninitialized.cpp	(working copy)
@@ -12,18 +12,20 @@
 int c = (c + c); // expected-warning 2 {{variable 'c' 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}}
+int g = boo(g);  // expected-warning{{variable 'g' is uninitialized when used within its own initialization}}
+int h = far(h);  // expected-warning{{variable 'h' is uninitialized when used within its own initialization}}
 
 // Thes don't warn as they don't require the value.
-int g = sizeof(g);
+int i = sizeof(i);
 void* ptr = &ptr;
-int h = bar(&h);
-int i = boo(i);
-int j = far(j);
+int j = bar(&j);
 int k = __alignof__(k);
 
 int l = k ? l : l;  // expected-warning 2{{variable 'l' is uninitialized when used within its own initialization}}
 int m = 1 + (k ? m : m);  // expected-warning 2{{variable 'm' is uninitialized when used within its own initialization}}
 int n = -n;  // expected-warning {{variable 'n' is uninitialized when used within its own initialization}}
+int o = foo(reinterpret_cast<int&>(o));  // expected-warning {{variable 'o' is uninitialized when used within its own initialization}}
+int p = reinterpret_cast<int&>(p) + 10;  // expected-warning {{variable 'p' is uninitialized when used within its own initialization}}
 
 void test_stuff () {
   int a = a; // no-warning: used to signal intended lack of initialization.
@@ -44,6 +46,8 @@
   int l = k ? l : l;  // FIXME: warn here
   int m = 1 + (k ? m : m);  // FIXME: warn here
   int n = -n;  // expected-warning {{variable 'n' is uninitialized when used within its own initialization}}
+  int o = foo(reinterpret_cast<int&>(o));  // expected-warning {{variable 'o' is uninitialized when used within its own initialization}}
+  int p = reinterpret_cast<int&>(p) + 10;  // expected-warning {{variable 'p' is uninitialized when used within its own initialization}}
 
   for (;;) {
     int a = a; // no-warning: used to signal intended lack of initialization.
@@ -64,6 +68,8 @@
     int l = k ? l : l;  // FIXME: warn here
     int m = 1 + (k ? m : m);  // FIXME: warn here
     int n = -n;  // expected-warning {{variable 'n' is uninitialized when used within its own initialization}}
+    int o = foo(reinterpret_cast<int&>(o));  // expected-warning {{variable 'o' is uninitialized when used within its own initialization}}
+    int p = reinterpret_cast<int&>(p) + 10;  // expected-warning {{variable 'p' is uninitialized when used within its own initialization}}
   }
 }
 
@@ -323,19 +329,21 @@
   static int c = (c + c); // expected-warning 2{{variable 'c' is uninitialized when used within its own initialization}}
   static int e = static_cast<long>(e) + 1; // expected-warning {{variable 'e' is uninitialized when used within its own initialization}}
   static int f = foo(f); // expected-warning {{variable 'f' is uninitialized when used within its own initialization}}
+  static int g = boo(g);  // expected-warning{{variable 'g' is uninitialized when used within its own initialization}}
+  static int h = far(h);  // expected-warning{{variable 'h' is uninitialized when used within its own initialization}}
 
   // Thes don't warn as they don't require the value.
-  static int g = sizeof(g);
-  int gg = g;  // Silence unneeded warning
+  static int i = sizeof(i);
+  int ii = i;  // Silence unneeded warning
   static void* ptr = &ptr;
-  static int h = bar(&h);
-  static int i = boo(i);
-  static int j = far(j);
+  static int j = bar(&j);
   static int k = __alignof__(k);
 
   static int l = k ? l : l;  // expected-warning 2{{variable 'l' is uninitialized when used within its own initialization}}
   static int m = 1 + (k ? m : m);  // expected-warning 2{{variable 'm' is uninitialized when used within its own initialization}}
   static int n = -n;  // expected-warning {{variable 'n' is uninitialized when used within its own initialization}}
+  static int o = foo(reinterpret_cast<int&>(o));  // expected-warning {{variable 'o' is uninitialized when used within its own initialization}}
+  static int p = reinterpret_cast<int&>(p) + 10;  // expected-warning {{variable 'p' is uninitialized when used within its own initialization}}
 
   void test() {
     static int a = a; // no-warning: used to signal intended lack of initialization.
@@ -344,18 +352,20 @@
     static int d = ({ d + d ;}); // expected-warning 2{{variable 'd' is uninitialized when used within its own initialization}}
     static int e = static_cast<long>(e) + 1; // expected-warning {{variable 'e' is uninitialized when used within its own initialization}}
     static int f = foo(f); // expected-warning {{variable 'f' is uninitialized when used within its own initialization}}
+    static int g = boo(g);  // expected-warning{{variable 'g' is uninitialized when used within its own initialization}}
+    static int h = far(h);  // expected-warning{{variable 'h' is uninitialized when used within its own initialization}}
 
     // Thes don't warn as they don't require the value.
-    static int g = sizeof(g);
+    static int i = sizeof(i);
     static void* ptr = &ptr;
-    static int h = bar(&h);
-    static int i = boo(i);
-    static int j = far(j);
+    static int j = bar(&j);
     static int k = __alignof__(k);
 
     static int l = k ? l : l;  // expected-warning 2{{variable 'l' is uninitialized when used within its own initialization}}
     static int m = 1 + (k ? m : m);  // expected-warning 2{{variable 'm' is uninitialized when used within its own initialization}}
     static int n = -n;  // expected-warning {{variable 'n' is uninitialized when used within its own initialization}}
+    static int o = foo(reinterpret_cast<int&>(o));  // expected-warning {{variable 'o' is uninitialized when used within its own initialization}}
+    static int p = reinterpret_cast<int&>(p) + 10;  // expected-warning {{variable 'p' is uninitialized when used within its own initialization}}
    for (;;) {
       static int a = a; // no-warning: used to signal intended lack of initialization.
       static int b = b + 1; // expected-warning {{variable 'b' is uninitialized when used within its own initialization}}
@@ -363,18 +373,20 @@
       static int d = ({ d + d ;}); // expected-warning 2{{variable 'd' is uninitialized when used within its own initialization}}
       static int e = static_cast<long>(e) + 1; // expected-warning {{variable 'e' is uninitialized when used within its own initialization}}
       static int f = foo(f); // expected-warning {{variable 'f' is uninitialized when used within its own initialization}}
+      static int g = boo(g);  // expected-warning{{variable 'g' is uninitialized when used within its own initialization}}
+      static int h = far(h);  // expected-warning{{variable 'h' is uninitialized when used within its own initialization}}
 
       // Thes don't warn as they don't require the value.
-      static int g = sizeof(g);
+      static int i = sizeof(i);
       static void* ptr = &ptr;
-      static int h = bar(&h);
-      static int i = boo(i);
-      static int j = far(j);
+      static int j = bar(&j);
       static int k = __alignof__(k);
 
       static int l = k ? l : l;  // expected-warning 2{{variable 'l' is uninitialized when used within its own initialization}}
       static int m = 1 + (k ? m : m); // expected-warning 2{{variable 'm' is uninitialized when used within its own initialization}}
       static int n = -n;  // expected-warning {{variable 'n' is uninitialized when used within its own initialization}}
+      static int o = foo(reinterpret_cast<int&>(o));  // expected-warning {{variable 'o' is uninitialized when used within its own initialization}}
+      static int p = reinterpret_cast<int&>(p) + 10;  // expected-warning {{variable 'p' is uninitialized when used within its own initialization}}
     }
   }
 }
@@ -397,3 +409,21 @@
     int &c = c; // FIXME: Warn here.
   };
 }
+
+class string {
+  public:
+    string();
+    string(const char*);
+    string(const string&);
+};
+string operator+(const string&, const string&);
+string test(string&);
+
+string StringA = "start " + StringA + " end";  // expected-warning {{variable 'StringA' is uninitialized when used within its own initialization}}
+const string StringB = "start " + StringB + " end";  // expected-warning {{variable 'StringB' is uninitialized when used within its own initialization}}
+string StringC = test(StringC);  // expected-warning {{variable 'StringC' is uninitialized when used within its own initialization}}
+void stringTest() {
+  string StringA = "start " + StringA + " end";  // expected-warning {{variable 'StringA' is uninitialized when used within its own initialization}}
+  const string StringB = "start " + StringB + " end";  // expected-warning {{variable 'StringB' is uninitialized when used within its own initialization}}
+  string StringC = test(StringC);  // expected-warning {{variable 'StringC' is uninitialized when used within its own initialization}}
+}
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp	(revision 162493)
+++ lib/Sema/SemaDecl.cpp	(working copy)
@@ -6224,7 +6224,7 @@
     // For conditional operators, the cast can be outside the conditional
     // operator if both expressions are DeclRefExpr's.
     void HandleValue(Expr *E) {
-      E = E->IgnoreParenImpCasts();
+      E = E->IgnoreParens();
       if (DeclRefExpr* DRE = dyn_cast<DeclRefExpr>(E)) {
         HandleDeclRefExpr(DRE);
         return;
@@ -6236,12 +6236,12 @@
       }
     }
 
-    void VisitImplicitCastExpr(ImplicitCastExpr *E) {
-      if ((!isRecordType && E->getCastKind() == CK_LValueToRValue) ||
-          (isRecordType && E->getCastKind() == CK_NoOp))
+    void VisitCastExpr(CastExpr *E) {
+      if (E->getCastKind() == CK_LValueToRValue ||
+          E->getCastKind() == CK_NoOp || E->getCastKind() == CK_LValueBitCast)
         HandleValue(E->getSubExpr());
 
-      Inherited::VisitImplicitCastExpr(E);
+      Inherited::VisitCastExpr(E);
     }
 
     void VisitMemberExpr(MemberExpr *E) {
@@ -6269,6 +6269,24 @@
 
     void VisitObjCMessageExpr(ObjCMessageExpr *E) { return; }
 
+    // Catch when variables are passed by reference to a fuction.
+    void VisitCallExpr(CallExpr *E) {
+      for (CallExpr::arg_iterator I = E->arg_begin(), End = E->arg_end();
+           I != End; ++I)
+        HandleValue(*I);
+
+      Inherited::VisitCallExpr(E);
+    }
+
+    void VisitCXXConstructExpr(CXXConstructExpr *E) {
+      for (CallExpr::arg_iterator I = E->arg_begin(), End = E->arg_end();
+           I != End; ++I)
+        HandleValue(*I);
+
+      Inherited::VisitCXXConstructExpr(E);
+    }
+
+
     void HandleDeclRefExpr(DeclRefExpr *DRE) {
       Decl* ReferenceDecl = DRE->getDecl(); 
       if (OrigDecl != ReferenceDecl) return;
