[cfe-commits] r106993 - in /cfe/trunk: include/clang/Parse/Action.h lib/Parse/ParseDeclCXX.cpp lib/Sema/Sema.cpp lib/Sema/Sema.h lib/Sema/SemaAccess.cpp test/CXX/temp/temp.spec/temp.explicit/p11.cpp

Douglas Gregor dgregor at apple.com
Tue Jun 29 08:13:51 PDT 2010


On Jun 28, 2010, at 1:39 AM, Chandler Carruth wrote:

> Author: chandlerc
> Date: Mon Jun 28 03:39:25 2010
> New Revision: 106993
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=106993&view=rev
> Log:
> Partial fix for PR7267 based on comments by John McCall on an earlier patch.
> This is more targeted, as it simply provides toggle actions for the parser to
> turn access checking on and off. We then use these to suppress access checking
> only while we parse the template-id (included scope specifier) of an explicit
> instantiation and explicit specialization of a class template. The
> specialization behavior is an extension, as it seems likely a defect that the
> standard did not exempt them as it does explicit instantiations.

Both EDG and g++ seem to allow this "extension", too.

> Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=106993&r1=106992&r2=106993&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
> +++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Mon Jun 28 03:39:25 2010
> @@ -613,6 +613,20 @@
>     ConsumeCodeCompletionToken();
>   }
> 
> +  // C++03 [temp.explicit] 14.7.2/8:
> +  //   The usual access checking rules do not apply to names used to specify
> +  //   explicit instantiations.
> +  //
> +  // As an extension we do not perform access checking on the names used to
> +  // specify explicit specializations either. This is important to allow
> +  // specializing traits classes for private types.
> +  bool SuppressingAccessChecks = false;
> +  if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
> +      TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization) {
> +    Actions.ActOnStartSuppressingAccessChecks();
> +    SuppressingAccessChecks = true;
> +  }
> +
>   AttributeList *AttrList = 0;
>   // If attributes exist after tag, parse them.
>   if (Tok.is(tok::kw___attribute))
> @@ -732,10 +746,18 @@
>       DS.SetTypeSpecError();
>       SkipUntil(tok::semi, false, true);
>       TemplateId->Destroy();
> +      if (SuppressingAccessChecks)
> +        Actions.ActOnStopSuppressingAccessChecks();
> +
>       return;
>     }
>   }
> 
> +  // As soon as we're finished parsing the class's template-id, turn access
> +  // checking back on.
> +  if (SuppressingAccessChecks)
> +    Actions.ActOnStopSuppressingAccessChecks();
> +
>   // There are four options here.  If we have 'struct foo;', then this
>   // is either a forward declaration or a friend declaration, which
>   // have to be treated differently.  If we have 'struct foo {...' or

I'd feel a bit more comfortable if this were an RAII object.

	- Doug



More information about the cfe-commits mailing list