[PATCH] D43153: [clang] Implement P0692 "Access Checking on Specializations"

2023-01-12 Thread Roman Lebedev via Phabricator via cfe-commits
lebedev.ri resigned from this revision.
lebedev.ri added a comment.
Herald added a subscriber: StephenFan.
Herald added a project: All.

This review seems to be stuck/dead, consider abandoning if no longer relevant.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D43153/new/

https://reviews.llvm.org/D43153

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D43153: [clang] Implement P0692 "Access Checking on Specializations"

2018-02-10 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith added a comment.

In https://reviews.llvm.org/D43153#1004464, @AntonBikineev wrote:

> So is my impression wrong and names in declaration-specifiers/declarators of 
> partial-specialiations of variable-templates should be exempted from checks 
> as well?


No, sorry, that's my error not yours.


Repository:
  rC Clang

https://reviews.llvm.org/D43153



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D43153: [clang] Implement P0692 "Access Checking on Specializations"

2018-02-10 Thread Anton Bikineev via Phabricator via cfe-commits
AntonBikineev added a comment.

@rsmith Thanks for pointing out this example. Now I see that I misunderstood 
the wording.
Another question is that in the provided example you say that the following line

  template A::B x; // ok!

should suppress the error of accessing private A::B. But in the wording it's 
said that

> The usual access checking rules do not apply to non-dependent names used to 
> specify **template arguments of the simple-template-id** of the partial 
> specialization.

So it gave me the impression that only names used as template arguments should 
be exempted from checks. But here `A::B` is a non-dependent name that's part of 
the declaration-specifier. So is my impression wrong and names in 
declaration-specifiers/declarators of partial-specialiations of 
variable-templates should be exempted from checks as well?

Thanks.


Repository:
  rC Clang

https://reviews.llvm.org/D43153



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D43153: [clang] Implement P0692 "Access Checking on Specializations"

2018-02-09 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith added a comment.

How do you avoid suppressing diagnostics in the declaration of a template that 
is not a partial specialization? For example:

  class A { class B {}; };
  template A::B x; // error, but...
  template A::B x; // ok!

I would expect you'd need to delay the access checking diagnostics here until 
the declaration is complete and you find out whether you have a partial 
specialization or not.


Repository:
  rC Clang

https://reviews.llvm.org/D43153



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D43153: [clang] Implement P0692 "Access Checking on Specializations"

2018-02-09 Thread Anton Bikineev via Phabricator via cfe-commits
AntonBikineev created this revision.
AntonBikineev added reviewers: rsmith, lebedev.ri.

This is an attempt to implement P0692 

Please note a couple of things:

1. given that clang already suppresses access checks on explicit 
specializations of classes as an extension, I decided to not make the feature 
C++17-specific and backport it to previous standards. Not sure that this is 
right though;
2. I'm also not sure that ParseOptionalCXXScopeSpecifer in a declarator is the 
correct place for suppressing checks.


Repository:
  rC Clang

https://reviews.llvm.org/D43153

Files:
  include/clang/Parse/RAIIObjectsForParser.h
  include/clang/Sema/DeclSpec.h
  lib/Parse/ParseDecl.cpp
  lib/Parse/ParseDeclCXX.cpp
  lib/Parse/ParseTemplate.cpp
  test/CXX/drs/dr1xx.cpp
  test/SemaCXX/access.cpp

Index: test/SemaCXX/access.cpp
===
--- test/SemaCXX/access.cpp
+++ test/SemaCXX/access.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify %s
 
 class C {
 struct S; // expected-note {{previously declared 'private' here}}
@@ -169,3 +169,103 @@
   }
   void bar() { foo(); }
 }
+
+namespace P0692 {
+  namespace class_ {
+template 
+class trait_type {};
+   
+template 
+class trait_nontype;
+
+template  class>
+class trait_template;
+
+class A {
+  class B1 {}; // expected-note 2{{here}}
+
+  template 
+  class B2 {}; // expected-note 2{{here}}
+
+  class B3 {};
+   
+  static const int I = 0; // expected-note 4{{here}}
+};
+   
+template 
+class trait_type {
+  void use_private(int = A::I) { // expected-error {{private}}
+A::B2 error; // expected-error {{private}}
+  }
+};
+
+template  class T>
+class trait_type {
+  static const int I = A::I; // expected-error {{private}}
+};
+   
+template <>
+class trait_type
+  : A::B1 { // expected-error {{private}}
+  void use_private(int = A::I) { // expected-error {{private}}
+A::B1 error; // expected-error {{private}}
+  }
+};
+
+template class trait_type;
+
+template <>
+class trait_nontype {
+  static const int I = A::I; // expected-error {{private}}
+};
+
+template <>
+class trait_template {
+  A::B2 error; // expected-error {{private}}
+};
+  }
+
+  namespace function {
+class A {
+  class B1 {}; // expected-note 1{{here}}
+
+  class B2 {};
+   
+  using Int = int; // expected-note 1{{here}}
+};
+   
+template 
+void foo1() {}
+
+template <> void foo1() {
+A::B1 error; // expected-error {{private}}
+}
+
+template void foo1();
+
+template 
+void foo2(A::Int) {} // expected-error {{private}}
+  }
+
+  namespace variable {
+class A {
+  class B1 {};
+
+  template 
+  class B2 {};
+   
+  static const int I = 0; // expected-note 2{{here}}
+};
+
+template 
+int var = 0;
+
+template <>
+int var =
+A::I; // expected-error {{private}}
+
+template 
+int var =
+A::I; // expected-error {{private}}
+  }
+}
Index: test/CXX/drs/dr1xx.cpp
===
--- test/CXX/drs/dr1xx.cpp
+++ test/CXX/drs/dr1xx.cpp
@@ -917,12 +917,12 @@
   template  void C::g() {}
 
   class A {
-class B {}; // expected-note {{here}}
+class B {};
 void f();
   };
 
   template void C::f();
-  template <> void C::g(); // expected-error {{private}}
+  template <> void C::g();
 
   void A::f() {
 C cb;
Index: lib/Parse/ParseTemplate.cpp
===
--- lib/Parse/ParseTemplate.cpp
+++ lib/Parse/ParseTemplate.cpp
@@ -235,7 +235,10 @@
 
   // Parse the declarator.
   ParsingDeclarator DeclaratorInfo(*this, DS, (DeclaratorContext)Context);
+  DeclaratorInfo.setTemplateDeclOrSpec(TemplateInfo.Kind !=
+   ParsedTemplateInfo::NonTemplate);
   ParseDeclarator(DeclaratorInfo);
+
   // Error parsing the declarator?
   if (!DeclaratorInfo.hasName()) {
 // If so, skip until the semi-colon or a }.
Index: lib/Parse/ParseDeclCXX.cpp
===
--- lib/Parse/ParseDeclCXX.cpp
+++ lib/Parse/ParseDeclCXX.cpp
@@ -1375,15 +1375,22 @@
   //   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.
+  // C++2a [temp.spec] 17.8/6:
+  //   The usual access checking rules do not apply to names in a declaration
+  //   of an explicit instantiation or explicit specialization,