]> granicus.if.org Git - clang/commitdiff
Teach -Wuninitialized about C++'s typeid expression, including both the
authorChandler Carruth <chandlerc@gmail.com>
Wed, 13 Apr 2011 08:18:42 +0000 (08:18 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Wed, 13 Apr 2011 08:18:42 +0000 (08:18 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@129431 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/UninitializedValues.cpp
test/SemaCXX/uninit-variables.cpp

index d2eaff29ac7ca3f7094eac42a7f6d46180b40d97..59a42813fc55144d9b7c05a611e4eb924ab9b08c 100644 (file)
@@ -390,6 +390,7 @@ public:
   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::VisitUnaryExprOrTypeTraitExpr(
   }
 }
 
+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.
 //====------------------------------------------------------------------------//
index 9b8db6ff2cf18d4029276f1bb4fe3e4f58c98ffb..a0180e3d3a1507be55350995bca23dd917db1393 100644 (file)
@@ -1,5 +1,8 @@
 // RUN: %clang_cc1 -fsyntax-only -Wuninitialized -fsyntax-only -fcxx-exceptions %s -verify
 
+// Stub out types for 'typeid' to work.
+namespace std { class type_info {}; }
+
 int test1_aux(int &x);
 int test1() {
   int x;
@@ -13,6 +16,20 @@ int test2_aux() {
   return x; // no-warning
 }
 
+// Don't warn on unevaluated contexts.
+void unevaluated_tests() {
+  int x;
+  (void)sizeof(x);
+  (void)typeid(x);
+}
+
+// Warn for glvalue arguments to typeid whose type is polymorphic.
+struct A { virtual ~A() {} };
+void polymorphic_test() {
+  A *a; // expected-note{{declared here}} expected-note{{add initialization}}
+  (void)typeid(*a); // expected-warning{{variable 'a' is uninitialized when used here }}
+}
+
 // Handle cases where the CFG may constant fold some branches, thus
 // mitigating the need for some path-sensitivity in the analysis.
 unsigned test3_aux();