Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -1403,6 +1403,11 @@ "virtual function %0 has different calling convention attributes " "%diff{($) than the function it overrides (which has calling convention $)|" "than the function it overrides}1,2">; +def warn_conflicting_overriding_cc_attributes : Warning< + "virtual function %0 has different calling convention attributes " + "%diff{($) than the function it overrides (which has calling convention $)|" + "than the function it overrides}1,2. New attribute ignored.">, + InGroup<IgnoredAttributes>; def err_covariant_return_inaccessible_base : Error< "invalid covariant return for virtual function: %1 is a " Index: lib/Sema/SemaDeclCXX.cpp =================================================================== --- lib/Sema/SemaDeclCXX.cpp +++ lib/Sema/SemaDeclCXX.cpp @@ -12933,9 +12933,16 @@ if (New->getStorageClass() == SC_Static) return false; - Diag(New->getLocation(), - diag::err_conflicting_overriding_cc_attributes) - << New->getDeclName() << New->getType() << Old->getType(); + // vswriter.h header from Windows SDK violates this. Thus, we should just + // warn, not error on Windows. + if (getLangOpts().MSVCCompat) + Diag(New->getLocation(), + diag::warn_conflicting_overriding_cc_attributes) + << New->getDeclName() << New->getType() << Old->getType(); + else + Diag(New->getLocation(), + diag::err_conflicting_overriding_cc_attributes) + << New->getDeclName() << New->getType() << Old->getType(); Diag(Old->getLocation(), diag::note_overridden_virtual_function); return true; } Index: test/SemaCXX/virtual-override-x86.cpp =================================================================== --- test/SemaCXX/virtual-override-x86.cpp +++ test/SemaCXX/virtual-override-x86.cpp @@ -1,4 +1,7 @@ -// RUN: %clang_cc1 -triple=i686-pc-win32 -fsyntax-only -verify %s -std=c++11 +// RUN: %clang_cc1 -triple=i686-pc-win32 -fsyntax-only -verify %s -std=c++11 -DTEST1 +// RUN: %clang_cc1 -triple=i386-pc-win32 -fms-compatibility -fsyntax-only -verify %s -std=c++11 -DTEST2 + +#ifdef TEST1 namespace PR14339 { class A { @@ -31,3 +34,23 @@ void g(); // expected-error{{virtual function 'g' has different calling convention attributes ('void () __attribute__((thiscall))') than the function it overrides (which has calling convention 'void () __attribute__((stdcall))'}} }; } + +#elif TEST2 + +// PR24595: This code is present in vswriter.h header file from Windows SDK 8.1. +// We should be able to compile it in 32 bit mode. +class CVssWriter +{ +public: + __stdcall CVssWriter() {} + virtual __stdcall ~CVssWriter() {} // expected-note {{overridden virtual function is here}} +}; + +class CVssWriterEx : public CVssWriter // expected-warning {{virtual function '~CVssWriterEx' has different calling convention attributes ('void () __attribute__((thiscall))') than the function it overrides (which has calling convention 'void () __attribute__((stdcall)) noexcept'). New attribute ignored.}} +{}; + +#else + +#error Unknown test + +#endif