2019-05-31 01:31:54 +08:00
// RUN: %clang_cc1 %s -fcxx-exceptions -fdeclspec -fsyntax-only -Wexceptions -verify -std=c++14
// RUN: %clang_cc1 %s -fcxx-exceptions -fdeclspec -fsyntax-only -Wexceptions -verify -std=c++17 -DCPP17
__attribute__ ( ( nothrow ) ) void f1 ( ) ;
static_assert ( noexcept ( f1 ( ) ) , " " ) ;
void f1 ( ) noexcept ;
// expected-error@+2 {{exception specification in declaration does not match previous declaration}}
// expected-note@-2 {{previous declaration is here}}
void f1 ( ) noexcept ( false ) ;
__attribute__ ( ( nothrow ) ) void f2 ( ) ;
static_assert ( noexcept ( f2 ( ) ) , " " ) ;
// expected-error@+2 {{exception specification in declaration does not match previous declaration}}
// expected-note@-3 {{previous declaration is here}}
void f2 ( ) noexcept ( false ) ;
void f3 ( ) __attribute__ ( ( nothrow ) ) ;
static_assert ( noexcept ( f3 ( ) ) , " " ) ;
void f3 ( ) noexcept ;
// expected-error@+2 {{exception specification in declaration does not match previous declaration}}
// expected-note@-2 {{previous declaration is here}}
void f3 ( ) noexcept ( false ) ;
// Still noexcept due to throw()
__attribute__ ( ( nothrow ) ) void f4 ( ) throw ( ) ;
static_assert ( noexcept ( f4 ( ) ) , " " ) ;
// Still noexcept due to noexcept
__attribute__ ( ( nothrow ) ) void f5 ( ) noexcept ;
static_assert ( noexcept ( f5 ( ) ) , " " ) ;
// Still noexcept due to noexcept(true)
__attribute__ ( ( nothrow ) ) void f6 ( ) noexcept ( true ) ;
static_assert ( noexcept ( f6 ( ) ) , " " ) ;
# ifndef CPP17
// Doesn't override C++ implementation.
// expected-warning@+1{{'nothrow' attribute conflicts with exception specification; attribute ignored}}
__attribute__ ( ( nothrow ) ) void f7 ( ) throw ( int ) ;
static_assert ( ! noexcept ( f7 ( ) ) , " " ) ;
# endif
// Doesn't override C++ implementation.
// expected-warning@+1{{'nothrow' attribute conflicts with exception specification; attribute ignored}}
__attribute__ ( ( nothrow ) ) void f8 ( ) noexcept ( false ) ;
static_assert ( ! noexcept ( f8 ( ) ) , " " ) ;
__declspec ( nothrow ) void foo1 ( ) noexcept ;
__declspec ( nothrow ) void foo2 ( ) noexcept ( true ) ;
// expected-warning@+1{{'nothrow' attribute conflicts with exception specification; attribute ignored}}
__declspec ( nothrow ) void foo3 ( ) noexcept ( false ) ;
__declspec ( nothrow ) void foo4 ( ) noexcept ( noexcept ( foo1 ( ) ) ) ;
__declspec ( nothrow ) void foo5 ( ) noexcept ( noexcept ( foo2 ( ) ) ) ;
// expected-warning@+1{{'nothrow' attribute conflicts with exception specification; attribute ignored}}
__declspec ( nothrow ) void foo6 ( ) noexcept ( noexcept ( foo3 ( ) ) ) ;
2019-05-31 23:56:27 +08:00
2019-06-01 00:46:38 +08:00
template < typename F >
__declspec ( nothrow ) void foo7 ( ) noexcept ( noexcept ( F ( ) ) ) ;
2019-05-31 23:56:27 +08:00
// FIXME: It would be nice to be able to warn on these, however at the time we
// evaluate the nothrow, these have yet to be parsed, so the data is not yet
// there.
struct S {
__declspec ( nothrow ) void f1 ( ) ;
# ifndef CPP17
__declspec ( nothrow ) void f2 ( ) throw ( ) ;
__declspec ( nothrow ) void f3 ( ) throw ( int ) ;
# endif
__declspec ( nothrow ) void f4 ( ) noexcept ( true ) ;
__declspec ( nothrow ) void f5 ( ) noexcept ( false ) ;
} ;
2019-06-04 02:36:26 +08:00
namespace PR42100 {
class Base {
public :
// expected-note@+1{{overridden virtual function is here}}
virtual __declspec ( nothrow ) void foo ( ) = 0 ;
// expected-note@+1{{previous declaration is here}}
__declspec ( nothrow ) void bar ( ) ;
} ;
// expected-warning@+1{{'bar' is missing exception specification '__attribute__((nothrow))'}}
void Base : : bar ( ) { }
class Sub : public Base {
public :
// expected-warning@+1{{exception specification of overriding function is more lax than base version}}
void foo ( ) { }
} ;
}
2019-06-04 02:36:33 +08:00
2019-06-04 03:57:52 +08:00
namespace FuncPointerReferenceConverts {
2019-06-04 02:36:33 +08:00
void FuncToBeRefed ( ) ;
# ifndef CPP17
// expected-error@+6{{target exception specification is not superset of source}}
// expected-error@+6{{target exception specification is not superset of source}}
# else
// expected-error@+3{{non-const lvalue reference to type 'void () __attribute__((nothrow))' cannot bind to a value of unrelated type 'void ()'}}
// expected-error@+3{{cannot initialize a variable of type 'void (*)() __attribute__((nothrow))' with an lvalue of type 'void ()': different exception specifications}}
# endif
__declspec ( nothrow ) void ( & FuncRef ) ( ) = FuncToBeRefed ;
__declspec ( nothrow ) void ( * FuncPtr ) ( ) = FuncToBeRefed ;
}