From 6d9f13127cba3eb7074a027c63160c8a2eca0e65 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Wed, 13 Feb 2013 21:18:23 +0000 Subject: [PATCH] ubsan: Add checking for invalid downcasts. Per [expr.static.cast]p2 and p11, base-to-derived casts have undefined behavior if the object is not actually an instance of the derived type. Runtime library part. llvm-svn: 175079 --- compiler-rt/lib/ubsan/lit_tests/TypeCheck/vptr.cpp | 15 +++++++++++++-- compiler-rt/lib/ubsan/ubsan_handlers.cc | 2 +- compiler-rt/lib/ubsan/ubsan_handlers_cxx.cc | 1 - 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/compiler-rt/lib/ubsan/lit_tests/TypeCheck/vptr.cpp b/compiler-rt/lib/ubsan/lit_tests/TypeCheck/vptr.cpp index 574a7be..109e7a8 100644 --- a/compiler-rt/lib/ubsan/lit_tests/TypeCheck/vptr.cpp +++ b/compiler-rt/lib/ubsan/lit_tests/TypeCheck/vptr.cpp @@ -1,11 +1,13 @@ // RUN: %clang -ccc-cxx -fsanitize=vptr %s -O3 -o %t -// RUN: %t rT && %t mT && %t fT -// RUN: %t rU && %t mU && %t fU +// RUN: %t rT && %t mT && %t fT && %t cT +// RUN: %t rU && %t mU && %t fU && %t cU // RUN: %t rS && %t rV && %t oV // RUN: %t mS 2>&1 | FileCheck %s --check-prefix=CHECK-MEMBER --strict-whitespace // RUN: %t fS 2>&1 | FileCheck %s --check-prefix=CHECK-MEMFUN --strict-whitespace +// RUN: %t cS 2>&1 | FileCheck %s --check-prefix=CHECK-DOWNCAST --strict-whitespace // RUN: %t mV 2>&1 | FileCheck %s --check-prefix=CHECK-MEMBER --strict-whitespace // RUN: %t fV 2>&1 | FileCheck %s --check-prefix=CHECK-MEMFUN --strict-whitespace +// RUN: %t cV 2>&1 | FileCheck %s --check-prefix=CHECK-DOWNCAST --strict-whitespace // RUN: %t oU 2>&1 | FileCheck %s --check-prefix=CHECK-OFFSET --strict-whitespace // RUN: %t m0 2>&1 | FileCheck %s --check-prefix=CHECK-NULL-MEMBER --strict-whitespace @@ -102,5 +104,14 @@ int main(int, char **argv) { // CHECK-OFFSET-NEXT: {{^ \^ ( ~~~~~~~~~~~~)~~~~~~~~~~~ *$}} // CHECK-OFFSET-NEXT: {{^ ( )?vptr for}} 'T' base class of [[DYN_TYPE]] return reinterpret_cast(p)->v() - 2; + + case 'c': + // CHECK-DOWNCAST: vptr.cpp:[[@LINE+5]]:5: runtime error: downcast of address [[PTR:0x[0-9a-f]*]] which does not point to an object of type 'T' + // CHECK-DOWNCAST-NEXT: [[PTR]]: note: object is of type [[DYN_TYPE:'S'|'U']] + // CHECK-DOWNCAST-NEXT: {{^ .. .. .. .. .. .. .. .. .. .. .. .. }} + // CHECK-DOWNCAST-NEXT: {{^ \^~~~~~~~~~~(~~~~~~~~~~~~)? *$}} + // CHECK-DOWNCAST-NEXT: {{^ vptr for}} [[DYN_TYPE]] + static_cast(reinterpret_cast(p)); + return 0; } } diff --git a/compiler-rt/lib/ubsan/ubsan_handlers.cc b/compiler-rt/lib/ubsan/ubsan_handlers.cc index 1b02aa0..33e044d 100644 --- a/compiler-rt/lib/ubsan/ubsan_handlers.cc +++ b/compiler-rt/lib/ubsan/ubsan_handlers.cc @@ -22,7 +22,7 @@ using namespace __ubsan; namespace __ubsan { const char *TypeCheckKinds[] = { "load of", "store to", "reference binding to", "member access within", - "member call on", "constructor call on" + "member call on", "constructor call on", "downcast of", "downcast of" }; } diff --git a/compiler-rt/lib/ubsan/ubsan_handlers_cxx.cc b/compiler-rt/lib/ubsan/ubsan_handlers_cxx.cc index dcc1f60..b6cddef 100644 --- a/compiler-rt/lib/ubsan/ubsan_handlers_cxx.cc +++ b/compiler-rt/lib/ubsan/ubsan_handlers_cxx.cc @@ -42,7 +42,6 @@ static void HandleDynamicTypeCacheMiss( << TypeCheckKinds[Data->TypeCheckKind] << (void*)Pointer << Data->Type; // If possible, say what type it actually points to. - // FIXME: Demangle the type names. DynamicTypeInfo DTI = getDynamicTypeInfo((void*)Pointer); if (!DTI.isValid()) Diag(Pointer, DL_Note, "object has invalid vptr") -- 2.7.4