Skip to content

Commit b1803f0

Browse files
skip annotating classes with only defaulted, deleted, or pure virtual methods (#48)
## Purpose Make annotating at the class level for vtable export more strict. ## Background b7cb8df introduced exporting at the class level for class definitions with out-of-line virtual methods. However, the check for virtual methods requiring export was not as strict as it could be: defaulted, deleted, and pure virtual methods do not require the vtable to be exported. ## Validation 1. New test cases to verify stricter virtual method checks. 2. Ran tests locally on Windows and Linux, --------- Co-authored-by: Saleem Abdulrasool <[email protected]>
1 parent b7cb8df commit b1803f0

File tree

2 files changed

+46
-3
lines changed

2 files changed

+46
-3
lines changed

Sources/idt/idt.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,9 @@ class visitor : public clang::RecursiveASTVisitor<visitor> {
253253
// access level.
254254
bool should_export_record = false;
255255
for (const auto *MD : RD->methods())
256-
if ((should_export_record = (MD->isVirtual() && !MD->hasBody())))
256+
if ((should_export_record =
257+
!(MD->isPureVirtual() || MD->isDefaulted() || MD->isDeleted()) &&
258+
(MD->isVirtual() && !MD->hasBody())))
257259
break;
258260

259261
const bool is_exported_record = is_symbol_exported(RD);

Tests/VTables.hh

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,56 @@ struct ClassWithInlineVirtualMethod {
1010
static unsigned static_field;
1111
};
1212

13+
// CHECK-NOT: VTables.hh:[[@LINE+1]]:{{.*}}
14+
struct ClassWithDefaultVirtualDestructor {
15+
// CHECK-NOT: VTables.hh:[[@LINE+1]]:{{.*}}
16+
virtual ~ClassWithDefaultVirtualDestructor() = default;
17+
};
18+
19+
// CHECK-NOT: VTables.hh:[[@LINE+1]]:{{.*}}
20+
struct ClassWithDeletedVirtualDestructor {
21+
// CHECK-NOT: VTables.hh:[[@LINE+1]]:{{.*}}
22+
virtual ~ClassWithDeletedVirtualDestructor() = delete;
23+
};
24+
25+
// CHECK-NOT: VTables.hh:[[@LINE+1]]:{{.*}}
26+
struct ClassWithPureVirtualMethod {
27+
// CHECK-NOT: VTables.hh:[[@LINE+1]]:{{.*}}
28+
virtual void virtualMethod() = 0;
29+
};
30+
1331
// CHECK: VTables.hh:[[@LINE+1]]:8: remark: unexported public interface 'ClassWithExternVirtualMethod'
1432
struct ClassWithExternVirtualMethod {
15-
private:
1633
// CHECK-NOT: VTables.hh:[[@LINE+1]]:{{.*}}
17-
virtual void virtualMedhod();
34+
virtual void virtualMethod();
1835
// CHECK-NOT: VTables.hh:[[@LINE+1]]:{{.*}}
1936
void method();
2037
};
2138

39+
// CHECK-NOT: VTables.hh:[[@LINE+1]]:{{.*}}
40+
struct DerivedClassWithInlineOverriddenExternVirtualMethod : public ClassWithExternVirtualMethod {
41+
// CHECK-NOT: VTables.hh:[[@LINE+1]]:{{.*}}
42+
void virtualMethod() override {}
43+
};
44+
45+
// CHECK: VTables.hh:[[@LINE+1]]:8: remark: unexported public interface 'DerivedClassWithExternOverriddenExternVirtualMethod'
46+
struct DerivedClassWithExternOverriddenExternVirtualMethod : public ClassWithExternVirtualMethod {
47+
// CHECK-NOT: VTables.hh:[[@LINE+1]]:{{.*}}
48+
void virtualMethod() override;
49+
};
50+
51+
// CHECK-NOT: VTables.hh:[[@LINE+1]]:{{.*}}
52+
struct DerivedClassWithInlineOverriddenPureVirtualMethod : public ClassWithPureVirtualMethod {
53+
// CHECK-NOT: VTables.hh:[[@LINE+1]]:{{.*}}
54+
void virtualMethod() override {}
55+
};
56+
57+
// CHECK: VTables.hh:[[@LINE+1]]:8: remark: unexported public interface 'DerivedClassWithExternOverriddenPureVirtualMethod'
58+
struct DerivedClassWithExternOverriddenPureVirtualMethod : public ClassWithPureVirtualMethod {
59+
// CHECK-NOT: VTables.hh:[[@LINE+1]]:{{.*}}
60+
void virtualMethod() override;
61+
};
62+
2263
// CHECK-NOT: VTables.hh:[[@LINE+1]]:{{.*}}
2364
struct OuterClass {
2465
// CHECK: VTables.hh:[[@LINE+1]]:3: remark: unexported public interface 'method'

0 commit comments

Comments
 (0)