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 <[email protected]> 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.
>

Attachment: clang-visibility.patch
Description: Binary data

_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to