[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