Files
clang-p2996/clang/test/CXX/except/except.spec/p4.cpp
Richard Smith a91de375f2 Promote a warning on ill-formed code (redeclaration missing an exception
specification) to an error. No compiler other than Clang seems to allow this,
and it doesn't seem like a useful thing to accept as an extension in general.

The current behavior was added for PR5957, where the problem was specifically
related to mismatches of the exception specification on the implicitly-declared
global operator new and delete. To retain that workaround, we downgrade the
error to an ExtWarn when the declaration is of a replaceable global allocation
function.

Now that this is an error, stop trying (and failing) to recover from a missing
computed noexcept specification. That recovery didn't work, and led to crashes
in code like the added testcase.

llvm-svn: 248867
2015-09-30 00:48:50 +00:00

42 lines
2.0 KiB
C++

// 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-error {{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}}
// Make sure this restriction interacts properly with __attribute__((noreturn))
void __attribute__ ((__noreturn__)) PR17110(int status) throw();
void PR17110(int status) throw();