[PATCH] Implementation of core DR580 and C++11 member access rules

Ismail Pazarbasi ismail.pazarbasi at gmail.com
Sat Apr 20 02:14:29 PDT 2013


  As a part of style changes, `DC = FN` moved to next line.

Hi rsmith,

http://llvm-reviews.chandlerc.com/D696

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D696?vs=1647&id=1703#toc

Files:
  lib/Sema/SemaAccess.cpp
  test/SemaCXX/access.cpp

Index: lib/Sema/SemaAccess.cpp
===================================================================
--- lib/Sema/SemaAccess.cpp
+++ lib/Sema/SemaAccess.cpp
@@ -84,10 +84,10 @@
     : Inner(DC),
       Dependent(DC->isDependentContext()) {
 
-    // C++ [class.access.nest]p1:
+    // C++11 [class.access.nest]p1:
     //   A nested class is a member and as such has the same access
     //   rights as any other member.
-    // C++ [class.access]p2:
+    // C++11 [class.access]p2:
     //   A member of a class can also access all the names to which
     //   the class has access.  A local class of a member function
     //   may access the same names that the member function itself
@@ -1476,18 +1476,18 @@
   llvm_unreachable("falling off end");
 }
 
-void Sema::HandleDelayedAccessCheck(DelayedDiagnostic &DD, Decl *decl) {
+void Sema::HandleDelayedAccessCheck(DelayedDiagnostic &DD, Decl *D) {
   // Access control for names used in the declarations of functions
   // and function templates should normally be evaluated in the context
   // of the declaration, just in case it's a friend of something.
   // However, this does not apply to local extern declarations.
 
-  DeclContext *DC = decl->getDeclContext();
-  if (FunctionDecl *fn = dyn_cast<FunctionDecl>(decl)) {
-    if (!DC->isFunctionOrMethod()) DC = fn;
-  } else if (FunctionTemplateDecl *fnt = dyn_cast<FunctionTemplateDecl>(decl)) {
-    // Never a local declaration.
-    DC = fnt->getTemplatedDecl();
+  DeclContext *DC = D->getDeclContext();
+  if (FunctionDecl *FN = dyn_cast<FunctionDecl>(D)) {
+    if (!DC->isFunctionOrMethod())
+      DC = FN;
+  } else if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D)) {
+    DC = dyn_cast<DeclContext>(TD->getTemplatedDecl());
   }
 
   EffectiveContext EC(DC);
Index: test/SemaCXX/access.cpp
===================================================================
--- test/SemaCXX/access.cpp
+++ test/SemaCXX/access.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
 
 class C {
     struct S; // expected-note {{previously declared 'private' here}}
@@ -32,3 +32,27 @@
     class X {};
   };
 }
+
+// PR15209
+namespace PR15209 {
+  class A {
+    typedef int I;  // expected-note {{implicitly declared private here}}
+    template<int> friend struct B;
+    template<int> struct C;
+    template<int, typename T> friend struct E;
+    template<template<int> class T> friend struct TT;
+    static constexpr int x = 0;
+  };
+  template<A::I> struct B { };
+
+  template<A::I> struct A::C { };
+
+  template<A::I> struct D { };  // expected-error {{'I' is a private member of 'PR15209::A'}}
+
+  template<A::I, typename T> struct E { };
+
+  template<template<A::I> class T> struct TT {
+    T<A::I(0)> t;
+  };
+  template struct TT<B>;
+}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D696.2.patch
Type: text/x-patch
Size: 2826 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130420/f8b769d2/attachment.bin>


More information about the cfe-commits mailing list