Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 349849 - Code analysis "Invalid Argument" reports invalid argument which is valid
Summary: Code analysis "Invalid Argument" reports invalid argument which is valid
Status: RESOLVED WONTFIX
Alias: None
Product: CDT
Classification: Tools
Component: cdt-parser (show other bugs)
Version: 8.0   Edit
Hardware: PC Linux
: P3 normal with 2 votes (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact: Markus Schorn CLA
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-06-20 12:16 EDT by Kocka Mising name CLA
Modified: 2018-02-18 15:32 EST (History)
7 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Kocka Mising name CLA 2011-06-20 12:16:28 EDT
In the following example "result.push_back(*it);" Is marked with "Invalid
Argument" by Code analysis.

#include <iostream>
#include <vector>
#include <boost/tokenizer.hpp>
#include <string>
using namespace std;
using namespace boost;

int main() {
    vector<string> result;
    string temp;
    tokenizer<> tokens(temp);
    for (tokenizer<>::const_iterator it = tokens.begin(); tokens.end() != it;
++it) {
        result.push_back(*it);
    }
    return (0);
}


I have already posted this, but I think It is in wrong place:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=348170
Comment 1 Elena Laskavaia CLA 2011-06-20 18:10:32 EDT
Is there problem with parsing headers? If you remove boost headers still reproduciable?
Comment 2 Tomasz Wesolowski CLA 2011-06-20 18:46:46 EDT
This is a Codan marker generated by the problem binding which is created by the Parser, I suggest changing component to cdt-parser.

Btw- quite strange, as the type of the IASTExpression `*it` itself seems to be correctly deduced.
Comment 3 Markus Schorn CLA 2011-06-29 09:57:48 EDT
The root cause seems to be an error in parsing boost::iterator_traversal.
Comment 4 Adam Paetznick CLA 2013-05-01 11:40:56 EDT
The following simple example reproduces the problem.

#include <vector>
#include <list>

int main() {
  std::vector<int> vec_foo = { 1 };
  std::vector<int> vec_bar;
  std::list<int> list_foo = { 1 };
  std::list<int> list_bar;
  list_bar.push_back(list_foo.front());
  vec_bar.push_back(list_foo.front());
  list_bar.push_back(vec_foo[0]);
  vec_bar.push_back(vec_foo[0]);
  return 0;
}

On lines 11 & 12 (i.e. "list_bar.push_back(vec_foo[0]);" and "vec_bar.push_back(vec_foo[0]);") CDT reports:
Invalid arguments 'Candidates are:
void push_back(const int &)
void push_back(int &&)
'.
However, "g++ -std=c++11" compiles cleanly.


Note that CDT does *not* complain about lines 9 & 10.  It seems that the return value of vec_foo[0] is not being parsed correctly.  Note also that replacing with vec_foo.at(0) has no effect.

I am using CDT 8.1 (Ubuntu 13.04 eclipse-cdt-8.1.0+dfsg-2).
Comment 5 Adam Paetznick CLA 2013-05-01 12:04:03 EDT
I found that the problem goes away for the example above if c++11 support is disabled.  That is, when I remove "-std=c++11" from the CDT GCC Builtin Compiler Settings in C/C++ General->Preprocessor Includes->Providers and rebuild the index, the error is no longer reported.
Of course, this doesn't do much good if the project requires c++11 support.
Comment 6 Nathan Ridge CLA 2013-12-15 15:19:56 EST
Adam, do you still have this problem with CDT 8.2 (Kepler)? Both of the examples posted here work fine for me.
Comment 7 Doug Glidden CLA 2014-03-18 11:35:53 EDT
With CDT 8.3, Adam's sample is no longer exhibiting this error.  However, the following sample does exhibit the error:

#include <list>

int main()
{
  std::list< int > list_foo;
  std::list< int > list_bar;

  list_foo.splice( list_foo.end(), list_bar );

  return 0;
}

As Adam previously described, the issue only appears when C++11 (C++0x on older versions of GCC) support is enabled, which leads me to believe Eclipse's parser is not correctly interpreting rvalue references, since the change of the second parameter from an lvalue reference (std::list& __x) to an rvalue reference (std::list&& x) is the only difference in this function when C++11 is enabled.
Comment 8 Nathan Ridge CLA 2014-03-19 00:04:56 EDT
(In reply to Doug Glidden from comment #7)
> With CDT 8.3, Adam's sample is no longer exhibiting this error.  However,
> the following sample does exhibit the error:
> 
> #include <list>
> 
> int main()
> {
>   std::list< int > list_foo;
>   std::list< int > list_bar;
> 
>   list_foo.splice( list_foo.end(), list_bar );
> 
>   return 0;
> }
> 
> As Adam previously described, the issue only appears when C++11 (C++0x on
> older versions of GCC) support is enabled, which leads me to believe
> Eclipse's parser is not correctly interpreting rvalue references, since the
> change of the second parameter from an lvalue reference (std::list& __x) to
> an rvalue reference (std::list&& x) is the only difference in this function
> when C++11 is enabled.

I do not get any errors for this example. Note that in my standard library's <list> header, there are two overloads of splice(), one which takes an lvalue reference as the second argument, and one which takes an rvalue reference, and the call in this example matches the lvalue reference one (as evidenced by 'Open Declaration' on 'splice' in the example taking me to that one).

What compiler version are you using?
Comment 9 Doug Glidden CLA 2014-03-19 08:38:33 EDT
(In reply to Nathan Ridge from comment #8)
> I do not get any errors for this example. Note that in my standard library's
> <list> header, there are two overloads of splice(), one which takes an
> lvalue reference as the second argument, and one which takes an rvalue
> reference, and the call in this example matches the lvalue reference one (as
> evidenced by 'Open Declaration' on 'splice' in the example taking me to that
> one).
> 
> What compiler version are you using?

I am using GCC 4.4.7 (I know it's old, but it's the version included with RedHat/CentOS 6.4 Final, so I'm stuck with it).  My <list> header also includes both of those definitions of splice(), but they are #ifdef-ed to ensure that only one or the other will exist; when C++0x support is enabled, only the rvalue version is defined; otherwise, only the lvalue version is defined.  The final C++11 standard definitely indicates that both versions should be defined, but GCC 4.4.7 was based on a preliminary version of the standard that was, shall we say, incomplete.  It's curious that GCC has no problem compiling the code, but after a little reading, I think Eclipse is probably technically correct, at least according to the final C++11 spec.  In any case, explicitly casting the argument to an rvalue (i.e. (std::list< int >&&) list_bar) works around the problem.
Comment 10 Nathan Ridge CLA 2014-03-20 00:32:59 EDT
(In reply to Doug Glidden from comment #9)
> (In reply to Nathan Ridge from comment #8)
> > I do not get any errors for this example. Note that in my standard library's
> > <list> header, there are two overloads of splice(), one which takes an
> > lvalue reference as the second argument, and one which takes an rvalue
> > reference, and the call in this example matches the lvalue reference one (as
> > evidenced by 'Open Declaration' on 'splice' in the example taking me to that
> > one).
> > 
> > What compiler version are you using?
> 
> I am using GCC 4.4.7 (I know it's old, but it's the version included with
> RedHat/CentOS 6.4 Final, so I'm stuck with it).  My <list> header also
> includes both of those definitions of splice(), but they are #ifdef-ed to
> ensure that only one or the other will exist; when C++0x support is enabled,
> only the rvalue version is defined; otherwise, only the lvalue version is
> defined.  The final C++11 standard definitely indicates that both versions
> should be defined, but GCC 4.4.7 was based on a preliminary version of the
> standard that was, shall we say, incomplete.  It's curious that GCC has no
> problem compiling the code, but after a little reading, I think Eclipse is
> probably technically correct, at least according to the final C++11 spec. 
> In any case, explicitly casting the argument to an rvalue (i.e. (std::list<
> int >&&) list_bar) works around the problem.

GCC 4.4 was released in 2009, 2 years before the C++11 standard was finalized. At the time, an rvalue reference was allowed to bind to an lvalue; this was then changed to be disallowed in the final version of the standard.

GCC labels its C++11 support as experimental, and makes it clear that they make no attempt to maintain backward compatibility with earlier versions that implement earlier drafts of a feature proposal [1]. Therefore I do not see much motivation in having Eclipse support such older C++11 feature variants, either. If someone does care to implement such an option in Eclipse, I imagine we would accept patches.

[1] http://gcc.gnu.org/projects/cxx0x.html
Comment 11 Nathan Ridge CLA 2018-02-18 15:32:53 EST
(In reply to Nathan Ridge from comment #10)
> GCC 4.4 was released in 2009, 2 years before the C++11 standard was
> finalized. At the time, an rvalue reference was allowed to bind to an
> lvalue; this was then changed to be disallowed in the final version of the
> standard.
> 
> GCC labels its C++11 support as experimental, and makes it clear that they
> make no attempt to maintain backward compatibility with earlier versions
> that implement earlier drafts of a feature proposal [1]. Therefore I do not
> see much motivation in having Eclipse support such older C++11 feature
> variants, either. If someone does care to implement such an option in
> Eclipse, I imagine we would accept patches.

It's now been 4 years since I wrote this, GCC 4.4 has been unsupported for several years, and the older variant of C++0x rvalue references that it implemented is becoming more and more irrelevant as time passes. I think it's safe to close this bug as WONTFIX.