Index: clang/lib/Sema/SemaTemplate.cpp =================================================================== --- clang/lib/Sema/SemaTemplate.cpp +++ clang/lib/Sema/SemaTemplate.cpp @@ -718,9 +718,13 @@ SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs) { + // DependentScopeDeclRefExpr::Create requires a valid QualifierLoc + NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context); + if (!QualifierLoc) + return ExprError(); + return DependentScopeDeclRefExpr::Create( - Context, SS.getWithLocInContext(Context), TemplateKWLoc, NameInfo, - TemplateArgs); + Context, QualifierLoc, TemplateKWLoc, NameInfo, TemplateArgs); } Index: clang/test/SemaTemplate/instantiate-incomplete-typo-suggested-error-limit.cpp =================================================================== --- /dev/null +++ clang/test/SemaTemplate/instantiate-incomplete-typo-suggested-error-limit.cpp @@ -0,0 +1,60 @@ +// RUN: not %clang -fsyntax-only -std=c++11 -ferror-limit=1 %s 2>&1 | FileCheck %s + +// Test case for PR35682. +// The issue be caused by the typo correction that changes String to the +// incomplete type string. The example is based on the std::pair code and +// reduced to a minimal test case. When using std::pair the issue can only be +// reproduced when using the -stdlib=libc++ compiler option. + +template class allocator; + +template struct char_traits; + +template , + class Allocator = allocator> +class basic_string; +typedef basic_string, allocator> string; + +template struct enable_if {}; +template struct enable_if { typedef Tp type; }; + +template struct integral_constant { + static constexpr const Tp value = v; + typedef Tp value_type; + typedef integral_constant type; + + constexpr operator value_type() const noexcept { return value; } + constexpr value_type operator()() const noexcept { return value; } +}; + +template constexpr const Tp integral_constant::value; + +using true_type = integral_constant; +using false_type = integral_constant; + +template struct is_same : public false_type {}; +template struct is_same : public true_type {}; + +template struct single { + typedef T first_type; + + T first; + + struct CheckArgs { + template static constexpr bool enable_implicit() { + return is_same::value; + } + }; + + template (), + bool>::type = false> + single(U1 &&u1); +}; + +using SetKeyType = String; +single v; + +// CHECK: error: unknown type name 'String'; did you mean 'string'? +// CHECK: fatal error: too many errors emitted, stopping now [-ferror-limit=] +// CHECK-NOT: Assertion{{.*}}failed