summaryrefslogtreecommitdiff
path: root/compilerplugins
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2020-11-03 08:33:19 +0100
committerStephan Bergmann <sbergman@redhat.com>2020-11-03 22:29:36 +0100
commit64e58879c4445bfc733d337c53ac7dc1748fdbb9 (patch)
tree6fb1f0fc0a5bba3a4f73472d23a88df20de5afa6 /compilerplugins
parent6f3899b27156591e65f62649a92c727eb6f5dd03 (diff)
Avoid UBSan pointer-overflow
...as seen with recently introduced UITest_writer_tests UITEST_TEST_NAME=compareDocuments.compareDocuments.test_tdf137855, but where the unsigned sal_uLong (aka sal_uIntPtr) value is apparently meant to wrap around and address an element of m_pMemory at a negative index from m_pBDiag: > sw/source/core/doc/doccomp.cxx:832:13: runtime error: addition of unsigned offset to 0x6250014a90d0 overflowed to 0x6250014a90b8 > #0 in (anonymous namespace)::Compare::CompareSequence::Compare(unsigned long, unsigned long, unsigned long, unsigned long) at sw/source/core/doc/doccomp.cxx:832:13 > #1 in (anonymous namespace)::Compare::CompareSequence::CompareSequence((anonymous namespace)::CompareData&, (anonymous namespace)::CompareData&, (anonymous namespace)::Compare::MovedData const&, (anonymous namespace)::Compare::MovedData const&) at sw/source/core/doc/doccomp.cxx:794:5 > #2 in (anonymous namespace)::Compare::Compare(unsigned long, (anonymous namespace)::CompareData&, (anonymous namespace)::CompareData&) at sw/source/core/doc/doccomp.cxx:605:25 > #3 in (anonymous namespace)::CompareData::CompareLines((anonymous namespace)::CompareData&) at sw/source/core/doc/doccomp.cxx:440:17 > #4 in SwDoc::CompareDoc(SwDoc const&) at sw/source/core/doc/doccomp.cxx:1877:13 > #5 in SwEditShell::CompareDoc(SwDoc const&) at sw/source/core/edit/editsh.cxx:877:34 > #6 in SwView::InsertMedium(unsigned short, std::unique_ptr<SfxMedium, std::default_delete<SfxMedium> >, short) at sw/source/uibase/uiview/view2.cxx:2377:39 > #7 in SwView::DialogClosedHdl(sfx2::FileDialogHelper*) at sw/source/uibase/uiview/view2.cxx:2574:26 [...] Using std::make_signed_t where its canonic type happens to be `long` requires a workaround for old Clang to avoid a false > CXXFunctionalCastExpr, suspicious cast from 'sal_uLong' (aka 'unsigned long') to 'std::make_signed_t<decltype(d)>' (aka 'long') [loplugin:toolslong] warning. Change-Id: I07413ba06051f75d80832a4772ab1c541805b259 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/105234 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'compilerplugins')
-rw-r--r--compilerplugins/clang/toolslong.cxx17
1 files changed, 17 insertions, 0 deletions
diff --git a/compilerplugins/clang/toolslong.cxx b/compilerplugins/clang/toolslong.cxx
index 719b5b0caca5..b0d6a78d35ab 100644
--- a/compilerplugins/clang/toolslong.cxx
+++ b/compilerplugins/clang/toolslong.cxx
@@ -17,6 +17,8 @@
#include "clang/AST/Attr.h"
#include "clang/Basic/Builtins.h"
+#include "config_clang.h"
+
#include "check.hxx"
#include "compat.hxx"
#include "plugin.hxx"
@@ -32,6 +34,21 @@ bool isLong(QualType type)
// some parts of the STL have ::difference_type => long
if (type->getAs<AutoType>() || type->getAs<DecltypeType>())
return false;
+#if CLANG_VERSION < 80000
+ // Prior to <https://github.com/llvm/llvm-project/commit/
+ // c50240dac133451b3eae5b89cecca4c1c4af9fd4> "[AST] Get aliased type info from an aliased
+ // TemplateSpecialization" in Clang 8, if type is a TemplateSpecializationType on top of a
+ // TypedefType, the above getAs<TypedefType> returned null (as it unconditionally desugared the
+ // TemplateSpecializationType to the underlying canonic type, not to any aliased type), so re-
+ // check with the TemplateSpecializationType's aliased type:
+ if (auto const t = type->getAs<TemplateSpecializationType>())
+ {
+ if (t->isTypeAlias())
+ {
+ return isLong(t->getAliasedType());
+ }
+ }
+#endif
if (type->isSpecificBuiltinType(BuiltinType::Kind::Long))
return true;
auto arrayType = type->getAsArrayTypeUnsafe();