From a41d9dd1f1bd88e022bc2f82987aeead497088c7 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Tue, 28 Jul 2009 20:46:55 +0000 Subject: [PATCH] Fix PR 4631. The compound initializers of unions were not being evaluated, which could cause false positives if any the subexpressions had side-effects. These initializers weren't evaluated because the StoreManager would need to handle them, but that's an orthogonal problem of whether or not the StoreManager can handle the binding. llvm-svn: 77361 --- clang/lib/Analysis/GRExprEngine.cpp | 10 ++-------- clang/test/Analysis/uninit-vals-ps.c | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/clang/lib/Analysis/GRExprEngine.cpp b/clang/lib/Analysis/GRExprEngine.cpp index eb31f84..ee8865b 100644 --- a/clang/lib/Analysis/GRExprEngine.cpp +++ b/clang/lib/Analysis/GRExprEngine.cpp @@ -2228,7 +2228,8 @@ void GRExprEngine::VisitInitListExpr(InitListExpr* E, NodeTy* Pred, QualType T = getContext().getCanonicalType(E->getType()); unsigned NumInitElements = E->getNumInits(); - if (T->isArrayType() || T->isStructureType()) { + if (T->isArrayType() || T->isStructureType() || + T->isUnionType() || T->isVectorType()) { llvm::ImmutableList StartVals = getBasicVals().getEmptySValList(); @@ -2283,13 +2284,6 @@ void GRExprEngine::VisitInitListExpr(InitListExpr* E, NodeTy* Pred, return; } - if (T->isUnionType() || T->isVectorType()) { - // FIXME: to be implemented. - // Note: That vectors can return true for T->isIntegerType() - MakeNode(Dst, E, Pred, state); - return; - } - if (Loc::IsLocType(T) || T->isIntegerType()) { assert (E->getNumInits() == 1); NodeSet Tmp; diff --git a/clang/test/Analysis/uninit-vals-ps.c b/clang/test/Analysis/uninit-vals-ps.c index 4482b13..5f402ee 100644 --- a/clang/test/Analysis/uninit-vals-ps.c +++ b/clang/test/Analysis/uninit-vals-ps.c @@ -102,3 +102,25 @@ int pr_4630(char *a, int y) { } } +// PR 4631 - False positive with union initializer +// Previously the analyzer didn't examine the compound initializers of unions, +// resulting in some false positives for initializers with side-effects. +union u_4631 { int a; }; +struct s_4631 { int a; }; +int pr4631_f2(int *p); +int pr4631_f3(void *q); +int pr4631_f1(void) +{ + int x; + union u_4631 m = { pr4631_f2(&x) }; + pr4631_f3(&m); // tell analyzer that we use m + return x; // no-warning +} +int pr4631_f1_b(void) +{ + int x; + struct s_4631 m = { pr4631_f2(&x) }; + pr4631_f3(&m); // tell analyzer that we use m + return x; // no-warning +} + -- 2.7.4