Skip to content

Commit 64b70fd

Browse files
fix GetVariableOffset for static constexpr class attribute
by explicitly initializing constexpr with `Sema::InstantiateVariableDefinition`
1 parent 826be78 commit 64b70fd

File tree

2 files changed

+61
-5
lines changed

2 files changed

+61
-5
lines changed

lib/Interpreter/CppInterOp.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1284,12 +1284,22 @@ namespace Cpp {
12841284
#endif
12851285
}
12861286
auto VDAorErr = compat::getSymbolAddress(I, StringRef(mangledName));
1287-
if (!VDAorErr) {
1288-
llvm::logAllUnhandledErrors(VDAorErr.takeError(), llvm::errs(),
1289-
"Failed to GetVariableOffset:");
1290-
return 0;
1287+
if (VDAorErr)
1288+
return (intptr_t)jitTargetAddressToPointer<void*>(VDAorErr.get());
1289+
1290+
llvm::logAllUnhandledErrors(VDAorErr.takeError(), llvm::errs(),
1291+
"Failed to GetVariableOffset:");
1292+
1293+
if (VD->isConstexpr() && !VD->hasInit())
1294+
getSema().InstantiateVariableDefinition(SourceLocation(), VD);
1295+
if (VD->hasInit() &&
1296+
(VD->isConstexpr() || VD->getType().isConstQualified())) {
1297+
if (const APValue* val = VD->evaluateValue()) {
1298+
if (VD->getType()->isIntegralType(C)) {
1299+
return (intptr_t)val->getInt().getRawData();
1300+
}
1301+
}
12911302
}
1292-
return (intptr_t) jitTargetAddressToPointer<void*>(VDAorErr.get());
12931303
}
12941304

12951305
return 0;

unittests/CppInterOp/FunctionReflectionTest.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1154,3 +1154,49 @@ TEST(FunctionReflectionTest, Destruct) {
11541154
output = testing::internal::GetCapturedStdout();
11551155
EXPECT_EQ(output, "Destructor Executed");
11561156
}
1157+
1158+
TEST(FunctionReflectionTest, StaticConstExprDatamember) {
1159+
if (llvm::sys::RunningOnValgrind())
1160+
GTEST_SKIP() << "XFAIL due to Valgrind report";
1161+
1162+
Cpp::CreateInterpreter();
1163+
1164+
Cpp::Declare(R"(
1165+
class MyClass {
1166+
public:
1167+
static constexpr int x = 3;
1168+
};
1169+
1170+
template<int i>
1171+
class MyTemplatedClass {
1172+
public:
1173+
static constexpr int x = i;
1174+
};
1175+
)");
1176+
1177+
Cpp::TCppScope_t MyClass = Cpp::GetNamed("MyClass");
1178+
EXPECT_TRUE(MyClass);
1179+
1180+
std::vector<Cpp::TCppScope_t> datamembers;
1181+
Cpp::GetStaticDatamembers(MyClass, datamembers);
1182+
EXPECT_EQ(datamembers.size(), 1);
1183+
1184+
intptr_t offset = Cpp::GetVariableOffset(datamembers[0]);
1185+
EXPECT_EQ(3, *(int*)offset);
1186+
1187+
ASTContext& C = Interp->getCI()->getASTContext();
1188+
std::vector<Cpp::TemplateArgInfo> template_args = {
1189+
{C.IntTy.getAsOpaquePtr(), "5"}};
1190+
1191+
Cpp::TCppFunction_t MyTemplatedClass =
1192+
Cpp::InstantiateTemplate(Cpp::GetNamed("MyTemplatedClass"),
1193+
template_args.data(), template_args.size());
1194+
EXPECT_TRUE(MyTemplatedClass);
1195+
1196+
datamembers.clear();
1197+
Cpp::GetStaticDatamembers(MyTemplatedClass, datamembers);
1198+
EXPECT_EQ(datamembers.size(), 1);
1199+
1200+
offset = Cpp::GetVariableOffset(datamembers[0]);
1201+
EXPECT_EQ(5, *(int*)offset);
1202+
}

0 commit comments

Comments
 (0)