Missing deduction guide for aggregate causes crash in some contexts
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
The context needed to cause the crash is quite unstable, so I was not able to reduce the code as I wanted. The namespaces were necessary for example, but one the code was reduced, it could work. Even if you were not able to reproduce the crash, the key point is nonetheless the absence of deduction guide for the class _`integral_iterator`_, as the log crash suggested (thanks for the relevant names). I hope the log will suffice to you.
```
0 libsystem_kernel.dylib 0x7ff813182846 __pthread_kill + 10
1 libsystem_pthread.dylib 0x7ff8131bdb12 pthread_kill + 259
2 libsystem_c.dylib 0x7ff8130a10fa raise + 24
3 clang 0x104d40c32 SignalHandler(int, __siginfo*, void*) + 130
4 libsystem_platform.dylib 0x7ff8131f631d _sigtramp + 29
5 clang 0x103ec0001 clang::Stmt::getSourceRange() const + 1969
6 clang 0x1038e439f clang::Sema::**DeclareAggregateDeductionGuideFromInitList**(clang::TemplateDecl*, llvm::MutableArrayRef, clang::SourceLocation) + 431
7 clang 0x1036d5abc clang::Sema::DeduceTemplateSpecializationFromInitializer(clang::TypeSourceInfo*, clang::InitializedEntity const&, clang::InitializationKind
```
Notice that the fifth line (the one over **`DeclareAggregateDeductionGuideFromInitList`** ) may change, with even a strange mention of Microsoft!
```
5 clang 0x112060001 (anonymous namespace)::MicrosoftRecordLayoutBuilder::getAdjustedElementInfo(clang::ASTRecordLayout const&) + 97
5 clang 0x106870001 (anonymous namespace)::EmptySubobjectMap::CanPlaceBaseAtOffset((anonymous namespace)::BaseSubobjectInfo const*, clang::CharUnits) + 81
6 clang 0x11257e81b (anonymous namespace)::ConvertConstructorToDeductionGuideTransform::ConvertConstructorToDeductionGuideTransform(clang::Sema&, clang::ClassTemplateDecl*) + 91
5 clang 0x10cb40001 clang::analyze_scanf::ScanfSpecifier::fixType(clang::QualType, clang::QualType, clang::LangOptions const&, clang::ASTContext&) + 753
5 ??? 0x7ff7b22fe468 ???
5 clang 0x10a300001 clang::ASTContext::setNonKeyFunction(clang::CXXMethodDecl const*) + 145
5 clang 0x1084e0001 void std::__1::__insertion_sort_move[abi:nn200100](clang::CXXRecordDecl const**, clang::CXXRecordDecl const**, std::__1::iterator_traits::value_type*, DumpRecordLayout(llvm::raw_ostream&, clang::RecordDecl const*, clang::ASTContext const&, clang::CharUnits, unsigned int, char const*, bool, bool)::$_0&) + 753
5 clang 0x109800001 RequiresVtordisp(llvm::SmallPtrSetImpl const&, clang::CXXRecordDecl const*) + 1
...
```
Here is the code.
My guess:
In the following code the compiler is led to check for the concept `input_range` on the class _`integral_range`_, thus checking for begin and end returning an _`integral_iterator`_ that could be constructed with a missing deduction guide. If I add the guide, the issue disappears. The instabilities to get a crash and the logs seem to indicate a memory corruption.
```c++
template struct integral_iterator
{
I index;
integral_iterator operator++(int);
integral_iterator& operator++();
bool operator==(const integral_iterator&) const;
};
template struct integral_range
{
I _min;
I _max;
};
#if 1 // crash
// here are a use case for DeclareAggregateDeductionGuideFromInitList
template auto begin (const integral_range& r) { return integral_iterator{r._min};}
template auto end (const integral_range& r) { return integral_iterator{r._max+1};}
#else
template integral_iterator begin (const integral_range& r);
template integral_iterator end (const integral_range& r);
#endif
template struct A
{
template A(const AA&);
};
template using B = integral_range;
template void f(A); // overloaded function
template void f (const B&);
template void foo(const B& r) { return f(r);}
```
In fact, the code was in a more complex context of namespaces and structures, like this one:
```c++
namespace ZZ
{
template struct Case0
{
static void f(A);
static void f (const B&);
};
struct Case1 // ok
{
template static void f(A);
template static void f (const B&);
};
template void f(const B& r)
{
// return Case1::f(r);//ok (context!)
return Case0::f(r);
}
// template void f (const B&); //ok with this. (context!)
}
namespace AA
{
template void foo(const B& r) { return ZZ::f(r);}
template void f (const B&);
}
```
Contributor guide
Assessment
This issue has not been assessed yet.