]> granicus.if.org Git - clang/commitdiff
MS ABI: Don't allow dllexport/import on lambdas
authorHans Wennborg <hans@hanshq.net>
Tue, 15 Sep 2015 21:05:30 +0000 (21:05 +0000)
committerHans Wennborg <hans@hanshq.net>
Tue, 15 Sep 2015 21:05:30 +0000 (21:05 +0000)
This is to follow up on David's comment in
http://reviews.llvm.org/D12422#235509

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@247718 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDeclAttr.cpp
test/SemaCXX/dllexport.cpp
test/SemaCXX/dllimport.cpp

index 71d1ab32e44e73ae5f76a0fb880b3926b5157f42..9565f67d3e4f0d621b66509a2a8731500d7239e1 100644 (file)
@@ -2274,6 +2274,8 @@ def err_attribute_dll_not_extern : Error<
   "%q0 must have external linkage when declared %q1">;
 def err_attribute_dll_thread_local : Error<
   "%q0 cannot be thread local when declared %q1">;
+def err_attribute_dll_lambda : Error<
+  "lambda cannot be declared %0">;
 def warn_attribute_invalid_on_definition : Warning<
   "'%0' attribute cannot be specified on a definition">,
   InGroup<IgnoredAttributes>;
index 31ed9f2434f26ff2a2a0b4899270e30a6493cc87..947103780c24a5b0566422ab12e4aad3ab2e49ad 100644 (file)
@@ -4335,6 +4335,14 @@ static void handleDLLAttr(Sema &S, Decl *D, const AttributeList &A) {
     }
   }
 
+  if (auto *MD = dyn_cast<CXXMethodDecl>(D)) {
+    if (S.Context.getTargetInfo().getCXXABI().isMicrosoft() &&
+        MD->getParent()->isLambda()) {
+      S.Diag(A.getRange().getBegin(), diag::err_attribute_dll_lambda) << A.getName();
+      return;
+    }
+  }
+
   unsigned Index = A.getAttributeSpellingListIndex();
   Attr *NewAttr = A.getKind() == AttributeList::AT_DLLExport
                       ? (Attr *)S.mergeDLLExportAttr(D, A.getRange(), Index)
index f7076fb8e8656f092a4a07fd0e49fafb9df42c5b..a32ba44442d7c189ef3af5aa35af910b877bf47c 100644 (file)
@@ -1083,3 +1083,12 @@ template<typename T> template<typename U> __declspec(dllexport) constexpr int CT
 #endif // __has_feature(cxx_variable_templates)
 
 // FIXME: Precedence rules seem to be different for classes.
+
+//===----------------------------------------------------------------------===//
+// Lambdas
+//===----------------------------------------------------------------------===//
+// The MS ABI doesn't provide a stable mangling for lambdas, so they can't be imported or exported.
+#ifdef MS
+// expected-error@+2{{lambda cannot be declared 'dllexport'}}
+#endif
+auto Lambda = []() __declspec(dllexport) -> bool { return true; };
index 91ed6b42606c96c4d07c6fb6b2ee254082cd4056..5d8ce78f6cdcba15f473d8de5229a1182bf6a7d6 100644 (file)
@@ -1339,3 +1339,14 @@ struct __declspec(dllimport) DerivedFromExplicitlyImportInstantiatedTemplate : p
 template <typename T> struct ExplicitInstantiationDeclTemplateBase { void func() {} };
 extern template struct ExplicitInstantiationDeclTemplateBase<int>;
 struct __declspec(dllimport) DerivedFromExplicitInstantiationDeclTemplateBase : public ExplicitInstantiationDeclTemplateBase<int> {};
+
+//===----------------------------------------------------------------------===//
+// Lambdas
+//===----------------------------------------------------------------------===//
+// The MS ABI doesn't provide a stable mangling for lambdas, so they can't be imported or exported.
+#ifdef MS
+// expected-error@+4{{lambda cannot be declared 'dllimport'}}
+#else
+// expected-warning@+2{{'dllimport' attribute ignored on inline function}}
+#endif
+auto Lambda = []() __declspec(dllimport) -> bool { return true; };