From: Ted Kremenek Date: Tue, 28 Jul 2009 20:46:55 +0000 (+0000) Subject: Fix PR 4631. The compound initializers of unions were not being evaluated, which X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f3bfa21565b8145afe9b4886770257e890b0b68d;p=clang 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@77361 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index eb31f84b0c..ee8865b635 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/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/test/Analysis/uninit-vals-ps.c b/test/Analysis/uninit-vals-ps.c index 4482b13236..5f402eee35 100644 --- a/test/Analysis/uninit-vals-ps.c +++ b/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 +} +