diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-08-30 15:04:51 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-08-30 15:04:51 +0000 |
commit | 5b6f769a6abda4da44186cc8e6a2d6ed37dc9344 (patch) | |
tree | e1c3c2d8b92c74dba1ba47a097fba1906884aa96 | |
parent | a75ec43d625753b4439b0d6f70bd988444c74617 (diff) |
Emulate (some of) Microsoft's looser semantic checking of exception
specifications, from Martin Vejnar!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@112482 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/SemaExceptionSpec.cpp | 8 | ||||
-rw-r--r-- | test/SemaCXX/MicrosoftExtensions.cpp | 26 | ||||
-rw-r--r-- | test/SemaCXX/exception-spec.cpp | 12 |
3 files changed, 34 insertions, 12 deletions
diff --git a/lib/Sema/SemaExceptionSpec.cpp b/lib/Sema/SemaExceptionSpec.cpp index 101d741724..c902e77870 100644 --- a/lib/Sema/SemaExceptionSpec.cpp +++ b/lib/Sema/SemaExceptionSpec.cpp @@ -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) { diff --git a/test/SemaCXX/MicrosoftExtensions.cpp b/test/SemaCXX/MicrosoftExtensions.cpp index c143e59fb3..48d4194197 100644 --- a/test/SemaCXX/MicrosoftExtensions.cpp +++ b/test/SemaCXX/MicrosoftExtensions.cpp @@ -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(); +}; diff --git a/test/SemaCXX/exception-spec.cpp b/test/SemaCXX/exception-spec.cpp index 498611ee85..b4bc78aa9a 100644 --- a/test/SemaCXX/exception-spec.cpp +++ b/test/SemaCXX/exception-spec.cpp @@ -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); |