summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2017-01-23 23:57:50 +0000
committerHans Wennborg <hans@hanshq.net>2017-01-23 23:57:50 +0000
commit251c204e57dba2a6b177312d601ad3e256f5f681 (patch)
tree3b82366f14d75e6ff7432dca880e152e27001de4 /clang
parent954a624fb987f97e74bdf7b01685d4ec2a4dc861 (diff)
downloadbcm5719-llvm-251c204e57dba2a6b177312d601ad3e256f5f681.tar.gz
bcm5719-llvm-251c204e57dba2a6b177312d601ad3e256f5f681.zip
Re-commit "Don't inline dllimport functions referencing non-imported methods"
This re-commits r292522 with the addition that it also handles calls through pointer to member functions without crashing. llvm-svn: 292856
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp10
-rw-r--r--clang/test/CodeGenCXX/dllimport.cpp10
2 files changed, 20 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index c9d9a35fb8a..f9866957a14 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1751,6 +1751,16 @@ namespace {
SafeToInline = E->getConstructor()->hasAttr<DLLImportAttr>();
return SafeToInline;
}
+ bool VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
+ CXXMethodDecl *M = E->getMethodDecl();
+ if (!M) {
+ // Call through a pointer to member function. This is safe to inline.
+ SafeToInline = true;
+ } else {
+ SafeToInline = M->hasAttr<DLLImportAttr>();
+ }
+ return SafeToInline;
+ }
bool VisitCXXDeleteExpr(CXXDeleteExpr *E) {
SafeToInline = E->getOperatorDelete()->hasAttr<DLLImportAttr>();
return SafeToInline;
diff --git a/clang/test/CodeGenCXX/dllimport.cpp b/clang/test/CodeGenCXX/dllimport.cpp
index 4ec14b72109..8e7ead9d1fe 100644
--- a/clang/test/CodeGenCXX/dllimport.cpp
+++ b/clang/test/CodeGenCXX/dllimport.cpp
@@ -26,6 +26,7 @@ struct ExplicitSpec_NotImported {};
#define USEVARTYPE(type, var) type UNIQ(use)() { return var; }
#define USEVAR(var) USEVARTYPE(int, var)
#define USE(func) void UNIQ(use)() { func(); }
+#define USE1(func) void UNIQ(use)() { func(nullptr); }
#define USEMEMFUNC(class, func) void (class::*UNIQ(use)())() { return &class::func; }
#define USESTATICMEMFUNC(class, func) void (*UNIQ(use)())() { return &class::func; }
#define USECLASS(class) void UNIQ(USE)() { class x; }
@@ -316,10 +317,13 @@ namespace ns { __declspec(dllimport) void externalFunc(); }
USE(ns::externalFunc)
// A dllimport function referencing non-imported vars or functions must not be available_externally.
+
__declspec(dllimport) int ImportedVar;
int NonImportedVar;
__declspec(dllimport) int ImportedFunc();
int NonImportedFunc();
+struct ClassWithNonImportedMethod { int f(); };
+
__declspec(dllimport) inline int ReferencingImportedVar() { return ImportedVar; }
// MO1-DAG: define available_externally dllimport i32 @"\01?ReferencingImportedVar@@YAHXZ"
__declspec(dllimport) inline int ReferencingNonImportedVar() { return NonImportedVar; }
@@ -328,10 +332,16 @@ __declspec(dllimport) inline int ReferencingImportedFunc() { return ImportedFunc
// MO1-DAG: define available_externally dllimport i32 @"\01?ReferencingImportedFunc@@YAHXZ"
__declspec(dllimport) inline int ReferencingNonImportedFunc() { return NonImportedFunc(); }
// MO1-DAG: declare dllimport i32 @"\01?ReferencingNonImportedFunc@@YAHXZ"()
+__declspec(dllimport) inline int ReferencingNonImportedMethod(ClassWithNonImportedMethod *x) { return x->f(); }
+// MO1-DAG: declare dllimport i32 @"\01?ReferencingNonImportedMethod
+__declspec(dllimport) inline int ReferencingClassMemberPtr(int (ClassWithNonImportedMethod::*p)(), ClassWithNonImportedMethod *x) { return (x->*p)(); }
+// MO1-DAG: define available_externally dllimport i32 @"\01?ReferencingClassMemberPtr@@YAHP8ClassWithNonImportedMethod@@AEHXZPAU1@@Z"
USE(ReferencingImportedVar)
USE(ReferencingNonImportedVar)
USE(ReferencingImportedFunc)
USE(ReferencingNonImportedFunc)
+USE1(ReferencingNonImportedMethod)
+void UNIQ(use)() { ReferencingClassMemberPtr(&ClassWithNonImportedMethod::f, nullptr); }
// References to operator new and delete count too, despite not being DeclRefExprs.
__declspec(dllimport) inline int *ReferencingNonImportedNew() { return new int[2]; }
// MO1-DAG: declare dllimport i32* @"\01?ReferencingNonImportedNew@@YAPAHXZ"
OpenPOWER on IntegriCloud