diff --git a/clang/docs/TypeSanitizer.rst b/clang/docs/TypeSanitizer.rst index 3c683a6c24bb4..c2f628cb231db 100644 --- a/clang/docs/TypeSanitizer.rst +++ b/clang/docs/TypeSanitizer.rst @@ -119,8 +119,6 @@ brief dictionary of these terms. * ``omnipotent char``: This is a special type which can alias with anything. Its name comes from the C/C++ type ``char``. -* ``type p[x]``: This signifies pointers to the type. ``x`` is the number of indirections to reach the final value. - As an example, a pointer to a pointer to an integer would be ``type p2 int``. TypeSanitizer is still experimental. User-facing error messages should be improved in the future to remove references to LLVM IR specific terms. diff --git a/compiler-rt/lib/tysan/tysan.cpp b/compiler-rt/lib/tysan/tysan.cpp index 1c67adeba0fc5..76fa8f45ebe4f 100644 --- a/compiler-rt/lib/tysan/tysan.cpp +++ b/compiler-rt/lib/tysan/tysan.cpp @@ -22,6 +22,7 @@ #include "tysan/tysan.h" +#include #include #include @@ -40,20 +41,62 @@ tysan_copy_types(const void *daddr, const void *saddr, uptr size) { internal_memmove(shadow_for(daddr), shadow_for(saddr), size * sizeof(uptr)); } -static const char *getDisplayName(const char *Name) { +/// Struct returned by `parseIndirectionPrefix`. +struct ParseIndirectionPrefixResult { + /// Level of indirection - 0 if the prefix is not found. + size_t Indirection; + /// Pointer to the remaining part of the name after the indirection prefix. + /// (This is the original pointer if the prefix is not found.) + const char *RemainingName; +}; + +/// Parses the "p{indirection} " prefix given to pointer type names in TBAA. +static ParseIndirectionPrefixResult parseIndirectionPrefix(const char *Name) { + size_t CharIndex = 0; + + // Parse 'p'. + // This also handles the case of an empty string. + if (Name[CharIndex++] != 'p') + return {0, Name}; + + // Parse indirection level. + size_t Indirection = 0; + while (isdigit(Name[CharIndex])) { + const auto DigitValue = static_cast(Name[CharIndex] - '0'); + Indirection = Indirection * 10 + DigitValue; + ++CharIndex; + } + + // Parse space. + if (Name[CharIndex++] != ' ') + return {0, Name}; + + return {Indirection, Name + CharIndex}; +} + +static void printDisplayName(const char *Name) { if (Name[0] == '\0') - return ""; + Printf(""); + + // Parse indirection prefix and remove it. + const auto [Indirection, RemainingName] = parseIndirectionPrefix(Name); // Clang generates tags for C++ types that demangle as typeinfo. Remove the // prefix from the generated string. const char *TIPrefix = "typeinfo name for "; size_t TIPrefixLen = strlen(TIPrefix); - const char *DName = Symbolizer::GetOrInit()->Demangle(Name); + const char *DName = Symbolizer::GetOrInit()->Demangle(RemainingName); if (!internal_strncmp(DName, TIPrefix, TIPrefixLen)) DName += TIPrefixLen; - return DName; + // Print type name. + Printf("%s", DName); + + // Print asterisks for indirection (C pointer notation). + for (size_t i = 0; i < Indirection; ++i) { + Printf("*"); + } } static void printTDName(tysan_type_descriptor *td) { @@ -75,8 +118,7 @@ static void printTDName(tysan_type_descriptor *td) { } break; case TYSAN_STRUCT_TD: - Printf("%s", getDisplayName( - (char *)(td->Struct.Members + td->Struct.MemberCount))); + printDisplayName((char *)(td->Struct.Members + td->Struct.MemberCount)); break; } } diff --git a/compiler-rt/test/tysan/print_stacktrace.c b/compiler-rt/test/tysan/print_stacktrace.c index 3ffb6063377d9..831be5e4afed9 100644 --- a/compiler-rt/test/tysan/print_stacktrace.c +++ b/compiler-rt/test/tysan/print_stacktrace.c @@ -10,7 +10,7 @@ void zero_array() { for (i = 0; i < 1; ++i) P[i] = 0.0f; // CHECK: ERROR: TypeSanitizer: type-aliasing-violation - // CHECK: WRITE of size 4 at {{.*}} with type float accesses an existing object of type p1 float + // CHECK: WRITE of size 4 at {{.*}} with type float accesses an existing object of type float* // CHECK: {{#0 0x.* in zero_array .*print_stacktrace.c:}}[[@LINE-3]] // CHECK-SHORT-NOT: {{#1 0x.* in main .*print_stacktrace.c}} // CHECK-LONG-NEXT: {{#1 0x.* in main .*print_stacktrace.c}} diff --git a/compiler-rt/test/tysan/ptr-float.c b/compiler-rt/test/tysan/ptr-float.c index aaa9895986988..145d5d8f289ea 100644 --- a/compiler-rt/test/tysan/ptr-float.c +++ b/compiler-rt/test/tysan/ptr-float.c @@ -7,7 +7,7 @@ void zero_array() { for (i = 0; i < 1; ++i) P[i] = 0.0f; // CHECK: ERROR: TypeSanitizer: type-aliasing-violation - // CHECK: WRITE of size 4 at {{.*}} with type float accesses an existing object of type p1 float + // CHECK: WRITE of size 4 at {{.*}} with type float accesses an existing object of type float* // CHECK: {{#0 0x.* in zero_array .*ptr-float.c:}}[[@LINE-3]] }