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
This commit is contained in:
Chandler Carruth 2011-04-13 08:18:42 +00:00
parent 71c58f3d59
commit 0a7aa3b60b
2 changed files with 29 additions and 0 deletions

View 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.
//====------------------------------------------------------------------------//

View 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();