Emulate (some of) Microsoft's looser semantic checking of exception

specifications, from Martin Vejnar!

llvm-svn: 112482
This commit is contained in:
Douglas Gregor 2010-08-30 15:04:51 +00:00
parent 759ef23bb8
commit f62c5294c1
3 changed files with 34 additions and 12 deletions

View File

@ -261,6 +261,14 @@ bool Sema::CheckEquivalentExceptionSpec(const PartialDiagnostic &DiagID,
bool OldAny = !Old->hasExceptionSpec() || Old->hasAnyExceptionSpec();
bool NewAny = !New->hasExceptionSpec() || New->hasAnyExceptionSpec();
if (getLangOptions().Microsoft) {
// Treat throw(whatever) as throw(...) to be compatible with MS headers.
if (New->hasExceptionSpec() && New->getNumExceptions() > 0)
NewAny = true;
if (Old->hasExceptionSpec() && Old->getNumExceptions() > 0)
OldAny = true;
}
if (OldAny && NewAny)
return false;
if (OldAny || NewAny) {

View File

@ -1,7 +1,31 @@
// RUN: %clang_cc1 %s -fsyntax-only -verify -fms-extensions
// RUN: %clang_cc1 %s -fsyntax-only -verify -fms-extensions -fexceptions
// ::type_info is predeclared with forward class declartion
void f(const type_info &a);
// The following three are all equivalent when ms-extensions are on
void foo() throw(int);
void foo() throw(int, long);
void foo() throw(...);
void foo(); // expected-note {{previous declaration}}
// Only nothrow specification is treated specially.
void foo() throw(); // expected-error {{exception specification in declaration does not match previous declaration}}
// throw(...)
void r3();
void r3() throw(...);
void r6() throw(...);
void r6() throw(int); // okay
struct Base {
virtual void f2();
virtual void f3() throw(...);
};
struct Derived : Base {
virtual void f2() throw(...);
virtual void f3();
};

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -fsyntax-only -verify -fexceptions -fms-extensions %s
// RUN: %clang_cc1 -fsyntax-only -verify -fexceptions %s
// Straight from the standard:
// Plain function with spec
@ -43,18 +43,12 @@ void r2() throw(int);
void r2() throw(INT);
// throw-any spec and no spec at all are semantically equivalent
void r3();
void r3() throw(...);
void r4() throw(int, float);
void r4() throw(float, int);
void r5() throw(int); // expected-note {{previous declaration}}
void r5(); // expected-warning {{missing exception specification}}
void r6() throw(...); // expected-note {{previous declaration}}
void r6() throw(int); // expected-error {{exception specification in declaration does not match}}
void r7() throw(int); // expected-note {{previous declaration}}
void r7() throw(float); // expected-error {{exception specification in declaration does not match}}
@ -89,8 +83,6 @@ struct P : private A
struct Base
{
virtual void f1() throw();
virtual void f2();
virtual void f3() throw(...);
virtual void f4() throw(int, float);
virtual void f5() throw(int, float);
@ -107,8 +99,6 @@ struct Base
struct Derived : Base
{
virtual void f1() throw();
virtual void f2() throw(...);
virtual void f3();
virtual void f4() throw(float, int);
virtual void f5() throw(float);