Hi Richard,

I forgot about this for long time but I had a chance this weekend to
revisit it.

I've added the part to save and restore the pending local instantiations
around the calls to instantiate the class body and its members. But I'm
uncertain whether we need/want the vtable related code here since I don't
think we actually have a way to use the vtable in this context. It also
seems that we don't need an instance of *LocalInstantiationScope* here
since we don't have any template parameters to store at this level.

Sorry for the delay in the follow-up, once I get feedback from you the
subsequent ones will be much quicker.

Thanks,

MPark.




On 29 September 2014 at 11:05, Richard Smith <[email protected]> wrote:

> On Tue, Sep 23, 2014 at 2:33 PM, Michael Park <[email protected]> wrote:
>
>> I tried adding *LocalInstantiationScope* around
>> *PerformPendingInstantiation*, like so:
>>
>> // A static constexpr member function of a local class can be used in
>>> // a constexpr expression right after the local class' definition.
>>> // We need to instantiate them now, otherwise it may be too late.
>>> LocalInstantiationScope Local(SemaRef);
>>> SemaRef.PerformPendingInstantiations(/*LocalOnly=*/true);
>>> Local.Exit();
>>
>>
>> but it didn't seem to work. I'm not sure what I'm missing here. Could you
>> give me a hint please?
>>
>
> This is the bit I was referring to:
>
>   SavePendingLocalImplicitInstantiationsRAII
>       SavedPendingLocalImplicitInstantiations(*this);
>   std::unique_ptr<SavePendingInstantiationsAndVTableUsesRAII>
>       SavePendingInstantiationsAndVTableUses;
>   if (Recursive) {
>     SavePendingInstantiationsAndVTableUses.reset(
>         new SavePendingInstantiationsAndVTableUsesRAII(*this));
>   }
>
> [...]
>
>   PerformPendingInstantiations(/*LocalOnly=*/true);
>   Scope.Exit();
>
>   if (Recursive) {
>     // Define any pending vtables.
>     DefineUsedVTables();
>
>     // Instantiate any pending implicit instantiations found during the
>     // instantiation of this template.
>     PerformPendingInstantiations();
>
>     // Restore PendingInstantiations and VTableUses.
>     SavePendingInstantiationsAndVTableUses.reset();
>   }
>
>
>
>> Thanks
>>
>> On 25 August 2014 01:30, Richard Smith <[email protected]> wrote:
>>
>>> It would be better to save and restore the pending local instantiations
>>> around the calls to instantiate the class body and its members, as we do
>>> elsewhere when we perform local pending instantiations.
>>>
>>>
>>> On Fri, Aug 22, 2014 at 2:41 AM, Michael Park <[email protected]> wrote:
>>>
>>>> Fixes http://llvm.org/bugs/show_bug.cgi?id=20625
>>>>
>>>> _______________________________________________
>>>> cfe-commits mailing list
>>>> [email protected]
>>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>>>
>>>>
>>>
>>
>
diff --git lib/Sema/SemaTemplateInstantiateDecl.cpp 
lib/Sema/SemaTemplateInstantiateDecl.cpp
index 1df0701..6980769 100644
--- lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1265,11 +1265,19 @@ Decl 
*TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) {
   // DR1484 clarifies that the members of a local class are instantiated as 
part
   // of the instantiation of their enclosing entity.
   if (D->isCompleteDefinition() && D->isLocalClass()) {
+    Sema::SavePendingLocalImplicitInstantiationsRAII
+        SavedPendingLocalImplicitInstantiations(SemaRef);
+
     SemaRef.InstantiateClass(D->getLocation(), Record, D, TemplateArgs,
                              TSK_ImplicitInstantiation,
                              /*Complain=*/true);
+
     SemaRef.InstantiateClassMembers(D->getLocation(), Record, TemplateArgs,
                                     TSK_ImplicitInstantiation);
+
+    // This class may have local implicit instantiations that need to be
+    // performed within this scope.
+    SemaRef.PerformPendingInstantiations(/*LocalOnly=*/true);
   }
 
   SemaRef.DiagnoseUnusedNestedTypedefs(Record);
diff --git test/SemaTemplate/instantiate-local-class.cpp 
test/SemaTemplate/instantiate-local-class.cpp
index c9897b9..a945c01 100644
--- test/SemaTemplate/instantiate-local-class.cpp
+++ test/SemaTemplate/instantiate-local-class.cpp
@@ -194,3 +194,16 @@ struct B {
   void f() { F<int>(); }
 };
 }
+
+namespace PR20625 {
+template <typename T>
+void f() {
+  struct N {
+    static constexpr int get() { return 42; }
+  };
+  constexpr int n = N::get();
+  static_assert(n == 42, "n == 42");
+}
+
+void g() { f<void>(); }
+}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to