Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 333287 - Parser fails to deduce type in situation involving heavy template use (another one)
Summary: Parser fails to deduce type in situation involving heavy template use (anothe...
Status: RESOLVED FIXED
Alias: None
Product: CDT
Classification: Tools
Component: cdt-indexer (show other bugs)
Version: 8.1.0   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact: Markus Schorn CLA
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-12-29 01:04 EST by Nathan Ridge CLA
Modified: 2012-08-30 03:50 EDT (History)
2 users (show)

See Also:


Attachments
source file that reproduces the error (5.98 KB, application/octet-stream)
2010-12-29 01:04 EST, Nathan Ridge CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Nathan Ridge CLA 2010-12-29 01:04:49 EST
Created attachment 185868 [details]
source file that reproduces the error

For the code in the attached file, the parser gives an error at the call to
f(*iter) in main():

Invalid arguments Candidates are: void f(int)

It seems the parser is unable to deduce the type of *iter, even though there is a very plain

int operator*() const

in the base class of iter's type.

What seems to be confusing the parser is that the base class of iter's type has an (unused) template parameter which is instantiated with a rather complex type (called "messed_up_type" in the code).

The code in this example was reduced from code in boost and libstdc++.
Comment 1 Nathan Ridge CLA 2012-01-08 05:38:11 EST
Still an issue with latest Juno build. Reduced testcase:

template <typename From, typename To>
struct is_convertible
{
    typedef char one;
    typedef struct
    {
        char arr[2];
    } two;

    static one  test(To); 
    static two  test(...);

    static const bool value = sizeof(test(From())) == 1;
};

template <bool, bool>
struct minimum_category_impl;

template <>
struct minimum_category_impl<true, true>
{
    template <class T1, class T2> struct apply
    {
        typedef T1 type;
    };
};

template <class T1, class T2>
struct minimum_category
{
    typedef minimum_category_impl<
                is_convertible<T1, T2>::value,
                is_convertible<T2, T1>::value> outer;

    typedef typename outer::template apply<T1, T2> inner;
    typedef typename inner::type type;
};

template <typename>
class A {};

typedef typename minimum_category<int, int>::type messed_up_type;

typedef A<messed_up_type> type;  // ERROR HERE: 'Invalid template argumets'
Comment 2 Nathan Ridge CLA 2012-01-08 05:45:58 EST
This further reduced testcase may or may not be the same issue, I'm not sure:

template <typename From, typename To>
struct is_convertible
{
    typedef char one;
    typedef struct
    {
        char arr[2];
    } two;

    static one  test(To); 
    static two  test(...);

    static const bool value = sizeof(test(From())) == 1;
};

struct S {}; 
struct T {};

template <bool>
class B;

template <> struct B<false>
{
    typedef S type;
};

template <> struct B<true>
{
    typedef T type;
};

void f(T) {}

int main()
{
    B<is_convertible<int, int>::value>::type x;
    f(x);  // ERROR HERE: "Invalid arguments 'Candidates are: void f(T)'"
}
Comment 3 Nathan Ridge CLA 2012-08-30 03:50:06 EDT
This is fixed in the current master, probably by the fix to bug 299911 (since the implementation of is_convertible in the example used a dependent expression).