[llvm-branch-commits] [clang] 293a245 - Merging r372178:

Tom Stellard via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Nov 25 09:06:32 PST 2019


Author: Reid Kleckner
Date: 2019-11-25T08:46:15-08:00
New Revision: 293a245241d3ecadd5dea85e3f5760b2f10c3e9f

URL: https://github.com/llvm/llvm-project/commit/293a245241d3ecadd5dea85e3f5760b2f10c3e9f
DIFF: https://github.com/llvm/llvm-project/commit/293a245241d3ecadd5dea85e3f5760b2f10c3e9f.diff

LOG: 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 at google.com>!

Differential Revision: https://reviews.llvm.org/D67590
------------------------------------------------------------------------

Added: 
    

Modified: 
    clang/lib/Sema/SemaDecl.cpp
    clang/test/SemaCXX/ms-exception-spec.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 8f19edbc4f36..a8ee656dced8 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -3475,7 +3475,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 07633791b9f3..1a4c9fdc33e3 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-extensions -fexceptions -fcxx-exceptions
+// RUN: %clang_cc1 -std=c++11 %s -fsyntax-only -verify -fms-extensions -fexceptions -fcxx-exceptions
+// RUN: %clang_cc1 -std=c++17 %s -fsyntax-only -verify -fms-extensions -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 at +3 {{ISO C++17 does not allow dynamic exception specifications}}
+// expected-note at +2 {{use 'noexcept(false)' instead}}
+#endif
 void f() throw(...) { }
 
 namespace PR28080 {
 struct S;           // expected-note {{forward declaration}}
+#if __cplusplus >= 201703L
+// expected-error at +3 {{ISO C++17 does not allow dynamic exception specifications}}
+// expected-note at +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 at +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}}


        


More information about the llvm-branch-commits mailing list