Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Sema][CTAD] Allow user defined conversion for copy-list-initialization #94752

Merged
merged 5 commits into from
Jun 18, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion clang/include/clang/Sema/Initialization.h
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,7 @@ class InitializationKind {
/// Normal context
IC_Normal,

/// Normal context, but allows explicit conversion functionss
/// Normal context, but allows explicit conversion functions
IC_ExplicitConvs,

/// Implicit context (value initialization)
Expand Down
6 changes: 2 additions & 4 deletions clang/lib/Sema/SemaInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10892,8 +10892,6 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer(
// FIXME: The "second phase of [over.match.list] case can also
// theoretically happen here, but it's not clear whether we can
// ever have a parameter of the right type.
Comment on lines 10892 to 10894
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that comment still useful?

Copy link
Contributor Author

@spaits spaits Jun 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It wasn't useful (or at least I could definitely not understand why it was there) even when I was debugging to find the solution. Since I did not understand it I did not touch it.

What do you think, could we remove it?

bool SuppressUserConversions = Kind.isCopyInit();

if (TD) {
SmallVector<Expr *, 8> TmpInits;
for (Expr *E : Inits)
Expand All @@ -10903,12 +10901,12 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer(
TmpInits.push_back(E);
AddTemplateOverloadCandidate(
TD, FoundDecl, /*ExplicitArgs=*/nullptr, TmpInits, Candidates,
SuppressUserConversions,
/*SuppressUserConversions=*/false,
/*PartialOverloading=*/false, AllowExplicit, ADLCallKind::NotADL,
/*PO=*/{}, AllowAggregateDeductionCandidate);
} else {
AddOverloadCandidate(GD, FoundDecl, Inits, Candidates,
SuppressUserConversions,
/*SuppressUserConversions=*/false,
/*PartialOverloading=*/false, AllowExplicit);
}
};
Expand Down
90 changes: 90 additions & 0 deletions clang/test/SemaCXX/ctad-copy-init-list-narrowing.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// RUN: %clang_cc1 -fsyntax-only -verify -Wno-unused-value -std=c++20 %s
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: please format the test file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied clang format, nothing has really changed. I have changed the formatting by hand at some places.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, that's expected, we disable the clang-format for all lit test files (see the clang/test/.clang-format).

namespace std
{
typedef long unsigned int size_t;
}

namespace std
{
template<class _E>
class initializer_list
{
public:
typedef _E value_type;
typedef const _E& reference;
typedef const _E& const_reference;
typedef size_t size_type;
typedef const _E* iterator;
typedef const _E* const_iterator;

private:
iterator _M_array;
size_type _M_len;


constexpr initializer_list(const_iterator __a, size_type __l)
: _M_array(__a), _M_len(__l) { }

public:
constexpr initializer_list() noexcept
: _M_array(0), _M_len(0) { }


constexpr size_type
size() const noexcept { return _M_len; }


constexpr const_iterator
begin() const noexcept { return _M_array; }


constexpr const_iterator
end() const noexcept { return begin() + size(); }
};

template<class _Tp>
constexpr const _Tp*
begin(initializer_list<_Tp> __ils) noexcept
{ return __ils.begin(); }

template<class _Tp>
constexpr const _Tp*
end(initializer_list<_Tp> __ils) noexcept
{ return __ils.end(); }
}

template<class T, class Y>
class pair{
private:
T fst;
Y snd;
public:
pair(T f, Y s) : fst(f), snd(s) {}
};

template<class T, class Y>
class map {
public:
map(std::initializer_list<pair<T, Y>>, int a = 4, int b = 5) {}
};

template<class T, class Y>
class Contained {
public:
Contained(T, Y) {}
};

template<class T, class Y>
class A {
public:
A(std::initializer_list<Contained<T, Y> >, int) {}
};

int main() {
map mOk ={pair{5, 'a'}, {6, 'b'}, {7, 'c'}};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you try to simplify the test case a bit? There is so much boilerplate that it's hard to understand the issue.

map mNarrow ={pair{5, 'a'}, {6.0f, 'b'}, {7, 'c'}}; // expected-error {{type 'float' cannot be narrowed to 'int' in initializer list}} // expected-note {{insert an explicit cast to silence this issue}}

A aOk = {{Contained{5, 'c'}, {5, 'c'}}, 5};
A aNarrowNested = {{Contained{5, 'c'}, {5.0f, 'c'}}, 5}; // expected-error {{type 'float' cannot be narrowed to 'int' in initializer list}} // expected-note {{insert an explicit cast to silence this issue}}
A aNarrow = {{Contained{5, 'c'}, {5, 'c'}}, 5.0f}; // expected-error {{type 'float' cannot be narrowed to 'int' in initializer list}} // expected-note {{insert an explicit cast to silence this issue}}
}
Loading