Skip to content

security.ArrayBound FP caused by the lack of modeling narrowing casts #126884

@zufuliu

Description

@zufuliu

It has false positive for following code (online at https://godbolt.org/z/9v8P684rc):

struct Foo {
    unsigned char get(unsigned char ch) const {
        return s[ch];
    }
    unsigned char s[256];
};

int bar(const Foo &foo, const char *s) {
    int j = 0;
    if (s) {
        const unsigned char ch = s[j];
        j++;
        if (static_cast<signed char>(ch) >= 0) {
            // nop
        } else {
            j += foo.get(ch);
        }
    }
    return j;
}
<source>:3:16: warning: Out of bound access to memory preceding the field 's' [clang-analyzer-security.ArrayBound]
    3 |         return s[ch];
      |                ^
[<source>:10:9: note: Assuming 's' is non-null](javascript:;)
   10 |     if (s) {
      |         ^
[<source>:10:5: note: Taking true branch](javascript:;)
   10 |     if (s) {
      |     ^
[<source>:13:13: note: Assuming 'ch' is < 0](javascript:;)
   13 |         if (static_cast<signed char>(ch) >= 0) {
      |             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[<source>:13:9: note: Taking false branch](javascript:;)
   13 |         if (static_cast<signed char>(ch) >= 0) {
      |         ^
[<source>:16:18: note: Calling 'Foo::get'](javascript:;)
   16 |             j += foo.get(ch);
      |                  ^~~~~~~~~~~
[<source>:3:16: note: Access of the field 's' at negative byte offset](javascript:;)
    3 |         return s[ch];
      |                ^~~~~
1 warning generated.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions