]> granicus.if.org Git - clang/commitdiff
Improve diagnostic when failing to synthesize implicit member due to dllexport (PR22591)
authorHans Wennborg <hans@hanshq.net>
Sat, 21 Feb 2015 01:07:24 +0000 (01:07 +0000)
committerHans Wennborg <hans@hanshq.net>
Sat, 21 Feb 2015 01:07:24 +0000 (01:07 +0000)
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
lib/Sema/SemaDeclCXX.cpp
test/SemaCXX/dllexport-pr22591.cpp

index 83b7a58f2e24df5e04fcc27fa70281dc817dc2c5..c402e24a52ac400487c35d56bb18734310c7c540 100644 (file)
@@ -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 "
index 33f8c91691f9d42faf55aa9437b196c229b52005..4d2e87798fbca42585342b91b11b1ff80d212b67 100644 (file)
@@ -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.
index af75e4fe646052d6dde2f99fc94d24c73387e246..9d9fc84845c77276530ce134e64a3543c93f6c1b 100644 (file)
@@ -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;
 };