From 00c93a10c3504b77dad4467766bfca3248defbfb Mon Sep 17 00:00:00 2001 From: Richard Trieu Date: Sat, 7 May 2011 01:36:37 +0000 Subject: [PATCH] Patch for PR 7409 - only error on definition of invalid typedefs. Suppress errors for additional uses of this invalid typedef. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@131043 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/TreeTransform.h | 10 +++++--- test/SemaTemplate/typename-specifier.cpp | 31 ++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index da60fccf7e..c45d02a56c 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -2568,9 +2568,13 @@ TreeTransform::TransformNestedNameSpecifierLoc( Q.getLocalEndLoc()); break; } - - SemaRef.Diag(TL.getBeginLoc(), diag::err_nested_name_spec_non_tag) - << TL.getType() << SS.getRange(); + // If the nested-name-specifier is an invalid type def, don't emit an + // error because a previous error should have already been emitted. + TypedefTypeLoc* TTL = dyn_cast(&TL); + if (!TTL || !TTL->getTypedefNameDecl()->isInvalidDecl()) { + SemaRef.Diag(TL.getBeginLoc(), diag::err_nested_name_spec_non_tag) + << TL.getType() << SS.getRange(); + } return NestedNameSpecifierLoc(); } } diff --git a/test/SemaTemplate/typename-specifier.cpp b/test/SemaTemplate/typename-specifier.cpp index 4c788f6a8a..7898a20d6e 100644 --- a/test/SemaTemplate/typename-specifier.cpp +++ b/test/SemaTemplate/typename-specifier.cpp @@ -71,3 +71,34 @@ struct C { ::Y::type ip7 = &i; ::Y::type ip8 = &i; // expected-note{{in instantiation of template class 'Y' requested here}} ::Y::type ip9 = &i; // expected-note{{in instantiation of template class 'Y' requested here}} + +template struct D { + typedef typename T::foo foo; // expected-error {{type 'long' cannot be used prior to '::' because it has no members}} + typedef typename foo::bar bar; +}; + +D struct_D; // expected-note {{in instantiation of template class 'D' requested here}} + +template struct E { + typedef typename T::foo foo; + typedef typename foo::bar bar; // expected-error {{type 'foo' (aka 'double') cannot be used prior to '::' because it has no members}} +}; + +struct F { + typedef double foo; +}; + +E struct_E; // expected-note {{in instantiation of template class 'E' requested here}} + +template struct G { + typedef typename T::foo foo; + typedef typename foo::bar bar; +}; + +struct H { + struct foo { + typedef double bar; + }; +}; + +G struct_G;