LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 20821 - clang-cl doesn't accept two implicit conversions with a smart pointer pattern in the same way that MSVC does
Summary: clang-cl doesn't accept two implicit conversions with a smart pointer pattern...
Status: RESOLVED WONTFIX
Alias: None
Product: clang
Classification: Unclassified
Component: C++ (show other bugs)
Version: trunk
Hardware: PC All
: P normal
Assignee: Unassigned Clang Bugs
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-08-31 10:30 PDT by Ehsan Akhgari [:ehsan]
Modified: 2014-09-02 11:08 PDT (History)
6 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ehsan Akhgari [:ehsan] 2014-08-31 10:30:50 PDT
$ cat test.cpp
template<class T>
struct SP {
  SP();
  SP(T*);
  void operator=(T*);
  operator T*();
};

struct B{};
struct D:B{};

void f() {
  SP<D> d;
  SP<B> b = d;
}

$ cl -c test.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 17.00.61030 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

test.cpp

$ clang-cl -c test.cpp
test.cpp(14,9) :  error: no viable conversion from 'SP<D>' to 'SP<B>'
  SP<B> b = d;
        ^   ~
test.cpp(2,8) :  note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'SP<D>' to 'const SP<B> &' for 1st
      argument
struct SP {
       ^
test.cpp(2,8) :  note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'SP<D>' to 'SP<B> &&' for 1st argument

struct SP {
       ^
test.cpp(4,3) :  note: candidate constructor not viable: no known conversion from 'SP<D>' to 'B *' for 1st argument
  SP(T*);
  ^
test.cpp(6,3) :  note: candidate function
  operator T*();
  ^
1 error generated.


It seems like MSVC first invokes SP::operator T*() and then invokes the ctor taking the T* from it, which requires another implicit conversion from D* to B*.  I don't think this is valid C++, but we may want to support it for compat with MSVC.
Comment 1 Hans Wennborg 2014-09-02 11:03:46 PDT
> It seems like MSVC first invokes SP::operator T*() and then invokes the ctor taking the T* from it, which requires another implicit conversion from D* to B*.  I don't think this is valid C++, but we may want to support it for compat with MSVC.

I'm surprised that they allow that (it seems to compile with the 14 CTP too). Unless we really can't avoid it, I don't think we should support this.



For smart pointers, I think the common thing to do is to provide templates for converting copy constructors and assignment operators, something like:

template <typename T> SP {
  ...
  template <typename U> SP(SP<U> other) { ... }
  template <typename U> void operator=(SP<U> other);
}



I'll mark this wontfix for now.
Comment 2 Ehsan Akhgari [:ehsan] 2014-09-02 11:08:15 PDT
Agreed on the wontfix, FWIW I fixed this issue on our side, just filed this so that we have a record of the issue!