[cfe-dev] [PATCH] Using private types should be allowed as template parametter for explicit instantiation

John McCall rjmccall at apple.com
Tue Jun 22 14:05:40 PDT 2010


On Jun 22, 2010, at 11:39 AM, Olivier Goffart wrote:

> On Thursday 17 June 2010, Olivier Goffart wrote :
>> Hello.
>> 
>> Attached you will find my attempt to fix
>> http://llvm.org/bugs/show_bug.cgi?id=7267
>> 
>> The problem is that in this code
>> 
>> class X { class Y; };
>> template<class T> struct Test {};
>> template<> struct Test<X::Y> {};
>> 
>> Clang would complains that X::Y is private.
>> 
>> While the C++ specification 14.7.2 [temp.explicit] p11
>> says it should compile (The usual access checking rules do not apply to
>> names used to specify explicit instantiations)
>> 
>> (This break compilation of Qt's linguist tool)
>> 
>> 
>> The patch is only one line but was not trivial.
>> By having a ParsingDeclRAIIObject while parsing that kind of close, we make
>> sure any diagnostic are delayed. And because I do not call complete() on
>> it, the delayed diagnostic will not be issued.
>> 
>> Does my patch makes sens this time?
>> 
>> Regards.
> 
> Ping?

Sorry, missed this the last time.  This patch won't work for several reasons.

1.  You're suppressing access checks whenever ParseTemplateIdAfterTemplateName
parses a template argument list.  That's actually a large number of cases, most of
which are not explicit instantiations.  It happens to be the case that certain very
common cases follow a different code path, which is why your test case works,
but there are many other cases where this breaks things.

2.  You're suppressing access checks for explicit specializations, not just explicit
instantiations.  I see no justification of that in the standard.

3.  You're only suppressing access checks in the template arguments, not in the
template name itself (it could be a private member template) or in the associated
types (if it's a function template).  *All* access checks in the declaration need to be
suppressed.

4.  The use of ParsingDeclRAIIObject is clever, but I suspect it won't work as
desired for explicit instantiations of function templates.  If so, you'll need to make
a different mechanism which just completely suppresses access checks.  Fortunately,
it doesn't need to be recursive;  I think you can just make a new Action method to
enable/disable access checks, have the method set a flag on Sema, and have
CheckAccess in SemaAccess.cpp check that flag (right before the code about
delaying diagnostics when parsing declarators).

You can trigger the new mechanism in ParseExplicitInstantiation.

John.



More information about the cfe-dev mailing list