Bug 425042 - False-positive "Field ... could not be resolved" when dereferencing struct members returned by std::vector::operator [].
Summary: False-positive "Field ... could not be resolved" when dereferencing struct me...
Status: NEW
Alias: None
Product: CDT
Classification: Tools
Component: cdt-codan (show other bugs)
Version: 8.2.1   Edit
Hardware: PC Windows 7
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: CDT Codan Inbox CLA
QA Contact: Elena Laskavaia CLA
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-01-07 12:37 EST by Dmitry Stepanov CLA
Modified: 2015-08-22 16:30 EDT (History)
4 users (show)

See Also:


Attachments
C++ code sample with demo of CODAN false-positive (470 bytes, text/plain)
2014-01-07 12:37 EST, Dmitry Stepanov CLA
no flags Details
Illustration of CODAN reporting the false-positive. (20.41 KB, image/png)
2014-01-07 12:38 EST, Dmitry Stepanov CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Dmitry Stepanov CLA 2014-01-07 12:37:22 EST
Created attachment 238749 [details]
C++ code sample with demo of CODAN false-positive

GCC toolchain 4.6.3.

Please refer to test.cpp (see attachments) for more details.

Specifically, CODAN reports false-positive "Field 'x' could not be resolved" on line 17 and line 25. Please pay attention that CODAN has nothing to say about line 20, which is using an identical operator[] call.
Comment 1 Dmitry Stepanov CLA 2014-01-07 12:38:54 EST
Created attachment 238750 [details]
Illustration of CODAN reporting the false-positive.
Comment 2 Nathan Ridge CLA 2014-01-23 02:51:47 EST
Confirmed. Note that the problem occurs with the standard library headers of GCC 4.6.3 headers, but not with the standard library headers of GCC 4.7 or later.

(In reply to Dmitry Stepanov from comment #0)
> Please pay attention that CODAN has nothing to say
> about line 20, which is using an identical operator[] call.

That's because the type of 'ref1' is explicitly declared on the previous line, so we don't need to evaluate the type of 'vec[0]' to determine which class to lookup 'x' in. In the other cases we do need to evaluate the type of 'vec[0]', and that's what we get wrong.
Comment 3 Nathan Ridge CLA 2014-01-23 03:08:49 EST
Looks like the 4.6 standard library expects __SIZE_TYPE__ to be defined as a builtin symbol.

Here's a reduced testcase that does not include any library headers:


template <typename T>
class vec
{
public:
    // Error: Type '__SIZE_TYPE__' could not be resolved.
    T& operator[](__SIZE_TYPE__);  
    T& front();
};

struct MyStruct
{
    int x;
    int y;
};

int main(int, char**)
{
    typedef vec<MyStruct> MyVector;

    MyVector vec;

    // Error: Field 'x' could not be resolved.
    vec[0].x = 5;

    // However, no objections here.
    MyStruct& ref1 = vec[0];
    ref1.x = 5;

    auto& ref2 = vec[0];
    // Error: Field 'x' could not be resolved.
    ref2.x = 5;

    vec.front().x = 10;

    return 0;
}
Comment 4 Nathan Ridge CLA 2014-01-23 03:21:52 EST
(In reply to Nathan Ridge from comment #3)
> Looks like the 4.6 standard library expects __SIZE_TYPE__ to be defined as a
> builtin symbol.

Looks like gcc 4.6 defines __SIZE_TYPE__ as a builtin macro:

$ gcc-4.6 -dM -E - < /dev/null | grep __SIZE_TYPE__
#define __SIZE_TYPE__ long unsigned int

I therefore think it should be picked up by scanner discovery (rather than, say, having to be hardcoded as a builtin in GCCBuiltinSymbolProvider). CC'ing Andrew.
Comment 5 Tim Martin CLA 2015-08-22 10:19:36 EDT
This doesn't seem to be a problem for me in the current mainline. Is it reasonable that something else might have changed to fix this?
Comment 6 Nathan Ridge CLA 2015-08-22 16:08:03 EDT
(In reply to Tim Martin from comment #5)
> This doesn't seem to be a problem for me in the current mainline. Is it
> reasonable that something else might have changed to fix this?

As per comment 2, the problem only occurs with gcc 4.6 headers, not gcc 4.7 or later.

Were you testing with gcc 4.6 headers?
Comment 7 Tim Martin CLA 2015-08-22 16:30:38 EDT
Ah, I'm using the wrong headers. Sorry for the noise.