Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 333287

Summary: Parser fails to deduce type in situation involving heavy template use (another one)
Product: [Tools] CDT Reporter: Nathan Ridge <zeratul976>
Component: cdt-indexerAssignee: Project Inbox <cdt-indexer-inbox>
Status: RESOLVED FIXED QA Contact: Markus Schorn <mschorn.eclipse>
Severity: normal    
Priority: P3 CC: cdtdoug, yevshif
Version: 8.1.0   
Target Milestone: ---   
Hardware: All   
OS: All   
Whiteboard:
Attachments:
Description Flags
source file that reproduces the error none

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).