Description
namespace std {
template <class T> class initializer_list {};
}
template <typename T, int> class C {
public:
C(std::initializer_list<T>);
};
template <typename T> using Ptr =__remove_pointer(T) *;
template <typename T> C(T) -> C<Ptr<T>, sizeof(T)>;
class A {
public:
template <typename T1, typename T2>
T1 *some_func(T2 &&);
};
struct B : A {
int *ar = some_func<int>(C{some_func<int>(0)});
B() {}
};
I've debug in local. The crash issue caused by initializer rebuild failed in
llvm-project/clang/lib/Sema/SemaExpr.cpp
Lines 5717 to 5721 in 8e00703
SFINAETrap Trap(*this);
, we can got diagnostics like the following:
./main.cpp:23:28: error: no viable constructor or deduction guide for deduction of template arguments of 'C'
23 | int *ar = some_func<int>(C{some_func<int>(0)});
| ^
./main.cpp:6:34: note: candidate template ignored: couldn't infer template argument 'T'
6 | template <typename T, int> class C {
| ^
./main.cpp:8:3: note: candidate template ignored: couldn't infer template argument ''
8 | C(std::initializer_list<T>);
| ^
./main.cpp:12:24: note: candidate template ignored: couldn't infer template argument 'T'
12 | template <typename T> C(T) -> C<Ptr<T>, sizeof(T)>;
| ^
1 error generated.
But why does the check pass during Parse phase but fails when we rebuilding CXXDefaultInitExpr
? Through tracing, I found that the root cause was the parameter bool ListInitialization
that passed to RebuildCXXTemporaryObjectExpr
(fall throuth to Sema::BuildCXXTypeConstructExpr
). During parsing, ListInitialization
was true
, but it became false
during rebuilding, it's cause InitializationKind
to become DirectInit instead of DirectListInit. Finally, causing Sema::DeduceTemplateSpecializationFromInitializer
fail.
llvm-project/clang/lib/Sema/TreeTransform.h
Lines 14116 to 14121 in 8e00703
Therefore, I think the key to the problem is to fix TreeTransform.h:14116
's FIXME. As the comments in TreeTransform.h:14116
said, we should pass E->isListInitialization()
, because E
is actually list initialization, I have tried this modification, but it will cause 3 lit failures. We have not try to rebuild the CXXDefaultInitExpr
before this PR, so it's works fine before.