[cfe-commits] patch for llvm.org/pr8207
Douglas Gregor
dgregor at apple.com
Mon Sep 27 13:26:50 PDT 2010
On Sep 27, 2010, at 12:49 PM, Nico Weber wrote:
> And now with a more portable test, courtesy of Benjamin Kramer. Only
> the CHECK lines changed.
@@ -1549,6 +1549,13 @@
InstantiateClass(PointOfInstantiation, Record, Pattern,
TemplateArgs,
TSK);
+ } else {
+ //if (TSK == TSK_ExplicitInstantiationDefinition &&
+ //Record->getTemplateSpecializationKind() ==
+ //TSK_ExplicitInstantiationDeclaration) {
+ //Record->setTemplateSpecializationKind(TSK);
+ //MarkVTableUsed(PointOfInstantiation, Record, true);
+ //}
}
Pattern = cast_or_null<CXXRecordDecl>(Record->getDefinition());
I'm guessing that you didn't mean to comment these out :)
Property changes on: test/CodeGenCXX/template-inner-struct-visibility-hidden.cpp
___________________________________________________________________
Added: svn:eol-style
+ LF
That's a little strange... I would have expected "native", or no properties at all.
With those tweak, looks good; please go ahead and commit!
- Doug
> On Sun, Sep 26, 2010 at 3:14 PM, Nico Weber <thakis at chromium.org> wrote:
>> Updated the patch with a slightly beefier test case. The actual code
>> change is the same as in the previous patch.
>>
>> Please review.
>>
>> Nico
>>
>> On Sat, Sep 25, 2010 at 11:29 PM, Nico Weber <thakis at chromium.org> wrote:
>>> Hi,
>>>
>>> the attached patch fixes llvm.org/pr8207 (and potentially more). The
>>> reason the bug happens is the following code in CodeGenModule:
>>>
>>> LangOptions::VisibilityMode
>>> CodeGenModule::getDeclVisibilityMode(const Decl *D) const {
>>> // ...
>>>
>>> if (getLangOptions().CPlusPlus) {
>>> // Entities subject to an explicit instantiation declaration get default
>>> // visibility.
>>> if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
>>> // ...
>>> } else if (const ClassTemplateSpecializationDecl *ClassSpec
>>> = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
>>> if (ClassSpec->getSpecializationKind()
>>> == TSK_ExplicitInstantiationDeclaration)
>>> return LangOptions::Default;
>>> } else if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D)) {
>>> if (Record->getTemplateSpecializationKind()
>>> == TSK_ExplicitInstantiationDeclaration)
>>> return LangOptions::Default;
>>> } else if (const VarDecl *Var = dyn_cast<VarDecl>(D)) {
>>> // ...
>>> }
>>>
>>> // ...
>>> }
>>>
>>> // If this decl is contained in a class, it should have the same visibility
>>> // as the parent class.
>>> if (const DeclContext *DC = D->getDeclContext())
>>> if (DC->isRecord())
>>> return getDeclVisibilityMode(cast<Decl>(DC));
>>>
>>> return getLangOptions().getVisibilityMode();
>>> }
>>>
>>>
>>> When a template specialization declaration is overridden with a
>>> template specialization definition, the template specialization kind
>>> of inner structs was not updated. Hence, when the function above
>>> checked the visibility of the inner struct's function, it would look
>>> in the parent class (== the inner struct) because of the code at the
>>> end of the function, and then would return LangOptions::Default,
>>> because the inner struct would still have specialization kind
>>> TSK_ExplicitInstantiationDeclaration.
>>>
>>> The fix is to correctly re-set the specialization kind of inner
>>> structs on the TSK_ExplicitInstantiationDeclaration ->
>>> TSK_ExplicitInstantiationDefinition transition on the base class.
>>>
>>> Nico
>>>
>>>
>>> ps: I'm not sure if the call to MarkVTableUsed is needed, but it's
>>> called further up in that file when
>>> TSK_ExplicitInstantiationDefinition is set too.
>>>
>>
> <clang-visibility.patch>_______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list