Home | History | Annotate | Download | only in SemaCXX
      1 // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14
      2 
      3 namespace access_control {
      4 class Private {
      5   void check(int *) __attribute__((enable_if(false, "")));
      6   void check(double *) __attribute__((enable_if(true, "")));
      7 
      8   static void checkStatic(int *) __attribute__((enable_if(false, "")));
      9   static void checkStatic(double *) __attribute__((enable_if(true, "")));
     10 };
     11 
     12 auto Priv = reinterpret_cast<void (Private::*)(char *)>(&Private::check); // expected-error{{'check' is a private member of 'access_control::Private'}} expected-note@6{{implicitly declared private here}}
     13 
     14 auto PrivStatic = reinterpret_cast<void (*)(char *)>(&Private::checkStatic); // expected-error{{'checkStatic' is a private member of 'access_control::Private'}} expected-note@9{{implicitly declared private here}}
     15 
     16 class Protected {
     17 protected:
     18   void check(int *) __attribute__((enable_if(false, "")));
     19   void check(double *) __attribute__((enable_if(true, "")));
     20 
     21   static void checkStatic(int *) __attribute__((enable_if(false, "")));
     22   static void checkStatic(double *) __attribute__((enable_if(true, "")));
     23 };
     24 
     25 auto Prot = reinterpret_cast<void (Protected::*)(char *)>(&Protected::check); // expected-error{{'check' is a protected member of 'access_control::Protected'}} expected-note@19{{declared protected here}}
     26 
     27 auto ProtStatic = reinterpret_cast<void (*)(char *)>(&Protected::checkStatic); // expected-error{{'checkStatic' is a protected member of 'access_control::Protected'}} expected-note@22{{declared protected here}}
     28 }
     29 
     30 namespace unavailable {
     31 // Ensure that we check that the function can be called
     32 void foo() __attribute__((unavailable("don't call this")));
     33 void foo(int) __attribute__((enable_if(false, "")));
     34 
     35 void *Ptr = reinterpret_cast<void*>(foo); // expected-error{{'foo' is unavailable: don't call this}} expected-note@-3{{explicitly marked unavailable here}}
     36 }
     37 
     38 namespace template_deduction {
     39 void foo() __attribute__((enable_if(false, "")));
     40 
     41 void bar() __attribute__((enable_if(true, "")));
     42 void bar() __attribute__((enable_if(false, "")));
     43 
     44 void baz(int a) __attribute__((enable_if(true, "")));
     45 void baz(int a) __attribute__((enable_if(a, "")));
     46 void baz(int a) __attribute__((enable_if(false, "")));
     47 
     48 void qux(int a) __attribute__((enable_if(1, "")));
     49 void qux(int a) __attribute__((enable_if(true, "")));
     50 void qux(int a) __attribute__((enable_if(a, "")));
     51 void qux(int a) __attribute__((enable_if(false, "")));
     52 
     53 template <typename Fn, typename... Args> void call(Fn F, Args... As) {
     54   F(As...);
     55 }
     56 
     57 void test() {
     58   call(foo); // expected-error{{cannot take address of function 'foo'}}
     59   call(bar);
     60   call(baz, 0);
     61   call(qux, 0); // expected-error{{no matching function for call to 'call'}} expected-note@53{{candidate template ignored: couldn't infer template argument 'Fn'}}
     62 
     63   auto Ptr1 = foo; // expected-error{{cannot take address of function 'foo'}}
     64   auto Ptr2 = bar;
     65   auto Ptr3 = baz;
     66   auto Ptr4 = qux; // expected-error{{variable 'Ptr4' with type 'auto' has incompatible initializer of type '<overloaded function type>'}}
     67 }
     68 
     69 template <typename Fn, typename T, typename... Args>
     70 void callMem(Fn F, T t, Args... As) {
     71   (t.*F)(As...);
     72 }
     73 
     74 class Foo {
     75   void bar() __attribute__((enable_if(true, "")));
     76   void bar() __attribute__((enable_if(false, "")));
     77 
     78   static void staticBar() __attribute__((enable_if(true, "")));
     79   static void staticBar() __attribute__((enable_if(false, "")));
     80 };
     81 
     82 void testAccess() {
     83   callMem(&Foo::bar, Foo()); // expected-error{{'bar' is a private member of 'template_deduction::Foo'}} expected-note@-8{{implicitly declared private here}}
     84   call(&Foo::staticBar); // expected-error{{'staticBar' is a private member of 'template_deduction::Foo'}} expected-note@-6{{implicitly declared private here}}
     85 }
     86 }
     87 
     88 namespace template_template_deduction {
     89 void foo() __attribute__((enable_if(false, "")));
     90 template <typename T>
     91 T foo() __attribute__((enable_if(true, "")));
     92 
     93 template <typename Fn, typename... Args> auto call(Fn F, Args... As) {
     94   return F(As...);
     95 }
     96 
     97 auto Ok = call(&foo<int>);
     98 auto Fail = call(&foo); // expected-error{{no matching function for call to 'call'}} expected-note@-5{{candidate template ignored: couldn't infer template argument 'Fn'}}
     99 
    100 auto PtrOk = &foo<int>;
    101 auto PtrFail = &foo; // expected-error{{variable 'PtrFail' with type 'auto' has incompatible initializer of type '<overloaded function type>'}}
    102 }
    103 
    104 namespace pointer_equality {
    105   using FnTy = void (*)();
    106 
    107   void bothEnableIf() __attribute__((enable_if(false, "")));
    108   void bothEnableIf() __attribute__((enable_if(true, "")));
    109 
    110   void oneEnableIf() __attribute__((enable_if(false, "")));
    111   void oneEnableIf();
    112 
    113   void test() {
    114     FnTy Fn;
    115     (void)(Fn == bothEnableIf);
    116     (void)(Fn == &bothEnableIf);
    117     (void)(Fn == oneEnableIf);
    118     (void)(Fn == &oneEnableIf);
    119   }
    120 
    121   void unavailableEnableIf() __attribute__((enable_if(false, "")));
    122   void unavailableEnableIf() __attribute__((unavailable("noooo"))); // expected-note 2{{marked unavailable here}}
    123 
    124   void testUnavailable() {
    125     FnTy Fn;
    126     (void)(Fn == unavailableEnableIf); // expected-error{{is unavailable}}
    127     (void)(Fn == &unavailableEnableIf); // expected-error{{is unavailable}}
    128   }
    129 
    130   class Foo {
    131     static void staticAccessEnableIf(); // expected-note 2{{declared private here}}
    132     void accessEnableIf(); // expected-note{{declared private here}}
    133 
    134   public:
    135     static void staticAccessEnableIf() __attribute__((enable_if(false, "")));
    136     void accessEnableIf() __attribute__((enable_if(false, "")));
    137   };
    138 
    139   void testAccess() {
    140     FnTy Fn;
    141     (void)(Fn == Foo::staticAccessEnableIf); // expected-error{{is a private member}}
    142     (void)(Fn == &Foo::staticAccessEnableIf); // expected-error{{is a private member}}
    143 
    144     void (Foo::*MemFn)();
    145     (void)(MemFn == &Foo::accessEnableIf); // expected-error{{is a private member}}
    146   }
    147 }
    148