Files
clang-p2996/clang/test/CXX/except/except.spec/p5-pointers.cpp
Richard Smith e15a370084 PR25890: Fix incoherent error handling in PerformImplicitConversion and
CheckSingleAssignmentConstraints. These no longer produce ExprError() when they
have not emitted an error, and reliably inform the caller when they *have*
emitted an error.

This fixes some serious issues where we would fail to emit any diagnostic for
invalid code and then attempt to emit code for an invalid AST, and conversely
some issues where we would emit two diagnostics for the same problem.

llvm-svn: 283508
2016-10-06 23:12:58 +00:00

86 lines
2.6 KiB
C++

// RUN: %clang_cc1 -std=c++11 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s
// Assignment of function pointers.
struct A
{
};
struct B1 : A
{
};
struct B2 : A
{
};
struct D : B1, B2
{
};
struct P : private A
{
};
// Some functions to play with below.
void s1() throw();
void s2() throw(int);
void s3() throw(A);
void s4() throw(B1);
void s5() throw(D);
void s6();
void s7() throw(int, float);
void (*s8())() throw(B1); // s8 returns a pointer to function with spec
void s9(void (*)() throw(B1)); // s9 takes pointer to function with spec
void s10() noexcept;
void s11() noexcept(true);
void s12() noexcept(false);
void fnptrs()
{
// Assignment and initialization of function pointers.
void (*t1)() throw() = &s1; // valid
t1 = &s2; // expected-error {{not superset}}
t1 = &s3; // expected-error {{not superset}}
void (&t2)() throw() = s2; // expected-error {{not superset}}
void (*t3)() throw(int) = &s2; // valid
void (*t4)() throw(A) = &s1; // valid
t4 = &s3; // valid
t4 = &s4; // valid
t4 = &s5; // expected-error {{not superset}}
void (*t5)() = &s1; // valid
t5 = &s2; // valid
t5 = &s6; // valid
t5 = &s7; // valid
t1 = t3; // expected-error {{not superset}}
t3 = t1; // valid
void (*t6)() throw(B1);
t6 = t4; // expected-error {{not superset}}
t4 = t6; // valid
t5 = t1; // valid
t1 = t5; // expected-error {{not superset}}
// return types and arguments must match exactly, no inheritance allowed
void (*(*t7)())() throw(B1) = &s8; // valid
void (*(*t8)())() throw(A) = &s8; // expected-error {{return types differ}}
void (*(*t9)())() throw(D) = &s8; // expected-error {{return types differ}}
void (*t10)(void (*)() throw(B1)) = &s9; // valid
void (*t11)(void (*)() throw(A)) = &s9; // expected-error {{argument types differ}}
void (*t12)(void (*)() throw(D)) = &s9; // expected-error {{argument types differ}}
}
// Member function stuff
struct Str1 { void f() throw(int); }; // expected-note {{previous declaration}}
void Str1::f() // expected-error {{missing exception specification}}
{
}
void mfnptr()
{
void (Str1::*pfn1)() throw(int) = &Str1::f; // valid
void (Str1::*pfn2)() = &Str1::f; // valid
void (Str1::*pfn3)() throw() = &Str1::f; // expected-error {{not superset}}
}