Mordante updated this revision to Diff 210128. Mordante marked an inline comment as done. Mordante retitled this revision from "Fixes a clang frontend assertion failure (bug 35682)" to "Fixes an assertion failure while instantiation a template with an incomplete typo corrected type". Mordante edited the summary of this revision. Mordante added a comment.
Fixes @lebedev.ri's remark and adds the requested test. While working on the test I discovered the initial assumption in bug 35682 was incorrect. Updated the title and summary accordingly. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D64644/new/ https://reviews.llvm.org/D64644 Files: clang/lib/Sema/SemaTemplate.cpp clang/test/SemaTemplate/instantiate-incomplete-typo-suggested-error-limit.cpp 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,47 @@ +// RUN: not %clang -fsyntax-only -std=c++11 -ferror-limit=1 %s 2>&1 | FileCheck %s + +// Test case to test the error in https://bugs.llvm.org/show_bug.cgi?id=35682. +// 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. + +#include <type_traits> +#include <utility> + +template <class T> +class allocator; + +template <class charT> +struct char_traits; + +template <class CharT, class Traits = char_traits<CharT>, + class Allocator = allocator<CharT>> +class basic_string; +typedef basic_string<char, char_traits<char>, allocator<char>> string; + +template <class T> +struct single { + typedef T first_type; + + T first; + + struct CheckArgs { + template <class U1> + static constexpr bool enable_implicit() { + return std::is_constructible<first_type, U1>::value; + } + }; + + template <class U1, + typename std::enable_if<CheckArgs::template enable_implicit<U1>(), + bool>::type = false> + single(U1 &&u1) : first(std::forward<U1>(u1)) {} +}; + +using SetKeyType = String; +single<SetKeyType> 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 Index: clang/lib/Sema/SemaTemplate.cpp =================================================================== --- clang/lib/Sema/SemaTemplate.cpp +++ clang/lib/Sema/SemaTemplate.cpp @@ -718,9 +718,14 @@ SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs) { + // DependentScopeDeclRefExpr::Create requires a valid QualifierLoc + // See https://bugs.llvm.org/show_bug.cgi?id=35682 + NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context); + if (!QualifierLoc) + return ExprError(); + return DependentScopeDeclRefExpr::Create( - Context, SS.getWithLocInContext(Context), TemplateKWLoc, NameInfo, - TemplateArgs); + Context, std::move(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,47 @@ +// RUN: not %clang -fsyntax-only -std=c++11 -ferror-limit=1 %s 2>&1 | FileCheck %s + +// Test case to test the error in https://bugs.llvm.org/show_bug.cgi?id=35682. +// 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. + +#include <type_traits> +#include <utility> + +template <class T> +class allocator; + +template <class charT> +struct char_traits; + +template <class CharT, class Traits = char_traits<CharT>, + class Allocator = allocator<CharT>> +class basic_string; +typedef basic_string<char, char_traits<char>, allocator<char>> string; + +template <class T> +struct single { + typedef T first_type; + + T first; + + struct CheckArgs { + template <class U1> + static constexpr bool enable_implicit() { + return std::is_constructible<first_type, U1>::value; + } + }; + + template <class U1, + typename std::enable_if<CheckArgs::template enable_implicit<U1>(), + bool>::type = false> + single(U1 &&u1) : first(std::forward<U1>(u1)) {} +}; + +using SetKeyType = String; +single<SetKeyType> 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 Index: clang/lib/Sema/SemaTemplate.cpp =================================================================== --- clang/lib/Sema/SemaTemplate.cpp +++ clang/lib/Sema/SemaTemplate.cpp @@ -718,9 +718,14 @@ SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs) { + // DependentScopeDeclRefExpr::Create requires a valid QualifierLoc + // See https://bugs.llvm.org/show_bug.cgi?id=35682 + NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context); + if (!QualifierLoc) + return ExprError(); + return DependentScopeDeclRefExpr::Create( - Context, SS.getWithLocInContext(Context), TemplateKWLoc, NameInfo, - TemplateArgs); + Context, std::move(QualifierLoc), TemplateKWLoc, NameInfo, TemplateArgs); }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits