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

Ismail Pazarbasi ismail.pazarbasi at gmail.com
Mon Apr 22 14:10:45 PDT 2013


  I have added a few test cases for alias templates, a function template - to ensure I didn't break it - and extended previous one slightly. I initially had a FIXME for alias templates, but removed it right before I submitted the patch. I can't find a way to access a private variable/field from an alias template context.

Hi rsmith,

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

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

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

Index: lib/Sema/SemaAccess.cpp
===================================================================
--- lib/Sema/SemaAccess.cpp
+++ lib/Sema/SemaAccess.cpp
@@ -1487,7 +1487,7 @@
     if (!DC->isFunctionOrMethod())
       DC = FN;
   } else if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D)) {
-    DC = dyn_cast<DeclContext>(TD->getTemplatedDecl());
+    DC = cast<DeclContext>(TD->getTemplatedDecl());
   }
 
   EffectiveContext EC(DC);
Index: test/SemaCXX/access.cpp
===================================================================
--- test/SemaCXX/access.cpp
+++ test/SemaCXX/access.cpp
@@ -35,24 +35,74 @@
 
 // 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 { };
+  namespace alias_templates {
+    template<typename T1, typename T2> struct U { };
+    template<typename T1> using W = U<T1, float>;
 
-  template<A::I> struct A::C { };
+    class A {
+      typedef int I;
+      static constexpr I x = 0; // expected-note {{implicitly declared private here}}
+      static constexpr I y = 42; // expected-note {{implicitly declared private here}}
+      friend W<int>;
+    };
 
-  template<A::I> struct D { };  // expected-error {{'I' is a private member of 'PR15209::A'}}
+    template<typename T1>
+    struct U<T1, float>  {
+      int v_;
+      // the following will trigger for U<float, float> instantiation, via W<float>
+      U() : v_(A::x) { } // expected-error {{'x' is a private member of 'PR15209::alias_templates::A'}}
+    };
 
-  template<A::I, typename T> struct E { };
+    template<typename T1>
+    struct U<T1, int> {
+      int v_;
+      U() : v_(A::y) { } // expected-error {{'y' is a private member of 'PR15209::alias_templates::A'}}
+    };
 
-  template<template<A::I> class T> struct TT {
-    T<A::I(0)> t;
-  };
-  template struct TT<B>;
+    template struct U<int, int>; // expected-note {{in instantiation of member function 'PR15209::alias_templates::U<int, int>::U' requested here}}
+
+    void f()
+    {
+      W<int>();
+      // we should issue diagnostics for the following
+      W<float>(); // expected-note {{in instantiation of member function 'PR15209::alias_templates::U<float, float>::U' requested here}}
+    }
+  }
+
+  namespace templates {
+    class A {
+      typedef int I;  // expected-note {{implicitly declared private here}}
+      static constexpr I x = 0; // expected-note {{implicitly declared private here}}
+
+      template<int> friend struct B;
+      template<int> struct C;
+      template<template<int> class T> friend struct TT;
+      template<typename T> friend void funct(T);
+    };
+    template<A::I> struct B { };
+
+    template<A::I> struct A::C { };
+
+    template<template<A::I> class T> struct TT {
+      T<A::x> t;
+    };
+
+    template struct TT<B>;
+    template<A::I> struct D { };  // expected-error {{'I' is a private member of 'PR15209::templates::A'}}
+    template struct TT<D>;
+
+    // function template case
+    template<typename T>
+    void funct(T)
+    {
+      (void)A::x;
+    }
+
+    template void funct<int>(int);
+
+    void f()
+    {
+      (void)A::x;  // expected-error {{'x' is a private member of 'PR15209::templates::A'}}
+    }
+  }
 }
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D696.3.patch
Type: text/x-patch
Size: 3464 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130422/4ceafbbc/attachment.bin>


More information about the cfe-commits mailing list