Skip to content

Commit 293a245

Browse files
rnktstellar
authored andcommitted
Merging r372178:
------------------------------------------------------------------------ r372178 | rnk | 2019-09-17 13:29:10 -0700 (Tue, 17 Sep 2019) | 15 lines Ignore exception specifier mismatch when merging redeclarations Exception specifiers are now part of the function type in C++17. Normally, it is illegal to redeclare the same function or specialize a template with a different exception specifier, but under -fms-compatibility, we accept it with a warning. Without this change, the function types would not match due to the exception specifier, and clang would claim that the types were "incompatible". Now we emit the warning and merge the redeclaration as we would in C++14 and earlier. Fixes PR42842, which is about compiling _com_ptr_t in C++17. Based on a patch by Alex Fusco <alexfusco@google.com>! Differential Revision: https://reviews.llvm.org/D67590 ------------------------------------------------------------------------
1 parent aa0ed8d commit 293a245

File tree

2 files changed

+34
-2
lines changed

2 files changed

+34
-2
lines changed

clang/lib/Sema/SemaDecl.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3475,7 +3475,12 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD,
34753475
}
34763476
}
34773477

3478-
if (OldQTypeForComparison == NewQType)
3478+
// If the function types are compatible, merge the declarations. Ignore the
3479+
// exception specifier because it was already checked above in
3480+
// CheckEquivalentExceptionSpec, and we don't want follow-on diagnostics
3481+
// about incompatible types under -fms-compatibility.
3482+
if (Context.hasSameFunctionTypeIgnoringExceptionSpec(OldQTypeForComparison,
3483+
NewQType))
34793484
return MergeCompatibleFunctionDecls(New, Old, S, MergeTypeWithOld);
34803485

34813486
// If the types are imprecise (due to dependent constructs in friends or
Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,36 @@
1-
// RUN: %clang_cc1 %s -fsyntax-only -verify -fms-extensions -fexceptions -fcxx-exceptions
1+
// RUN: %clang_cc1 -std=c++11 %s -fsyntax-only -verify -fms-extensions -fexceptions -fcxx-exceptions
2+
// RUN: %clang_cc1 -std=c++17 %s -fsyntax-only -verify -fms-extensions -fexceptions -fcxx-exceptions
23

4+
// FIXME: Should -fms-compatibility soften these errors into warnings to match
5+
// MSVC? In practice, MSVC never implemented dynamic exception specifiers, so
6+
// there isn't much Windows code in the wild that uses them.
7+
#if __cplusplus >= 201703L
8+
// expected-error@+3 {{ISO C++17 does not allow dynamic exception specifications}}
9+
// expected-note@+2 {{use 'noexcept(false)' instead}}
10+
#endif
311
void f() throw(...) { }
412

513
namespace PR28080 {
614
struct S; // expected-note {{forward declaration}}
15+
#if __cplusplus >= 201703L
16+
// expected-error@+3 {{ISO C++17 does not allow dynamic exception specifications}}
17+
// expected-note@+2 {{use 'noexcept(false)' instead}}
18+
#endif
719
void fn() throw(S); // expected-warning {{incomplete type}} expected-note{{previous declaration}}
820
void fn() throw(); // expected-warning {{does not match previous declaration}}
921
}
22+
23+
template <typename T> struct FooPtr {
24+
template <typename U> FooPtr(U *p) : m_pT(nullptr) {}
25+
26+
template <>
27+
// FIXME: It would be better if this note pointed at the primary template
28+
// above.
29+
// expected-note@+1 {{previous declaration is here}}
30+
FooPtr(T *pInterface) throw() // expected-warning {{exception specification in declaration does not match previous declaration}}
31+
: m_pT(pInterface) {}
32+
33+
T *m_pT;
34+
};
35+
struct Bar {};
36+
template struct FooPtr<Bar>; // expected-note {{requested here}}

0 commit comments

Comments
 (0)