forked from OSchip/llvm-project
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:
parent
71c58f3d59
commit
0a7aa3b60b
|
@ -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.
|
||||
//====------------------------------------------------------------------------//
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue