From 7a4b8b04847231c6e2359949eee931699276f9b9 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Sat, 21 Feb 2015 01:07:24 +0000 Subject: [PATCH] Improve diagnostic when failing to synthesize implicit member due to dllexport (PR22591) This is only a problem in C++03 mode targeting MS ABI (MinGW doesn't export inline methods, and C++11 marks these methods implicitly deleted). Since targeting the MS ABI in pre-C++11 mode is a rare configuration, this will probably not get fixed, but we can at least have a better error message. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@230115 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 2 ++ lib/Sema/SemaDeclCXX.cpp | 6 ++++++ test/SemaCXX/dllexport-pr22591.cpp | 13 +++++++++++-- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 83b7a58f2e..c402e24a52 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -1302,6 +1302,8 @@ def err_missing_default_ctor : Error< "%select{|implicit default |inheriting }0constructor for %1 must explicitly " "initialize the %select{base class|member}2 %3 which does not have a default " "constructor">; +def note_due_to_dllexported_class : Note< + "due to '%0' being dllexported%select{|; try compiling in C++11 mode}1">; def err_illegal_union_or_anon_struct_member : Error< "%select{anonymous struct|union}0 member %1 has a non-trivial " diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 33f8c91691..4d2e87798f 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -4821,7 +4821,13 @@ static void checkDLLAttribute(Sema &S, CXXRecordDecl *Class) { // defaulted methods, and the copy and move assignment operators. The // latter are exported even if they are trivial, because the address of // an operator can be taken and should compare equal accross libraries. + DiagnosticErrorTrap Trap(S.Diags); S.MarkFunctionReferenced(Class->getLocation(), MD); + if (Trap.hasErrorOccurred()) { + S.Diag(ClassAttr->getLocation(), diag::note_due_to_dllexported_class) + << Class->getName() << !S.getLangOpts().CPlusPlus11; + break; + } // There is no later point when we will see the definition of this // function, so pass it to the consumer now. diff --git a/test/SemaCXX/dllexport-pr22591.cpp b/test/SemaCXX/dllexport-pr22591.cpp index af75e4fe64..9d9fc84845 100644 --- a/test/SemaCXX/dllexport-pr22591.cpp +++ b/test/SemaCXX/dllexport-pr22591.cpp @@ -1,16 +1,25 @@ // RUN: %clang_cc1 -triple i686-windows-gnu -verify -std=c++03 %s // RUN: %clang_cc1 -triple i686-windows-gnu -verify -std=c++11 %s +// RUN: %clang_cc1 -triple i686-windows-msvc -verify -std=c++03 -DERROR %s // RUN: %clang_cc1 -triple i686-windows-msvc -verify -std=c++11 %s -// FIXME: For C++03 MS ABI we erroneously try to synthesize default ctor, etc. for S. - +#ifndef ERROR // expected-no-diagnostics +#endif struct NonCopyable { private: +#ifdef ERROR + // expected-note@+2{{declared private here}} +#endif NonCopyable(); }; +#ifdef ERROR +// expected-error@+4{{field of type 'NonCopyable' has private default constructor}} +// expected-note@+3{{implicit default constructor for 'S' first required here}} +// expected-note@+2{{due to 'S' being dllexported; try compiling in C++11 mode}} +#endif struct __declspec(dllexport) S { NonCopyable member; }; -- 2.40.0