[cfe-commits] r108217 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaTemplate.cpp test/SemaTemplate/explicit-instantiation.cpp
Douglas Gregor
dgregor at apple.com
Mon Jul 12 17:10:05 PDT 2010
Author: dgregor
Date: Mon Jul 12 19:10:04 2010
New Revision: 108217
URL: http://llvm.org/viewvc/llvm-project?rev=108217&view=rev
Log:
Provide a special diagnostic for attempts to explicitly specialize
class templates within class scope (which is ill-formed), and recover
by dropping the explicit specialization entirely. Fixes the infinite
loop in PR7622.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/test/SemaTemplate/explicit-instantiation.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=108217&r1=108216&r2=108217&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Jul 12 19:10:04 2010
@@ -1575,6 +1575,8 @@
"explicit instantiation of non-templated type %0">;
def note_nontemplate_decl_here : Note<
"non-templated declaration is here">;
+def err_explicit_instantiation_in_class : Error<
+ "explicit instantiation of %0 in class scope">;
def err_explicit_instantiation_out_of_scope : Error<
"explicit instantiation of %0 not in a namespace enclosing %1">;
def err_explicit_instantiation_must_be_global : Error<
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=108217&r1=108216&r2=108217&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Mon Jul 12 19:10:04 2010
@@ -4549,13 +4549,21 @@
}
/// \brief Check the scope of an explicit instantiation.
-static void CheckExplicitInstantiationScope(Sema &S, NamedDecl *D,
+///
+/// \returns true if a serious error occurs, false otherwise.
+static bool CheckExplicitInstantiationScope(Sema &S, NamedDecl *D,
SourceLocation InstLoc,
bool WasQualifiedName) {
DeclContext *ExpectedContext
= D->getDeclContext()->getEnclosingNamespaceContext()->getLookupContext();
DeclContext *CurContext = S.CurContext->getLookupContext();
+ if (CurContext->isRecord()) {
+ S.Diag(InstLoc, diag::err_explicit_instantiation_in_class)
+ << D;
+ return true;
+ }
+
// C++0x [temp.explicit]p2:
// An explicit instantiation shall appear in an enclosing namespace of its
// template.
@@ -4576,7 +4584,7 @@
: diag::warn_explicit_instantiation_out_of_scope_0x)
<< D;
S.Diag(D->getLocation(), diag::note_explicit_instantiation_here);
- return;
+ return false;
}
// C++0x [temp.explicit]p2:
@@ -4585,10 +4593,10 @@
// its template is declared or, if that namespace is inline (7.3.1), any
// namespace from its enclosing namespace set.
if (WasQualifiedName)
- return;
+ return false;
if (CurContext->Equals(ExpectedContext))
- return;
+ return false;
S.Diag(InstLoc,
S.getLangOptions().CPlusPlus0x?
@@ -4596,6 +4604,7 @@
: diag::warn_explicit_instantiation_unqualified_wrong_namespace_0x)
<< D << ExpectedContext;
S.Diag(D->getLocation(), diag::note_explicit_instantiation_here);
+ return false;
}
/// \brief Determine whether the given scope specifier has a template-id in it.
@@ -4698,8 +4707,9 @@
// namespace of its template. [...]
//
// This is C++ DR 275.
- CheckExplicitInstantiationScope(*this, ClassTemplate, TemplateNameLoc,
- SS.isSet());
+ if (CheckExplicitInstantiationScope(*this, ClassTemplate, TemplateNameLoc,
+ SS.isSet()))
+ return true;
ClassTemplateSpecializationDecl *Specialization = 0;
Modified: cfe/trunk/test/SemaTemplate/explicit-instantiation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/explicit-instantiation.cpp?rev=108217&r1=108216&r2=108217&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/explicit-instantiation.cpp (original)
+++ cfe/trunk/test/SemaTemplate/explicit-instantiation.cpp Mon Jul 12 19:10:04 2010
@@ -83,3 +83,16 @@
void test1() { (void)&X0<1>::x; }
template struct X0<1>;
}
+
+namespace PR7622 { // expected-note{{to match this}}
+ template<typename,typename=int>
+ struct basic_streambuf;
+
+ // FIXME: Very poor recovery here.
+ template<typename,typename>
+ struct basic_streambuf{friend bob<>()}; // expected-error{{unknown type name 'bob'}} \
+ // expected-error{{ expected member name or ';' after declaration specifiers}}
+ template struct basic_streambuf<int>; // expected-error{{explicit instantiation of 'basic_streambuf' in class scope}}
+} // expected-error{{expected ';' after struct}}
+
+//expected-error{{expected '}'}}
More information about the cfe-commits
mailing list