https://github.com/gbMattN created https://github.com/llvm/llvm-project/pull/108385
Fixes issue #105960 If a member in a struct is also a struct, accessing a member partway through this inner struct currently causes a false positive. This is because when checking aliasing, the access offset is seen as greater than the starting offset of the inner struct, so the loop continues one iteration, and believes we are accessing the member after the inner struct. The next member's offset is greater than the offset we are looking for, so when we subtract the next member's offset from what we are looking for, the offset underflows. To fix this, we check if the member we think we are accessing has a greater offset than the offset we are looking for. If so, we take a step back. We cannot do this in the loop, since the loop does not check the final member. This means the penultimate member would still cause false positives. >From 2dffe46bc8af4ccd5627478ba9546647907104cc Mon Sep 17 00:00:00 2001 From: Matthew Nagy <gbm...@tiger-linux2.domain.snsys.com> Date: Thu, 12 Sep 2024 12:36:57 +0000 Subject: [PATCH] [TySan] Fix struct access with different bases --- compiler-rt/lib/tysan/tysan.cpp | 4 +++ .../tysan/struct-offset-different-base.cpp | 31 +++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 compiler-rt/test/tysan/struct-offset-different-base.cpp diff --git a/compiler-rt/lib/tysan/tysan.cpp b/compiler-rt/lib/tysan/tysan.cpp index f627851d049e6a..f2cb6faddf45ac 100644 --- a/compiler-rt/lib/tysan/tysan.cpp +++ b/compiler-rt/lib/tysan/tysan.cpp @@ -128,6 +128,10 @@ static bool isAliasingLegalUp(tysan_type_descriptor *TDA, break; } + //You can't have negative offset, you must be partially inside the last type + if (TDA->Struct.Members[Idx].Offset > OffsetA) + Idx -=1; + OffsetA -= TDA->Struct.Members[Idx].Offset; TDA = TDA->Struct.Members[Idx].Type; } else { diff --git a/compiler-rt/test/tysan/struct-offset-different-base.cpp b/compiler-rt/test/tysan/struct-offset-different-base.cpp new file mode 100644 index 00000000000000..c1ef5f8669c280 --- /dev/null +++ b/compiler-rt/test/tysan/struct-offset-different-base.cpp @@ -0,0 +1,31 @@ +// RUN: %clangxx_tysan -O0 %s -o %t && %run %t >%t.out 2>&1 +// RUN: FileCheck %s < %t.out + +#include <stdio.h> + +struct inner { + char buffer; + int i; +}; + +void init_inner(inner *list) { + list->i = 0; +} + +struct outer { + inner foo; + char buffer; +}; + +int main(void) { + outer *l = new outer(); + + init_inner(&l->foo); + + int access_offsets_with_different_base = l->foo.i; + printf("%d\n", access_offsets_with_different_base); + + return 0; +} + +// CHECK-NOT: ERROR: TypeSanitizer: type-aliasing-violation _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits