An ill-formed C++ code snippet
Before the fix,
this following C++ snippet would crash Clang.
From the bug report,
we can see how a user might accidentally omit the function name when they meant to declare a member function on line 3.
To many people’s surprise, line 3 is actually parsed as a member variable declaration.
The parantheses are insignificant here unlike when declaring a pointer to function or array. So line 3 is essentially T A<T>{};.
The template parameter there is ill-formed and is handled by 942c03910aef.
Why crash?
The core of this problem is that the identifier part of the ill-formed member variable declaration is empty inside Clang’s AST,
when handling the default member initializer (the {} on line 3 of crash.cpp) inside clang::Sema::BuildCXXDefaultInitExpr.
Here’s an excerpt from clang::Sema::BuildCXXDefaultInitExpr.
The range-based for loop is never run as the Lookup is empty!
Pattern stays as nullptr.
This triggers an asssertion failure at
clang/lib/Sema/SemaDeclCXX.cpp:15540 if NDEBUG is not defined.
Otherwise, Pattern is accessed 😱 at
clang/lib/Sema/SemaDeclCXX.cpp:15542,
the bahavior of which is undefined 💣 💥.
clang::Sema::BuildCXXDefaultInitExpr is call stack #12 in the crash backtrace below:

The fix
Simply adding a line to set the identifier of an ill-formed declarator would suffice.

Now the name clash with the injected-class-name can also be correctly diagnosed as shown below 🎊 🙌 🎉:
