[llvm-bugs] [Bug 40814] New: False positive due to truncation of constant when comparing against non-default AS pointer

via llvm-bugs llvm-bugs at lists.llvm.org
Fri Feb 22 00:45:12 PST 2019


https://bugs.llvm.org/show_bug.cgi?id=40814

            Bug ID: 40814
           Summary: False positive due to truncation of constant when
                    comparing against non-default AS pointer
           Product: clang
           Version: trunk
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: Static Analyzer
          Assignee: dcoughlin at apple.com
          Reporter: david.stenberg at ericsson.com
                CC: dcoughlin at apple.com, llvm-bugs at lists.llvm.org

Seen on r354452.

When running:

    $ clang --target=amdgcn --analyze ptr-cmp.cl

on the following test case:

    #include <stdint.h>

    void bar(__global int *p) __attribute__((nonnull(1)));

    void foo(__global int *p) {
      if ((uint64_t)p <= 1UL << 32)
        bar(p);
    }

you get a warning for the call to bar():

    ptr-cmp.cl:7:5: warning: Null pointer passed as an argument to a 'nonnull'
parameter
        bar(p);
        ^~~~~~

which I think is a false positive. If you change the constant so that any of
its lower 32 bits are set, you don't get a warning. Same goes if you change the
comparison to a less-than operation.

I'm not very well-versed with the analyzer codebase, but as far as I can tell
the issue here seems to be that in SimpleSValBuilder::evalBinOpNN() the
right-hand side is converted to a void pointer for the default address space,
rather than the left-hand side's address space:

    case nonloc::ConcreteIntKind: {
      // FIXME: at the moment the implementation
      // of modeling "pointers as integers" is not complete.
      if (!BinaryOperator::isComparisonOp(op))
        return UnknownVal();
      // Transform the integer into a location and compare.
      // FIXME: This only makes sense for comparisons. If we want to, say,
      // add 1 to a LocAsInteger, we'd better unpack the Loc and add to it,
      // then pack it back into a LocAsInteger.
      llvm::APSInt i = rhs.castAs<nonloc::ConcreteInt>().getValue();
      BasicVals.getAPSIntType(Context.VoidPtrTy).apply(i);
<---------------------
      return evalBinOpLL(state, op, lhsL, makeLoc(i), resultTy);

which in this case means that the constant is truncated from 8 to 4 bytes, so
we get ((uint64_t)p <= 0U) instead.

This can be seen by dumping the state afterwards in
ExprEngine::VisitBinaryOperator():

    Store (direct and default bindings), 0x0 :

    Expressions by stack frame:
    #0 Calling foo
    (LC1, S1356) p : &p
    (LC1, S1370) p : &SymRegion{reg_$0<__global int * p>}
    (LC1, S1373) (uint64_t)p : &SymRegion{reg_$0<__global int * p>} [as 128 bit
integer]
    (LC1, S1386) 1UL << 32 : 4294967296 U64b
    (LC1, S1390) 1UL << 32 : 4294967296 U128b
    (LC1, S1393) (uint64_t)p <= 1UL << 32 : (reg_$0<__global int * p>) <= 0U
<--------------------------

    Ranges are empty.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20190222/09de6735/attachment.html>


More information about the llvm-bugs mailing list