aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-08-30 15:04:51 +0000
committerDouglas Gregor <dgregor@apple.com>2010-08-30 15:04:51 +0000
commit5b6f769a6abda4da44186cc8e6a2d6ed37dc9344 (patch)
treee1c3c2d8b92c74dba1ba47a097fba1906884aa96
parenta75ec43d625753b4439b0d6f70bd988444c74617 (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.cpp8
-rw-r--r--test/SemaCXX/MicrosoftExtensions.cpp26
-rw-r--r--test/SemaCXX/exception-spec.cpp12
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);