From 42b98e2a824a234c69b46fe26b87906a5eb198d5 Mon Sep 17 00:00:00 2001 From: Richard Trieu Date: Fri, 28 Oct 2016 00:15:24 +0000 Subject: [PATCH] Fix a crash on invalid code. The diagnostic was attempting to access the QualType of a TypeDecl by calling TypeDecl::getTypeForDecl. However, the Type pointer stored there is lazily loaded by functions in ASTContext. In most cases, the pointer is loaded and this does not cause a problem. However, when more that 50 or so unknown types are seen beforehand, this causes the Type to not be loaded, passing a null Type to the diagnostics, leading to the crash. Using ASTContext::getTypeDeclType will give a proper QualType for all cases. llvm-svn: 285370 --- clang/lib/Sema/SemaCXXScopeSpec.cpp | 2 +- clang/test/SemaCXX/nested-name-spec.cpp | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp b/clang/lib/Sema/SemaCXXScopeSpec.cpp index c350f6c..6c7d813 100644 --- a/clang/lib/Sema/SemaCXXScopeSpec.cpp +++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp @@ -801,7 +801,7 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S, if (!Found.empty()) { if (TypeDecl *TD = Found.getAsSingle()) Diag(IdInfo.IdentifierLoc, diag::err_expected_class_or_namespace) - << QualType(TD->getTypeForDecl(), 0) << getLangOpts().CPlusPlus; + << Context.getTypeDeclType(TD) << getLangOpts().CPlusPlus; else { Diag(IdInfo.IdentifierLoc, diag::err_expected_class_or_namespace) << IdInfo.Identifier << getLangOpts().CPlusPlus; diff --git a/clang/test/SemaCXX/nested-name-spec.cpp b/clang/test/SemaCXX/nested-name-spec.cpp index 0fbdedc..f445725 100644 --- a/clang/test/SemaCXX/nested-name-spec.cpp +++ b/clang/test/SemaCXX/nested-name-spec.cpp @@ -435,3 +435,21 @@ namespace PR16951 { // expected-error{{no member named 'X2' in 'PR16951::enumerator_2'}} } + +namespace PR30619 { +c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; +// expected-error@-1 16{{unknown type name 'c'}} +c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; +// expected-error@-1 16{{unknown type name 'c'}} +c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; +// expected-error@-1 16{{unknown type name 'c'}} +c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; +// expected-error@-1 16{{unknown type name 'c'}} +namespace A { +class B { + typedef C D; // expected-error{{unknown type name 'C'}} + A::D::F; + // expected-error@-1{{'D' (aka 'int') is not a class, namespace, or enumeration}} +}; +} +} -- 2.7.4