summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp7
-rw-r--r--clang/test/SemaCXX/ms-exception-spec.cpp29
2 files changed, 34 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index dfa5647e9df..dead3b69bbd 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -3562,7 +3562,12 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD,
}
}
- if (OldQTypeForComparison == NewQType)
+ // If the function types are compatible, merge the declarations. Ignore the
+ // exception specifier because it was already checked above in
+ // CheckEquivalentExceptionSpec, and we don't want follow-on diagnostics
+ // about incompatible types under -fms-compatibility.
+ if (Context.hasSameFunctionTypeIgnoringExceptionSpec(OldQTypeForComparison,
+ NewQType))
return MergeCompatibleFunctionDecls(New, Old, S, MergeTypeWithOld);
// If the types are imprecise (due to dependent constructs in friends or
diff --git a/clang/test/SemaCXX/ms-exception-spec.cpp b/clang/test/SemaCXX/ms-exception-spec.cpp
index 60bfeba037a..cf460356c97 100644
--- a/clang/test/SemaCXX/ms-exception-spec.cpp
+++ b/clang/test/SemaCXX/ms-exception-spec.cpp
@@ -1,9 +1,36 @@
-// RUN: %clang_cc1 %s -fsyntax-only -verify -fms-compatibility -fexceptions -fcxx-exceptions
+// RUN: %clang_cc1 -std=c++11 %s -fsyntax-only -verify -fms-compatibility -fexceptions -fcxx-exceptions
+// RUN: %clang_cc1 -std=c++17 %s -fsyntax-only -verify -fms-compatibility -fexceptions -fcxx-exceptions
+// FIXME: Should -fms-compatibility soften these errors into warnings to match
+// MSVC? In practice, MSVC never implemented dynamic exception specifiers, so
+// there isn't much Windows code in the wild that uses them.
+#if __cplusplus >= 201703L
+// expected-error@+3 {{ISO C++17 does not allow dynamic exception specifications}}
+// expected-note@+2 {{use 'noexcept(false)' instead}}
+#endif
void f() throw(...) { }
namespace PR28080 {
struct S; // expected-note {{forward declaration}}
+#if __cplusplus >= 201703L
+// expected-error@+3 {{ISO C++17 does not allow dynamic exception specifications}}
+// expected-note@+2 {{use 'noexcept(false)' instead}}
+#endif
void fn() throw(S); // expected-warning {{incomplete type}} expected-note{{previous declaration}}
void fn() throw(); // expected-warning {{does not match previous declaration}}
}
+
+template <typename T> struct FooPtr {
+ template <typename U> FooPtr(U *p) : m_pT(nullptr) {}
+
+ template <>
+ // FIXME: It would be better if this note pointed at the primary template
+ // above.
+ // expected-note@+1 {{previous declaration is here}}
+ FooPtr(T *pInterface) throw() // expected-warning {{exception specification in declaration does not match previous declaration}}
+ : m_pT(pInterface) {}
+
+ T *m_pT;
+};
+struct Bar {};
+template struct FooPtr<Bar>; // expected-note {{requested here}}
OpenPOWER on IntegriCloud