[cfe-commits] r121322 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaTemplate.cpp test/SemaTemplate/typename-specifier-4.cpp
Douglas Gregor
dgregor at apple.com
Wed Dec 8 16:06:27 PST 2010
Author: dgregor
Date: Wed Dec 8 18:06:27 2010
New Revision: 121322
URL: http://llvm.org/viewvc/llvm-project?rev=121322&view=rev
Log:
A typename specifier can end up referring to a unresolved using
declaration that is a value in ill-formed code. Instead of crashing,
treat this as a dependent typename specifier and suggest that the
using add "typename" into the using declaration. Fixes <rdar://problem/8740998>.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/test/SemaTemplate/typename-specifier-4.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=121322&r1=121321&r2=121322&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Dec 8 18:06:27 2010
@@ -1782,6 +1782,11 @@
"missing 'typename' prior to dependent type name '%0%1'">;
def ext_typename_outside_of_template : ExtWarn<
"'typename' occurs outside of a template">, InGroup<CXX0x>;
+def err_typename_refers_to_using_value_decl : Error<
+ "typename specifier refers to a dependent using declaration for a value "
+ "%0 in %1">;
+def note_using_value_decl_missing_typename : Note<
+ "add 'typename' to treat this using declaration as a type">;
def err_template_kw_refers_to_non_template : Error<
"%0 following the 'template' keyword does not refer to a template">;
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=121322&r1=121321&r2=121322&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Dec 8 18:06:27 2010
@@ -5699,6 +5699,23 @@
case LookupResult::NotFound:
DiagID = diag::err_typename_nested_not_found;
break;
+
+ case LookupResult::FoundUnresolvedValue: {
+ // We found a using declaration that is a value. Most likely, the using
+ // declaration itself is meant to have the 'typename' keyword.
+ SourceRange FullRange(KeywordLoc.isValid() ? KeywordLoc : NNSRange.getBegin(),
+ IILoc);
+ Diag(IILoc, diag::err_typename_refers_to_using_value_decl)
+ << Name << Ctx << FullRange;
+ if (UnresolvedUsingValueDecl *Using
+ = dyn_cast<UnresolvedUsingValueDecl>(Result.getRepresentativeDecl())){
+ SourceLocation Loc = Using->getTargetNestedNameRange().getBegin();
+ Diag(Loc, diag::note_using_value_decl_missing_typename)
+ << FixItHint::CreateInsertion(Loc, "typename ");
+ }
+ }
+ // Fall through to create a dependent typename type, from which we can recover
+ // better.
case LookupResult::NotFoundInCurrentInstantiation:
// Okay, it's a member of an unknown instantiation.
@@ -5716,7 +5733,7 @@
Referenced = Result.getFoundDecl();
break;
- case LookupResult::FoundUnresolvedValue:
+
llvm_unreachable("unresolved using decl in non-dependent context");
return QualType();
Modified: cfe/trunk/test/SemaTemplate/typename-specifier-4.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/typename-specifier-4.cpp?rev=121322&r1=121321&r2=121322&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/typename-specifier-4.cpp (original)
+++ cfe/trunk/test/SemaTemplate/typename-specifier-4.cpp Wed Dec 8 18:06:27 2010
@@ -134,3 +134,23 @@
template <typename T> typename T::Y::Z::W *S<T>::f() { }
template <typename T> typename T::template Y<int>::template Z<float>::template W<double> S<T>::g() { }
}
+
+namespace rdar8740998 {
+ template<typename T>
+ struct X : public T {
+ using T::iterator; // expected-note{{add 'typename' to treat this using declaration as a type}} \
+ // expected-error{{dependent using declaration resolved to type without 'typename'}}
+
+ void f() {
+ typename X<T>::iterator i; // expected-error{{typename specifier refers to a dependent using declaration for a value 'iterator' in 'X<T>'}}
+ }
+ };
+
+ struct HasIterator {
+ typedef int *iterator; // expected-note{{target of using declaration}}
+ };
+
+ void test_X(X<HasIterator> xi) { // expected-note{{in instantiation of template class}}
+ xi.f();
+ }
+}
More information about the cfe-commits
mailing list