summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2019-12-11 11:13:50 +0100
committerStephan Bergmann <sbergman@redhat.com>2019-12-11 16:03:17 +0100
commit1586241344faf329a9b9b0e969d43fe186906b74 (patch)
tree78eb5c64d1da88000c68266da92616096fdfd796
parent128dabf58a535d422eb27f8dc760c81e54c6b354 (diff)
Extend loplugin:unusedmember "layout heuristic" to base classes
With clang-cl on Windows, where CPPU_GCC3_ALIGN expands to nothing, there were warnings about unsued Char1::c1 and Char2::c2 in cppu/source/uno/check.cxx (which were suppressed on Linux thanks to CPPU_GCC3_ALIGN(T) making the plugin's "layout heuristic" kick in for T). But Char1 and Char2 are also (indirect) bases of Char3, for which the heuristic kicks in thanks to a sizeof(Char3) expression. Extending the heuristic to base classes seems like a good improvement anyway, and happens to make the unwanted warnings on Windows go away. Change-Id: I1fac3104aa7a1745ccf2f23972953eaacbd45104 Reviewed-on: https://gerrit.libreoffice.org/84927 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
-rw-r--r--compilerplugins/clang/test/unusedmember.cxx20
-rw-r--r--compilerplugins/clang/unusedmember.cxx28
2 files changed, 41 insertions, 7 deletions
diff --git a/compilerplugins/clang/test/unusedmember.cxx b/compilerplugins/clang/test/unusedmember.cxx
index 84802414f47b..d40d87b2d29b 100644
--- a/compilerplugins/clang/test/unusedmember.cxx
+++ b/compilerplugins/clang/test/unusedmember.cxx
@@ -145,6 +145,25 @@ void f()
}
}
+namespace Bases
+{
+namespace
+{
+struct S1
+{
+ int i1;
+};
+struct S2 : S1
+{
+ int i2;
+};
+struct S3 : S2
+{
+};
+}
+void f() { (void)sizeof(S3); }
+}
+
int main()
{
(void)&Enum::f;
@@ -153,6 +172,7 @@ int main()
(void)&UnusedDataMember::f;
(void)&Alignof::f;
(void)&Aligned::f;
+ (void)&Bases::f;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/compilerplugins/clang/unusedmember.cxx b/compilerplugins/clang/unusedmember.cxx
index c8a536c79f53..ed7096ecbc1e 100644
--- a/compilerplugins/clang/unusedmember.cxx
+++ b/compilerplugins/clang/unusedmember.cxx
@@ -241,11 +241,7 @@ public:
{
return true;
}
- layout_.insert(expr->getTypeSourceInfo()
- ->getType()
- ->castAs<RecordType>()
- ->getDecl()
- ->getCanonicalDecl());
+ recordRecordDeclAndBases(expr->getTypeSourceInfo()->getType()->castAs<RecordType>());
return true;
}
@@ -281,7 +277,7 @@ public:
}
if (auto const t1 = t->getAs<RecordType>())
{
- layout_.insert(t1->getDecl()->getCanonicalDecl());
+ recordRecordDeclAndBases(t1);
}
return true;
}
@@ -385,6 +381,24 @@ private:
return t.isTrivialType(compiler.getASTContext()) || isWarnUnusedType(t);
}
+ void recordRecordDeclAndBases(RecordType const* type)
+ {
+ auto const d1 = type->getDecl();
+ if (!layout_.insert(d1->getCanonicalDecl()).second)
+ {
+ return;
+ }
+ if (auto const d2 = dyn_cast_or_null<CXXRecordDecl>(d1->getDefinition()))
+ {
+ for (auto i = d2->bases_begin(); i != d2->bases_end(); ++i)
+ {
+ recordRecordDeclAndBases(i->getType()->castAs<RecordType>());
+ }
+ //TODO: doesn't iterate vbases, but presence of such would run counter to the layout
+ // heuristic anyway
+ }
+ }
+
void recordCastedRecordDecl(QualType type)
{
for (auto t = type;;)
@@ -396,7 +410,7 @@ private:
}
if (auto const t1 = t->getAs<RecordType>())
{
- layout_.insert(t1->getDecl()->getCanonicalDecl());
+ recordRecordDeclAndBases(t1);
}
break;
}