From: Chandler Carruth Date: Wed, 13 Apr 2011 08:18:42 +0000 (+0000) Subject: Teach -Wuninitialized about C++'s typeid expression, including both the X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=866849498461cf9022316034516475188b25955b;p=clang 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@129431 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/UninitializedValues.cpp b/lib/Analysis/UninitializedValues.cpp index d2eaff29ac..59a42813fc 100644 --- a/lib/Analysis/UninitializedValues.cpp +++ b/lib/Analysis/UninitializedValues.cpp @@ -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()) + if (cast(Record->getDecl())->isPolymorphic()) + Visit(E->getExprOperand()); + } +} + //------------------------------------------------------------------------====// // High-level "driver" logic for uninitialized values analysis. //====------------------------------------------------------------------------// diff --git a/test/SemaCXX/uninit-variables.cpp b/test/SemaCXX/uninit-variables.cpp index 9b8db6ff2c..a0180e3d3a 100644 --- a/test/SemaCXX/uninit-variables.cpp +++ b/test/SemaCXX/uninit-variables.cpp @@ -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();