forked from OSchip/llvm-project
Revert "[MS] Don't statically initialize dllimport member function pointers"
This reverts commit r306137. It has problems on code like this: struct __declspec(dllimport) Foo { int a; int get_a() { return a; } }; template <int (Foo::*Getter)()> struct HasValue { int operator()(Foo *p) { return (p->*Getter)(); } }; int main() { Foo f; f.a = 3; int x = HasValue<&Foo::get_a>()(&f); } llvm-svn: 306175
This commit is contained in:
parent
53dbfb3798
commit
33d501f7d1
|
@ -1665,19 +1665,6 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Member pointers are constant expressions unless they point to a
|
|
||||||
/// non-virtual dllimport member function.
|
|
||||||
static bool CheckMemberPointerConstantExpression(EvalInfo &Info,
|
|
||||||
SourceLocation Loc,
|
|
||||||
QualType Type,
|
|
||||||
const APValue &Value) {
|
|
||||||
const ValueDecl *Member = Value.getMemberPointerDecl();
|
|
||||||
const auto *FD = dyn_cast_or_null<CXXMethodDecl>(Member);
|
|
||||||
if (!FD)
|
|
||||||
return true;
|
|
||||||
return FD->isVirtual() || !FD->hasAttr<DLLImportAttr>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check that this core constant expression is of literal type, and if not,
|
/// Check that this core constant expression is of literal type, and if not,
|
||||||
/// produce an appropriate diagnostic.
|
/// produce an appropriate diagnostic.
|
||||||
static bool CheckLiteralType(EvalInfo &Info, const Expr *E,
|
static bool CheckLiteralType(EvalInfo &Info, const Expr *E,
|
||||||
|
@ -1770,9 +1757,6 @@ static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc,
|
||||||
return CheckLValueConstantExpression(Info, DiagLoc, Type, LVal);
|
return CheckLValueConstantExpression(Info, DiagLoc, Type, LVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Value.isMemberPointer())
|
|
||||||
return CheckMemberPointerConstantExpression(Info, DiagLoc, Type, Value);
|
|
||||||
|
|
||||||
// Everything else is fine.
|
// Everything else is fine.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
// Also check that -Wglobal-constructors does the right thing. Strictly
|
|
||||||
// speaking, this is a Sema test, but this avoids test case duplication.
|
|
||||||
// RUN: %clang_cc1 -Wglobal-constructors %s -verify -triple i686-windows-msvc -fms-extensions -std=c++11
|
|
||||||
//
|
|
||||||
// RUN: %clang_cc1 %s -emit-llvm -o - -triple i686-windows-msvc -fms-extensions -std=c++11 | FileCheck %s
|
|
||||||
|
|
||||||
struct __declspec(dllimport) Single {
|
|
||||||
void nonvirt();
|
|
||||||
virtual void virt();
|
|
||||||
};
|
|
||||||
|
|
||||||
struct A { int a; };
|
|
||||||
struct B { int b; };
|
|
||||||
struct __declspec(dllimport) Multi : A, B {
|
|
||||||
void nonvirt();
|
|
||||||
virtual void virt();
|
|
||||||
};
|
|
||||||
|
|
||||||
struct __declspec(dllimport) Virtual : virtual A {
|
|
||||||
void nonvirt();
|
|
||||||
virtual void virt();
|
|
||||||
};
|
|
||||||
|
|
||||||
struct General;
|
|
||||||
static_assert(sizeof(void (General::*)()) == 16, "force general memptr model");
|
|
||||||
struct __declspec(dllimport) General {
|
|
||||||
void nonvirt();
|
|
||||||
virtual void virt();
|
|
||||||
};
|
|
||||||
|
|
||||||
auto mp_single_nv = &Single::nonvirt; // expected-warning {{global constructor}}
|
|
||||||
auto mp_multi_nv = &Multi::nonvirt; // expected-warning {{global constructor}}
|
|
||||||
auto mp_virtual_nv = &Virtual::nonvirt; // expected-warning {{global constructor}}
|
|
||||||
auto mp_general_nv = &General::nonvirt; // expected-warning {{global constructor}}
|
|
||||||
|
|
||||||
auto mp_single_v = &Single::virt;
|
|
||||||
auto mp_multi_v = &Multi::virt;
|
|
||||||
auto mp_virtual_v = &Virtual::virt;
|
|
||||||
auto mp_general_v = &General::virt;
|
|
||||||
|
|
||||||
// All of the non-virtual globals need dynamic initializers.
|
|
||||||
|
|
||||||
// CHECK: @"\01?mp_single_nv@@3P8Single@@AEXXZQ1@" = global i8* null, align 4
|
|
||||||
// CHECK: @"\01?mp_multi_nv@@3P8Multi@@AEXXZQ1@" = global { i8*, i32 } zeroinitializer, align 4
|
|
||||||
// CHECK: @"\01?mp_virtual_nv@@3P8Virtual@@AEXXZQ1@" = global { i8*, i32, i32 } zeroinitializer, align 4
|
|
||||||
// CHECK: @"\01?mp_general_nv@@3P8General@@AEXXZQ1@" = global { i8*, i32, i32, i32 } zeroinitializer, align 4
|
|
||||||
|
|
||||||
// CHECK: @"\01?mp_single_v@@3P8Single@@AEXXZQ1@" = global i8* bitcast (void (%struct.Single*, ...)* @"\01??_9Single@@$BA@AE" to i8*), align 4
|
|
||||||
// CHECK: @"\01?mp_multi_v@@3P8Multi@@AEXXZQ1@" = global { i8*, i32 } { i8* bitcast (void (%struct.Multi*, ...)* @"\01??_9Multi@@$BA@AE" to i8*), i32 0 }, align 4
|
|
||||||
// CHECK: @"\01?mp_virtual_v@@3P8Virtual@@AEXXZQ1@" = global { i8*, i32, i32 } { i8* bitcast (void (%struct.Virtual*, ...)* @"\01??_9Virtual@@$BA@AE" to i8*), i32 0, i32 0 }, align 4
|
|
||||||
// CHECK: @"\01?mp_general_v@@3P8General@@AEXXZQ1@" = global { i8*, i32, i32, i32 } { i8* bitcast (void (%struct.General*, ...)* @"\01??_9General@@$BA@AE" to i8*), i32 0, i32 0, i32 0 }, align 4
|
|
||||||
|
|
||||||
// CHECK: define internal void @_GLOBAL__sub_I{{.*}}() {{.*}} {
|
|
||||||
// CHECK: call void @"\01??__Emp_single_nv@@YAXXZ"()
|
|
||||||
// CHECK: call void @"\01??__Emp_multi_nv@@YAXXZ"()
|
|
||||||
// CHECK: call void @"\01??__Emp_virtual_nv@@YAXXZ"()
|
|
||||||
// CHECK: call void @"\01??__Emp_general_nv@@YAXXZ"()
|
|
||||||
// CHECK: }
|
|
Loading…
Reference in New Issue