summaryrefslogtreecommitdiff
path: root/clang/test/CXX/expr/expr.unary
diff options
context:
space:
mode:
authorZancanaro; Carlo <czan8762@plang3.cs.usyd.edu.au>2012-09-24 09:58:17 +1000
committerZancanaro; Carlo <czan8762@plang3.cs.usyd.edu.au>2012-09-24 09:58:17 +1000
commit222e2a7620e6520ffaf4fc4e69d79c18da31542e (patch)
tree7bfbc05bfa3b41c8f9d2e56d53a0bc3e310df239 /clang/test/CXX/expr/expr.unary
parent3d206f03985b50beacae843d880bccdc91a9f424 (diff)
Add the clang library to the repo (with some of my changes, too).
Diffstat (limited to 'clang/test/CXX/expr/expr.unary')
-rw-r--r--clang/test/CXX/expr/expr.unary/expr.delete/p5.cpp46
-rw-r--r--clang/test/CXX/expr/expr.unary/expr.new/p17-crash.cpp14
-rw-r--r--clang/test/CXX/expr/expr.unary/expr.new/p17.cpp16
-rw-r--r--clang/test/CXX/expr/expr.unary/expr.new/p19.cpp46
-rw-r--r--clang/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp23
-rw-r--r--clang/test/CXX/expr/expr.unary/expr.new/p20-0x.cpp13
-rw-r--r--clang/test/CXX/expr/expr.unary/expr.new/p20.cpp141
-rw-r--r--clang/test/CXX/expr/expr.unary/expr.sizeof/p5-0x.cpp38
-rw-r--r--clang/test/CXX/expr/expr.unary/expr.unary.noexcept/cg.cpp26
-rw-r--r--clang/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp189
-rw-r--r--clang/test/CXX/expr/expr.unary/expr.unary.noexcept/ser.h8
-rw-r--r--clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp28
-rw-r--r--clang/test/CXX/expr/expr.unary/expr.unary.op/p4.cpp43
-rw-r--r--clang/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp35
14 files changed, 666 insertions, 0 deletions
diff --git a/clang/test/CXX/expr/expr.unary/expr.delete/p5.cpp b/clang/test/CXX/expr/expr.unary/expr.delete/p5.cpp
new file mode 100644
index 0000000..ecb2918
--- /dev/null
+++ b/clang/test/CXX/expr/expr.unary/expr.delete/p5.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -verify %s
+
+// If the object being deleted has incomplete class type at the point of
+// deletion and the complete class has a non-trivial destructor or a
+// deallocation function, the behavior is undefined.
+
+// The trivial case.
+class T0; // expected-note {{forward declaration}}
+void f0(T0 *a) { delete a; } // expected-warning {{deleting pointer to incomplete type}}
+class T0 { ~T0(); };
+
+// The trivial case, inside a template instantiation.
+template<typename T>
+struct T1_A { T *x; ~T1_A() { delete x; } }; // expected-warning {{deleting pointer to incomplete type}}
+class T1_B; // expected-note {{forward declaration}}
+void f0() { T1_A<T1_B> x; } // expected-note {{in instantiation of member function}}
+
+// This case depends on when we check T2_C::f0.
+class T2_A;
+template<typename T>
+struct T2_B { void f0(T *a) { delete a; } };
+struct T2_C { T2_B<T2_A> x; void f0(T2_A *a) { x.f0(a); } };
+void f0(T2_A *a) { T2_C x; x.f0(a); }
+class T2_A { };
+
+// An alternate version of the same.
+class T3_A;
+template<typename T>
+struct T3_B {
+ void f0(T *a) {
+ delete a; // expected-error{{calling a private destructor of class 'T3_A'}}
+ }
+};
+
+struct T3_C {
+ T3_B<T3_A> x;
+ void f0(T3_A *a) {
+ x.f0(a); // expected-note{{in instantiation of member function 'T3_B<T3_A>::f0' requested here}}
+ }
+};
+
+void f0(T3_A *a) { T3_C x; x.f0(a); }
+class T3_A {
+private:
+ ~T3_A(); // expected-note{{declared private here}}
+};
diff --git a/clang/test/CXX/expr/expr.unary/expr.new/p17-crash.cpp b/clang/test/CXX/expr/expr.unary/expr.new/p17-crash.cpp
new file mode 100644
index 0000000..27b915e
--- /dev/null
+++ b/clang/test/CXX/expr/expr.unary/expr.new/p17-crash.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -emit-llvm-only %s
+
+// this used to crash due to templ<int>'s dtor not being marked as used by the
+// new expression in func()
+struct non_trivial {
+ non_trivial() {}
+ ~non_trivial() {}
+};
+template < typename T > class templ {
+ non_trivial n;
+};
+void func() {
+ new templ<int>[1][1];
+}
diff --git a/clang/test/CXX/expr/expr.unary/expr.new/p17.cpp b/clang/test/CXX/expr/expr.unary/expr.new/p17.cpp
new file mode 100644
index 0000000..0d108eb
--- /dev/null
+++ b/clang/test/CXX/expr/expr.unary/expr.new/p17.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+class ctor {
+ ctor(); // expected-note{{implicitly declared private here}}
+};
+
+class dtor {
+ ~dtor(); // expected-note 3 {{implicitly declared private here}}
+};
+
+void test() {
+ new ctor[0]; // expected-error{{calling a private constructor of class 'ctor'}}
+ new dtor[0]; // expected-error{{calling a private destructor of class 'dtor'}}
+ new dtor[3]; // expected-error{{calling a private destructor of class 'dtor'}}
+ new dtor[3][3]; // expected-error{{calling a private destructor of class 'dtor'}}
+}
diff --git a/clang/test/CXX/expr/expr.unary/expr.new/p19.cpp b/clang/test/CXX/expr/expr.unary/expr.new/p19.cpp
new file mode 100644
index 0000000..bb69fd5
--- /dev/null
+++ b/clang/test/CXX/expr/expr.unary/expr.new/p19.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fexceptions %s
+typedef __SIZE_TYPE__ size_t;
+
+// Operator delete template for placement new with global lookup
+template<int I>
+struct X0 {
+ X0();
+
+ static void* operator new(size_t) {
+ return I; // expected-error{{cannot initialize}}
+ }
+
+ static void operator delete(void*) {
+ int *ip = I; // expected-error{{cannot initialize}}
+ }
+};
+
+void test_X0() {
+ // Using the global operator new suppresses the search for a
+ // operator delete in the class.
+ ::new X0<2>;
+
+ new X0<3>; // expected-note 2{{instantiation}}
+}
+
+// Operator delete template for placement new[] with global lookup
+template<int I>
+struct X1 {
+ X1();
+
+ static void* operator new[](size_t) {
+ return I; // expected-error{{cannot initialize}}
+ }
+
+ static void operator delete[](void*) {
+ int *ip = I; // expected-error{{cannot initialize}}
+ }
+};
+
+void test_X1() {
+ // Using the global operator new suppresses the search for a
+ // operator delete in the class.
+ ::new X1<2> [17];
+
+ new X1<3> [17]; // expected-note 2{{instantiation}}
+}
diff --git a/clang/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp b/clang/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp
new file mode 100644
index 0000000..4ebbfce
--- /dev/null
+++ b/clang/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+
+template<typename T>
+struct only {
+ only(T);
+ template<typename U> only(U) = delete;
+};
+
+void f() {
+ only<const int*> p = new const auto (0);
+ only<double*> q = new (auto) (0.0);
+
+ new auto; // expected-error{{new expression for type 'auto' requires a constructor argument}}
+ new (const auto)(); // expected-error{{new expression for type 'auto const' requires a constructor argument}}
+ new (auto) (1,2,3); // expected-error{{new expression for type 'auto' contains multiple constructor arguments}}
+}
+
+void p2example() {
+ only<int*> r = new auto(1);
+ auto x = new auto('a');
+
+ only<char*> testX = x;
+}
diff --git a/clang/test/CXX/expr/expr.unary/expr.new/p20-0x.cpp b/clang/test/CXX/expr/expr.unary/expr.new/p20-0x.cpp
new file mode 100644
index 0000000..eca1ec7
--- /dev/null
+++ b/clang/test/CXX/expr/expr.unary/expr.new/p20-0x.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -fexceptions %s
+typedef __SIZE_TYPE__ size_t;
+
+struct S {
+ // Placement allocation function:
+ static void* operator new(size_t, size_t);
+ // Usual (non-placement) deallocation function:
+ static void operator delete(void*, size_t); // expected-note{{declared here}}
+};
+
+void testS() {
+ S* p = new (0) S; // expected-error{{'new' expression with placement arguments refers to non-placement 'operator delete'}}
+}
diff --git a/clang/test/CXX/expr/expr.unary/expr.new/p20.cpp b/clang/test/CXX/expr/expr.unary/expr.new/p20.cpp
new file mode 100644
index 0000000..8cbe2b9
--- /dev/null
+++ b/clang/test/CXX/expr/expr.unary/expr.new/p20.cpp
@@ -0,0 +1,141 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fexceptions %s
+typedef __SIZE_TYPE__ size_t;
+
+// Overloaded operator delete with two arguments
+template<int I>
+struct X0 {
+ X0();
+ static void* operator new(size_t);
+ static void operator delete(void*, size_t) {
+ int *ip = I; // expected-error{{cannot initialize}}
+ }
+};
+
+void test_X0() {
+ new X0<1>; // expected-note{{instantiation}}
+}
+
+// Overloaded operator delete with one argument
+template<int I>
+struct X1 {
+ X1();
+
+ static void* operator new(size_t);
+ static void operator delete(void*) {
+ int *ip = I; // expected-error{{cannot initialize}}
+ }
+};
+
+void test_X1() {
+ new X1<1>; // expected-note{{instantiation}}
+}
+
+// Overloaded operator delete for placement new
+template<int I>
+struct X2 {
+ X2();
+
+ static void* operator new(size_t, double, double);
+ static void* operator new(size_t, int, int);
+
+ static void operator delete(void*, const int, int) {
+ int *ip = I; // expected-error{{cannot initialize}}
+ }
+
+ static void operator delete(void*, double, double);
+};
+
+void test_X2() {
+ new (0, 0) X2<1>; // expected-note{{instantiation}}
+}
+
+// Operator delete template for placement new
+struct X3 {
+ X3();
+
+ static void* operator new(size_t, double, double);
+
+ template<typename T>
+ static void operator delete(void*, T x, T) {
+ double *dp = &x;
+ int *ip = &x; // expected-error{{cannot initialize}}
+ }
+};
+
+void test_X3() {
+ new (0, 0) X3; // expected-note{{instantiation}}
+}
+
+// Operator delete template for placement new in global scope.
+struct X4 {
+ X4();
+ static void* operator new(size_t, double, double);
+};
+
+template<typename T>
+void operator delete(void*, T x, T) {
+ double *dp = &x;
+ int *ip = &x; // expected-error{{cannot initialize}}
+}
+
+void test_X4() {
+ new (0, 0) X4; // expected-note{{instantiation}}
+}
+
+// Useless operator delete hides global operator delete template.
+struct X5 {
+ X5();
+ static void* operator new(size_t, double, double);
+ void operator delete(void*, double*, double*);
+};
+
+void test_X5() {
+ new (0, 0) X5; // okay, we found X5::operator delete but didn't pick it
+}
+
+// Operator delete template for placement new
+template<int I>
+struct X6 {
+ X6();
+
+ static void* operator new(size_t) {
+ return I; // expected-error{{cannot initialize}}
+ }
+
+ static void operator delete(void*) {
+ int *ip = I; // expected-error{{cannot initialize}}
+ }
+};
+
+void test_X6() {
+ new X6<3>; // expected-note 2{{instantiation}}
+}
+
+void *operator new(size_t, double, double, double);
+
+template<typename T>
+void operator delete(void*, T x, T, T) {
+ double *dp = &x;
+ int *ip = &x; // expected-error{{cannot initialize}}
+}
+void test_int_new() {
+ new (1.0, 1.0, 1.0) int; // expected-note{{instantiation}}
+}
+
+// We don't need an operator delete if the type has a trivial
+// constructor, since we know that constructor cannot throw.
+// FIXME: Is this within the standard? Seems fishy, but both EDG+GCC do it.
+#if 0
+template<int I>
+struct X7 {
+ static void* operator new(size_t);
+ static void operator delete(void*, size_t) {
+ int *ip = I; // okay, since it isn't instantiated.
+ }
+};
+
+void test_X7() {
+ new X7<1>;
+}
+#endif
+
diff --git a/clang/test/CXX/expr/expr.unary/expr.sizeof/p5-0x.cpp b/clang/test/CXX/expr/expr.unary/expr.sizeof/p5-0x.cpp
new file mode 100644
index 0000000..afd8ef0
--- /dev/null
+++ b/clang/test/CXX/expr/expr.unary/expr.sizeof/p5-0x.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+// Test parsing + semantic analysis
+template<typename ...Types> struct count_types {
+ static const unsigned value = sizeof...(Types);
+};
+
+template<int ...Values> struct count_ints {
+ static const unsigned value = sizeof...(Values);
+};
+
+// Test instantiation
+int check_types[count_types<short, int, long>::value == 3? 1 : -1];
+int check_ints[count_ints<1, 2, 3, 4, 5>::value == 5? 1 : -1];
+
+// Test instantiation involving function parameter packs.
+struct any {
+ template<typename T> any(T);
+};
+
+template<typename ...Inits>
+void init_me(Inits ...inits) {
+ any array[sizeof...(inits)] = { inits... };
+}
+
+template void init_me<int, float, double*>(int, float, double*);
+
+// Test parser and semantic recovery.
+template<int Value> struct count_ints_2 {
+ static const unsigned value = sizeof...(Value); // expected-error{{'Value' does not refer to the name of a parameter pack}}
+};
+
+template<typename ...Types> // expected-note{{parameter pack 'Types' declared here}}
+struct count_types_2 {
+ static const unsigned value = sizeof... Type; // expected-error{{missing parentheses around the size of parameter pack 'Type'}} \
+ // expected-error{{Type' does not refer to the name of a parameter pack; did you mean 'Types'?}}
+};
+
diff --git a/clang/test/CXX/expr/expr.unary/expr.unary.noexcept/cg.cpp b/clang/test/CXX/expr/expr.unary/expr.unary.noexcept/cg.cpp
new file mode 100644
index 0000000..5c1029f
--- /dev/null
+++ b/clang/test/CXX/expr/expr.unary/expr.unary.noexcept/cg.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -triple x86_64-apple-darwin10 -S -emit-llvm -std=c++11 -include %S/ser.h %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -triple x86_64-apple-darwin10 -emit-pch -o %t-ser.pch -std=c++11 -x c++ %S/ser.h
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -triple x86_64-apple-darwin10 -S -emit-llvm -std=c++11 -include-pch %t-ser.pch %s -o - | FileCheck %s
+
+struct D {
+ ~D() throw();
+};
+struct E {
+ ~E() throw();
+};
+
+void test() {
+ bool b;
+ // CHECK: store i8 1
+ b = noexcept(0);
+ // CHECK: store i8 0
+ b = noexcept(throw 0);
+ b = f1();
+ b = f2();
+
+ // CHECK-NOT: call void @_ZN1ED1Ev
+ // CHECK: call void @_ZN1DD1Ev
+ D(), noexcept(E());
+}
+// CHECK: ret i1 true
+// CHECK: ret i1 false
diff --git a/clang/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp b/clang/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp
new file mode 100644
index 0000000..b5de1a7
--- /dev/null
+++ b/clang/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp
@@ -0,0 +1,189 @@
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++11 -fms-extensions %s
+
+#define P(e) static_assert(noexcept(e), "expected nothrow")
+#define N(e) static_assert(!noexcept(e), "expected throw")
+#define B(b, e) static_assert(b == noexcept(e), "expectation failed")
+
+void simple() {
+ P(0);
+ P(0 + 0);
+ int i;
+ P(i);
+ P(sizeof(0));
+ P(static_cast<int>(0));
+ N(throw 0);
+ N((throw 0, 0));
+}
+
+void nospec();
+void allspec() throw(...);
+void intspec() throw(int);
+void emptyspec() throw();
+void nothrowattr() __attribute__((nothrow));
+void noexcept_true() noexcept;
+void noexcept_false() noexcept(false);
+
+void call() {
+ N(nospec());
+ N(allspec());
+ N(intspec());
+ P(emptyspec());
+ P(nothrowattr());
+ P(noexcept_true());
+ N(noexcept_false());
+}
+
+void (*pnospec)();
+void (*pallspec)() throw(...);
+void (*pintspec)() throw(int);
+void (*pemptyspec)() throw();
+
+void callptr() {
+ N(pnospec());
+ N((*pnospec)());
+ N(pallspec());
+ N((*pallspec)());
+ N(pintspec());
+ N((*pintspec)());
+ P(pemptyspec());
+ P((*pemptyspec)());
+}
+
+struct S1 {
+ void nospec();
+ void allspec() throw(...);
+ void intspec() throw(int);
+ void emptyspec() throw();
+};
+
+void callmem() {
+ S1 s;
+ N(s.nospec());
+ N(s.allspec());
+ N(s.intspec());
+ P(s.emptyspec());
+}
+
+void (S1::*mpnospec)();
+void (S1::*mpallspec)() throw(...);
+void (S1::*mpintspec)() throw(int);
+void (S1::*mpemptyspec)() throw();
+
+void callmemptr() {
+ S1 s;
+ N((s.*mpnospec)());
+ N((s.*mpallspec)());
+ N((s.*mpintspec)());
+ P((s.*mpemptyspec)());
+}
+
+struct S2 {
+ S2();
+ S2(int, int) throw();
+ void operator +();
+ void operator -() throw();
+ void operator +(int);
+ void operator -(int) throw();
+ operator int();
+ operator float() throw();
+};
+
+void *operator new(__typeof__(sizeof(int)) sz, int) throw();
+
+struct Bad1 {
+ ~Bad1() throw(int);
+};
+struct Bad2 {
+ void operator delete(void*) throw(int);
+};
+
+typedef int X;
+
+void implicits() {
+ N(new int);
+ P(new (0) int);
+ P(delete (int*)0);
+ N(delete (Bad1*)0);
+ N(delete (Bad2*)0);
+ N(S2());
+ P(S2(0, 0));
+ S2 s;
+ N(+s);
+ P(-s);
+ N(s + 0);
+ P(s - 0);
+ N(static_cast<int>(s));
+ P(static_cast<float>(s));
+ N(Bad1());
+ P(X().~X());
+}
+
+struct V {
+ virtual ~V() throw();
+};
+struct D : V {};
+
+void dyncast() {
+ V *pv = 0;
+ D *pd = 0;
+ P(dynamic_cast<V&>(*pd));
+ P(dynamic_cast<V*>(pd));
+ N(dynamic_cast<D&>(*pv));
+ P(dynamic_cast<D*>(pv));
+}
+
+namespace std {
+ struct type_info {};
+}
+
+void idtype() {
+ P(typeid(V));
+ P(typeid((V*)0));
+ P(typeid(*(S1*)0));
+ N(typeid(*(V*)0));
+}
+
+void uneval() {
+ P(sizeof(typeid(*(V*)0)));
+ P(typeid(typeid(*(V*)0)));
+}
+
+struct G1 {};
+struct G2 { int i; };
+struct G3 { S2 s; };
+
+void gencon() {
+ P(G1());
+ P(G2());
+ N(G3());
+}
+
+template <class T> void f(T&&) noexcept;
+template <typename T, bool b>
+void late() {
+ B(b, typeid(*(T*)0));
+ B(b, T(1));
+ B(b, static_cast<T>(S2(0, 0)));
+ B(b, S1() + T());
+ P(f(T()));
+ P(new (0) T);
+ P(delete (T*)0);
+}
+struct S3 {
+ virtual ~S3() throw();
+ S3() throw();
+ explicit S3(int);
+ S3(const S2&);
+};
+template <class T> T&& f2() noexcept;
+template <typename T>
+void late2() {
+ P(dynamic_cast<S3&>(f2<T&>()));
+}
+void operator +(const S1&, float) throw();
+void operator +(const S1&, const S3&);
+void tlate() {
+ late<float, true>();
+ late<S3, false>();
+ late2<S3>();
+}
diff --git a/clang/test/CXX/expr/expr.unary/expr.unary.noexcept/ser.h b/clang/test/CXX/expr/expr.unary/expr.unary.noexcept/ser.h
new file mode 100644
index 0000000..e6e7b79
--- /dev/null
+++ b/clang/test/CXX/expr/expr.unary/expr.unary.noexcept/ser.h
@@ -0,0 +1,8 @@
+// Serialization testing helper for noexcept, included by cg.cpp.
+
+inline bool f1() {
+ return noexcept(0);
+}
+inline bool f2() {
+ return noexcept(throw 0);
+}
diff --git a/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
new file mode 100644
index 0000000..2dd6b23
--- /dev/null
+++ b/clang/test/CXX/expr/expr.unary/expr.unary.op/p3.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fsyntax-only %s -verify
+
+namespace rdar10544564 {
+ // Check that we don't attempt to use an overloaded operator& when
+ // naming a pointer-to-member.
+ struct X {
+ void** operator & ();
+ };
+
+ struct Y
+ {
+ public:
+ X member;
+ X memfunc1();
+ X memfunc2();
+ X memfunc2(int);
+
+ void test() {
+ X Y::*data_mem_ptr = &Y::member;
+ X (Y::*func_mem_ptr1)() = &Y::memfunc1;
+ X (Y::*func_mem_ptr2)() = &Y::memfunc2;
+ }
+ };
+
+ X Y::*data_mem_ptr = &Y::member;
+ X (Y::*func_mem_ptr1)() = &Y::memfunc1;
+ X (Y::*func_mem_ptr2)() = &Y::memfunc2;
+}
diff --git a/clang/test/CXX/expr/expr.unary/expr.unary.op/p4.cpp b/clang/test/CXX/expr/expr.unary/expr.unary.op/p4.cpp
new file mode 100644
index 0000000..06cc610
--- /dev/null
+++ b/clang/test/CXX/expr/expr.unary/expr.unary.op/p4.cpp
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// rdar://problem/8347416
+namespace test0 {
+ struct A {
+ void foo(void (A::*)(int)); // expected-note {{passing argument to parameter here}}
+ template<typename T> void g(T);
+
+ void test() {
+ foo(&g<int>); // expected-error {{can't form member pointer of type 'void (test0::A::*)(int)' without '&' and class name}}
+ }
+ };
+}
+
+// This should succeed.
+namespace test1 {
+ struct A {
+ static void f(void (A::*)());
+ static void f(void (*)(int));
+ void g();
+ static void g(int);
+
+ void test() {
+ f(&g);
+ }
+ };
+}
+
+// Also rdar://problem/8347416
+namespace test2 {
+ struct A {
+ static int foo(short);
+ static int foo(float);
+ int foo(int);
+ int foo(double);
+
+ void test();
+ };
+
+ void A::test() {
+ int (A::*ptr)(int) = &(A::foo); // expected-error {{can't form member pointer of type 'int (test2::A::*)(int)' without '&' and class name}}
+ }
+}
diff --git a/clang/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp b/clang/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp
new file mode 100644
index 0000000..ac11940
--- /dev/null
+++ b/clang/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// -- prvalue of arithmetic
+
+bool b = !0;
+
+bool b2 = !1.2;
+
+bool b3 = !4;
+
+// -- unscoped enumeration
+enum { E, F };
+
+bool b4 = !E;
+bool b5 = !F;
+
+// -- pointer,
+bool b6 = !&b4;
+void f();
+bool b61 = !&f;
+
+// -- or pointer to member type can be converted to a prvalue of type bool.
+struct S { void f() { } };
+
+bool b7 = !&S::f;
+
+
+bool b8 = !S(); //expected-error {{invalid argument type 'S'}}
+
+namespace PR8181
+{
+ bool f() { } // expected-note{{possible target for call}}
+ void f(char) { } // expected-note{{possible target for call}}
+ bool b = !&f; //expected-error {{reference to overloaded function could not be resolved; did you mean to call it with no arguments?}}
+}