I'll be the first to admit I'm not entirely confident that this fix is the
right one - but at the very least it's a starting point. It fixes the bug
and doesn't regress any other clang tests.
If there are things this change breaks, I'll be happy to add tests for those
cases & work on a fix that accommodates them, or if there's just a more
appropriate way to express the required semantics, I'm all ears.
[basically, members of local structs were being instantiated in the context
of their reference, not their definition, and failing because the Decl
corresponding to the template of the member wasn't in the context of the
instantiation scope (forEach in the attached example). By extending the
lifetime of the LocalInstantiationScope and walking up past uncombined
scopes in LocalInstantiationScope::findInstantiationOf it's now able to find
the relevant Decl & instantiate correctly]
Index: test/SemaCXX/PR9685.cpp
===================================================================
--- test/SemaCXX/PR9685.cpp (revision 0)
+++ test/SemaCXX/PR9685.cpp (revision 0)
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template <class Thing>
+void forEach(Thing t) {
+ struct Functor {
+ int i;
+ };
+ t.func();
+}
+
+template <typename T>
+void doIt() {
+ // This is the local class
+ struct Functor {
+ void func() {
+ (void)i;
+ }
+ int i;
+ };
+
+ forEach(Functor()); // expected-warning{{template argument uses local type 'Functor'}}
+}
+
+int main(int, char**) {
+ doIt<int>(); // expected-note{{in instantiation of function template specialization 'doIt<int>' requested here}}
+}
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiateDecl.cpp (revision 142336)
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp (working copy)
@@ -2540,7 +2540,6 @@
// This class may have local implicit instantiations that need to be
// instantiation within this scope.
PerformPendingInstantiations(/*LocalOnly=*/true);
- Scope.Exit();
if (Recursive) {
// Define any pending vtables.
Index: lib/Sema/SemaTemplateInstantiate.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiate.cpp (revision 142336)
+++ lib/Sema/SemaTemplateInstantiate.cpp (working copy)
@@ -2291,10 +2291,6 @@
else
CheckD = 0;
} while (CheckD);
-
- // If we aren't combined with our outer scope, we're done.
- if (!Current->CombineWithOuterScope)
- break;
}
// If we didn't find the decl, then we either have a sema bug, or we have a
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits