Bug 50306 - ambiguous templated conversion operators accepted
Summary: ambiguous templated conversion operators accepted
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.6.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: accepts-invalid
Depends on:
Blocks:
 
Reported: 2011-09-06 17:14 UTC by Marc-Andre Laperle
Modified: 2021-12-20 12:17 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail: 4.4.1, 4.5.2, 4.6.1
Last reconfirmed: 2011-11-19 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Marc-Andre Laperle 2011-09-06 17:14:23 UTC
This code does not generate an error or warning:

class A{};
class B : public A {};

template <class T> class SmartPtr{
public:
    template<typename OtherT> operator const SmartPtr<OtherT>&() const;

    template<typename OtherT> operator SmartPtr<OtherT>() const;
};

void func(SmartPtr<A>) {
}

int main() {
    SmartPtr<B> b;
    func(b); // this should be ambiguous?
}

But it is an error with MSVC 10 and Clang 2.8.

If the templates on the operators are removed, it also becomes ambiguous with gcc:

class A {};
class B : public A {};

template <class T> class SmartPtr {
public:
    operator const SmartPtr<A>&() const;
    operator SmartPtr<A>() const;
};

void func(SmartPtr<A>) {
}

int main() {
    SmartPtr<B> b;
    func(b); // func is ambiguous
}
Comment 1 Marc-Andre Laperle 2011-11-17 18:00:27 UTC
I have never worked with the GCC source code before, any pointers to where I should start to look to fix this issue? Thanks!
Comment 2 Manuel López-Ibáñez 2011-11-17 18:27:00 UTC
(In reply to comment #1)
> I have never worked with the GCC source code before, any pointers to where I
> should start to look to fix this issue? Thanks!

http://gcc.gnu.org/wiki/DebuggingGCC

You could put a breakpoint for the second testcase in error(). Find out why the error triggers, and then find out what is the difference with the first testcase. In any case, the relevant code is in gcc/cp/. I hope you don't get scared by the looks. It ain't pretty.

However, this seems to be fixed in trunk (at least revision 180166):

manuel@gcc12:~$ ~/trunk/180166/build/gcc/cc1plus pr50306.cc
 void func(SmartPtr<A>) int main()
pr50306.cc:15:9: error: conversion from ‘SmartPtr<B>’ to ‘SmartPtr<A>’ is ambiguous
pr50306.cc:14:15: note: candidates are:
pr50306.cc:7:3: note: SmartPtr<T>::operator SmartPtr<A>() const [with T = B]
pr50306.cc:6:3: note: SmartPtr<T>::operator const SmartPtr<A>&() const [with T = B]
pr50306.cc:10:6: error:   initializing argument 1 of ‘void func(SmartPtr<A>)’

Maybe you should try 4.6.2?
Comment 3 Marc-Andre Laperle 2011-11-19 05:38:32 UTC
I tried 4.6.2, r181503 and r180166 and they all compiled the sample code without error. Do you have any local changes or special parameters that made it not compile?
Comment 4 Paolo Carlini 2011-11-19 12:11:05 UTC
Yes, I confirm the issue doesn't seem fixed neither mainline nor 4_6-branch.
Comment 5 Manuel López-Ibáñez 2011-11-19 12:46:13 UTC
You are right, it seems I tested the second example by mistake.