[cfe-commits] r161051 - in /cfe/trunk: lib/StaticAnalyzer/Core/ExprEngine.cpp test/Analysis/reference.cpp
Anna Zaks
ganna at apple.com
Tue Jul 31 19:19:04 PDT 2012
On Jul 31, 2012, at 9:34 AM, Jordan Rose wrote:
> Author: jrose
> Date: Tue Jul 31 11:34:07 2012
> New Revision: 161051
>
> URL: http://llvm.org/viewvc/llvm-project?rev=161051&view=rev
> Log:
> [analyzer] Getting an lvalue for a reference field still requires a load.
>
> This was causing a crash in our array-to-pointer logic, since the region
> was clearly not an array.
>
> PR13440 / <rdar://problem/11977113>
>
> Modified:
> cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
> cfe/trunk/test/Analysis/reference.cpp
>
> Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=161051&r1=161050&r2=161051&view=diff
> ==============================================================================
> --- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
> +++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Tue Jul 31 11:34:07 2012
> @@ -1522,10 +1522,17 @@
>
> // For all other cases, compute an lvalue.
> SVal L = state->getLValue(field, baseExprVal);
> - if (M->isGLValue())
> + if (M->isGLValue()) {
> + if (field->getType()->isReferenceType()) {
> + if (const MemRegion *R = L.getAsRegion())
> + L = state->getSVal(R);
> + else
> + L = UnknownVal();
> + }
This could be factored out somewhere. There other places where we add same special handling of references. Ex in the same source file:
// For references, the 'lvalue' is the pointer address stored in the
// reference region.
if (VD->getType()->isReferenceType()) {
if (const MemRegion *R = V.getAsRegion())
V = state->getSVal(R);
else
V = UnknownVal();
}
> +
> Bldr.generateNode(M, Pred, state->BindExpr(M, LCtx, L), false, 0,
> ProgramPoint::PostLValueKind);
> - else {
> + } else {
> Bldr.takeNodes(Pred);
> evalLoad(Dst, M, M, Pred, state, L);
> Bldr.addNodes(Dst);
>
> Modified: cfe/trunk/test/Analysis/reference.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/reference.cpp?rev=161051&r1=161050&r2=161051&view=diff
> ==============================================================================
> --- cfe/trunk/test/Analysis/reference.cpp (original)
> +++ cfe/trunk/test/Analysis/reference.cpp Tue Jul 31 11:34:07 2012
> @@ -1,4 +1,6 @@
> -// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -analyzer-store=region -analyzer-constraints=range -verify -Wno-null-dereference %s
> +// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core,debug.ExprInspection -analyzer-store=region -analyzer-constraints=range -verify -Wno-null-dereference %s
> +
> +void clang_analyzer_eval(bool);
>
> typedef typeof(sizeof(int)) size_t;
> void malloc (size_t);
> @@ -55,3 +57,36 @@
> if (*p) return *p;
> return *(char*)0; // no-warning
> }
> +
> +
> +// PR13440 / <rdar://problem/11977113>
> +// Test that the array-to-pointer decay works for array references as well.
> +// More generally, when we want an lvalue for a reference field, we still need
> +// to do one level of load.
> +namespace PR13440 {
> + typedef int T[1];
> + struct S {
> + T &x;
> +
> + int *m() { return x; }
> + };
> +
> + struct S2 {
> + int (&x)[1];
> +
> + int *m() { return x; }
> + };
> +
> + void test() {
> + int a[1];
> + S s = { a };
> + S2 s2 = { a };
> +
> + if (s.x != a) return;
> + if (s2.x != a) return;
> +
> + a[0] = 42;
> + clang_analyzer_eval(s.x[0] == 42); // expected-warning{{TRUE}}
> + clang_analyzer_eval(s2.x[0] == 42); // expected-warning{{TRUE}}
> + }
> +}
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20120731/cac349ce/attachment.html>
More information about the cfe-commits
mailing list