summaryrefslogtreecommitdiffstats
path: root/clang/test
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-10-20 08:26:51 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-10-20 08:26:51 +0000
commit66f3ac9d21978f378cb0d490d2935833c730f9ba (patch)
treeacba658673ac5f2199598a140fef85ee0f325841 /clang/test
parentd189b82a9b92bd1f375fc9a942773aeb5b266765 (diff)
downloadbcm5719-llvm-66f3ac9d21978f378cb0d490d2935833c730f9ba.tar.gz
bcm5719-llvm-66f3ac9d21978f378cb0d490d2935833c730f9ba.zip
Rework implementation of DR1492: Apply the resolution to operator delete too,
since it also has an implicit exception specification. Downgrade the error to an extwarn, since at least for operator delete, system headers like to declare it as 'noexcept' whereas the implicit definition does not have an explicit exception specification. Move the exception specification for user-declared 'operator delete' functions from the type-as-written into the type, to reflect reality and to allow us to detect whether there was an implicit exception spec or not. llvm-svn: 166372
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/CXX/except/except.spec/p15.cpp14
-rw-r--r--clang/test/CXX/except/except.spec/p4.cpp36
-rw-r--r--clang/test/CXX/special/class.dtor/p3.cpp4
3 files changed, 47 insertions, 7 deletions
diff --git a/clang/test/CXX/except/except.spec/p15.cpp b/clang/test/CXX/except/except.spec/p15.cpp
index 110ec3fa030..fcf12357f91 100644
--- a/clang/test/CXX/except/except.spec/p15.cpp
+++ b/clang/test/CXX/except/except.spec/p15.cpp
@@ -9,16 +9,20 @@ void f() {
delete[] new int[1];
}
-void operator delete(void*) noexcept;
-void operator delete[](void*) noexcept;
+void operator delete(void*);
+void operator delete[](void*);
+
+static_assert(noexcept(operator delete(0)), "");
+static_assert(noexcept(operator delete[](0)), "");
// Same goes for explicit declarations.
void operator delete(void*, float);
-void operator delete(void*, float) noexcept;
-
void operator delete[](void*, float);
-void operator delete[](void*, float) noexcept;
+
+static_assert(noexcept(operator delete(0, 0.f)), "");
+static_assert(noexcept(operator delete[](0, 0.f)), "");
// But explicit specs stay.
void operator delete(void*, double) throw(int); // expected-note {{previous}}
+static_assert(!noexcept(operator delete(0, 0.)), "");
void operator delete(void*, double) noexcept; // expected-error {{does not match}}
diff --git a/clang/test/CXX/except/except.spec/p4.cpp b/clang/test/CXX/except/except.spec/p4.cpp
new file mode 100644
index 00000000000..1bf70188031
--- /dev/null
+++ b/clang/test/CXX/except/except.spec/p4.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -std=c++11 %s -verify -fcxx-exceptions
+
+// We permit overriding an implicit exception specification with an explicit one
+// as an extension, for compatibility with existing code.
+
+struct S {
+ void a(); // expected-note {{here}}
+ ~S(); // expected-note {{here}}
+ void operator delete(void*); // expected-note {{here}}
+};
+
+void S::a() noexcept {} // expected-error {{does not match previous}}
+S::~S() noexcept {} // expected-warning {{function previously declared with an implicit exception specification redeclared with an explicit exception specification}}
+void S::operator delete(void*) noexcept {} // expected-warning {{function previously declared with an implicit exception specification redeclared with an explicit exception specification}}
+
+struct T {
+ void a() noexcept; // expected-note {{here}}
+ ~T() noexcept; // expected-note {{here}}
+ void operator delete(void*) noexcept; // expected-note {{here}}
+};
+
+void T::a() {} // expected-warning {{missing exception specification 'noexcept'}}
+T::~T() {} // expected-warning {{function previously declared with an explicit exception specification redeclared with an implicit exception specification}}
+void T::operator delete(void*) {} // expected-warning {{function previously declared with an explicit exception specification redeclared with an implicit exception specification}}
+
+
+// The extension does not extend to function templates.
+
+template<typename T> struct U {
+ T t;
+ ~U(); // expected-note {{here}}
+ void operator delete(void*); // expected-note {{here}}
+};
+
+template<typename T> U<T>::~U() noexcept(true) {} // expected-error {{exception specification in declaration does not match previous declaration}}
+template<typename T> void U<T>::operator delete(void*) noexcept(false) {} // expected-error {{exception specification in declaration does not match previous declaration}}
diff --git a/clang/test/CXX/special/class.dtor/p3.cpp b/clang/test/CXX/special/class.dtor/p3.cpp
index c3a292d50c2..6f4d5c7f318 100644
--- a/clang/test/CXX/special/class.dtor/p3.cpp
+++ b/clang/test/CXX/special/class.dtor/p3.cpp
@@ -4,10 +4,10 @@
// the exception specification adjustment occurs.
namespace DR1492 {
struct A { ~A(); }; // expected-note {{here}}
- A::~A() noexcept {} // expected-error {{does not match previous declaration}}
+ A::~A() noexcept {} // expected-warning {{previously declared with an implicit exception specification}}
struct B { ~B() noexcept; }; // expected-note {{here}}
- B::~B() {} // expected-warning {{~B' is missing exception specification 'noexcept'}}
+ B::~B() {} // expected-warning {{previously declared with an explicit exception specification}}
template<typename T> struct C {
T t;
OpenPOWER on IntegriCloud