Teach -Wuninitialized about C++'s typeid expression, including both the
evaluated and unevaluated contexts. Add some testing of sizeof and
typeid.

Both of the typeid tests added here were triggering warnings previously.
Now the one false positive is suppressed without suppressing the warning
on actually buggy code.

llvm-svn: 129431
diff --git a/clang/lib/Analysis/UninitializedValues.cpp b/clang/lib/Analysis/UninitializedValues.cpp
index d2eaff2..59a4281 100644
--- a/clang/lib/Analysis/UninitializedValues.cpp
+++ b/clang/lib/Analysis/UninitializedValues.cpp
@@ -390,6 +390,7 @@
   void VisitBinaryOperator(BinaryOperator *bo);
   void VisitCastExpr(CastExpr *ce);
   void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *se);
+  void VisitCXXTypeidExpr(CXXTypeidExpr *E);
   void BlockStmt_VisitObjCForCollectionStmt(ObjCForCollectionStmt *fs);
   
   bool isTrackedVar(const VarDecl *vd) {
@@ -618,6 +619,17 @@
   }
 }
 
+void TransferFunctions::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
+  // typeid(expression) is potentially evaluated when the argument is
+  // a glvalue of polymorphic type. (C++ 5.2.8p2-3)
+  if (!E->isTypeOperand() && E->Classify(ac.getASTContext()).isGLValue()) {
+    QualType SubExprTy = E->getExprOperand()->getType();
+    if (const RecordType *Record = SubExprTy->getAs<RecordType>())
+      if (cast<CXXRecordDecl>(Record->getDecl())->isPolymorphic())
+        Visit(E->getExprOperand());
+  }
+}
+
 //------------------------------------------------------------------------====//
 // High-level "driver" logic for uninitialized values analysis.
 //====------------------------------------------------------------------------//