On 23 October 2013 11:18, Richard Smith <[email protected]> wrote:

> On Wed, Oct 23, 2013 at 2:21 AM, Nick Lewycky <[email protected]> wrote:
>
>> On 22 October 2013 22:07, Nick Lewycky <[email protected]> wrote:
>>
>>> On 22 October 2013 21:18, Nick Lewycky <[email protected]> wrote:
>>>
>>>> The attached patch makes ubsan emit summaries of errors it encounters.
>>>> The format of these summaries is:
>>>>   UndefinedBehaviourSanitizer: signed-integer-overflow file:49:7
>>>> where the string is the flag name. Most of the patch is adding the flag
>>>> names to all the reports all over.
>>>>
>>>
>>> I've noticed a small bug, for load-invalid-value we always pick "enum"
>>> and never "bool". I would guess that's because
>>> ASTContext::getTypeSize(BoolTy) returns 8 instead of 1?
>>>
>>> Richard, thoughts?
>>>
>>
>> Updated patch attached. It now detects bool sanitizer by looking at the
>> Type as a string, and is otherwise updated for the changes in
>> sanitizer-common.
>>
>
> This does the wrong thing for typedefs of bool. Can we emit a flag as part
> of the static info to say whether this was the bool sanitizer or the enum
> sanitizer? Otherwise, I don't see how we can distinguish the
> typedef-for-bool case from the enum-with-underlying-type-bool case.
>

Done. Patch attached!

Nick


>  This patch is stacked on top of
>>>> http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20131021/091535.html
>>>>  ,
>>>> or else ubsan's tests will fail.
>>>>
>>>> Please review!
>>>>
>>>> Nick
>>>>
>>>
>>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> [email protected]
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>
>>
>
Index: tools/clang/lib/CodeGen/CGExpr.cpp
===================================================================
--- tools/clang/lib/CodeGen/CGExpr.cpp	(revision 193231)
+++ tools/clang/lib/CodeGen/CGExpr.cpp	(working copy)
@@ -2027,7 +2027,11 @@
   uint16_t TypeKind = -1;
   uint16_t TypeInfo = 0;
 
-  if (T->isIntegerType()) {
+  if (T->isEnumeralType()) {
+    TypeKind = 2;
+    TypeInfo = (llvm::Log2_32(getContext().getTypeSize(T)) << 1) |
+               (T->isSignedIntegerType() ? 1 : 0);
+  } else if (T->isIntegerType()) {
     TypeKind = 0;
     TypeInfo = (llvm::Log2_32(getContext().getTypeSize(T)) << 1) |
                (T->isSignedIntegerType() ? 1 : 0);
Index: projects/compiler-rt/lib/ubsan/lit_tests/Misc/enum.cpp
===================================================================
--- projects/compiler-rt/lib/ubsan/lit_tests/Misc/enum.cpp	(revision 193231)
+++ projects/compiler-rt/lib/ubsan/lit_tests/Misc/enum.cpp	(working copy)
@@ -11,7 +11,8 @@
     *p = 0xff;
 
   // CHECK-PLAIN: error: load of value 4294967295, which is not a valid value for type 'enum E'
-  // FIXME: Support marshalling and display of enum class values.
-  // CHECK-BOOL: error: load of value <unknown>, which is not a valid value for type 'enum E'
+  // CHECK-PLAIN: UndefinedBehaviorSanitizer: enum
+  // CHECK-BOOL: error: load of value 255, which is not a valid value for type 'enum E'
+  // CHECK-BOOL: UndefinedBehaviorSanitizer: enum
   return (int)e != -1;
 }
Index: projects/compiler-rt/lib/ubsan/lit_tests/Misc/bool.cpp
===================================================================
--- projects/compiler-rt/lib/ubsan/lit_tests/Misc/bool.cpp	(revision 193231)
+++ projects/compiler-rt/lib/ubsan/lit_tests/Misc/bool.cpp	(working copy)
@@ -5,6 +5,7 @@
 int main(int argc, char **argv) {
   bool *p = (bool*)&NotABool;
 
-  // CHECK: bool.cpp:9:10: runtime error: load of value 123, which is not a valid value for type 'bool'
+  // CHECK: bool.cpp:10:10: runtime error: load of value 123, which is not a valid value for type 'bool'
+  // CHECK-NEXT: UndefinedBehaviorSanitizer: bool
   return *p;
 }
Index: projects/compiler-rt/lib/ubsan/lit_tests/TypeCheck/misaligned.cpp
===================================================================
--- projects/compiler-rt/lib/ubsan/lit_tests/TypeCheck/misaligned.cpp	(revision 193231)
+++ projects/compiler-rt/lib/ubsan/lit_tests/TypeCheck/misaligned.cpp	(working copy)
@@ -26,14 +26,16 @@
 
   switch (argv[1][0]) {
   case 'l':
-    // CHECK-LOAD: misaligned.cpp:[[@LINE+4]]:12: runtime error: load of misaligned address [[PTR:0x[0-9a-f]*]] for type 'int', which requires 4 byte alignment
+    // CHECK-LOAD: misaligned.cpp:[[@LINE+5]]:12: runtime error: load of misaligned address [[PTR:0x[0-9a-f]*]] for type 'int', which requires 4 byte alignment
+    // CHECK-LOAD-NEXT: UndefinedBehaviorSanitizer:
     // CHECK-LOAD-NEXT: [[PTR]]: note: pointer points here
     // CHECK-LOAD-NEXT: {{^ 00 00 00 01 02 03 04  05}}
     // CHECK-LOAD-NEXT: {{^             \^}}
     return *p && 0;
 
   case 's':
-    // CHECK-STORE: misaligned.cpp:[[@LINE+4]]:5: runtime error: store to misaligned address [[PTR:0x[0-9a-f]*]] for type 'int', which requires 4 byte alignment
+    // CHECK-STORE: misaligned.cpp:[[@LINE+5]]:5: runtime error: store to misaligned address [[PTR:0x[0-9a-f]*]] for type 'int', which requires 4 byte alignment
+    // CHECK-STORE-NEXT: UndefinedBehaviorSanitizer:
     // CHECK-STORE-NEXT: [[PTR]]: note: pointer points here
     // CHECK-STORE-NEXT: {{^ 00 00 00 01 02 03 04  05}}
     // CHECK-STORE-NEXT: {{^             \^}}
@@ -41,7 +43,8 @@
     break;
 
   case 'r':
-    // CHECK-REFERENCE: misaligned.cpp:[[@LINE+4]]:15: runtime error: reference binding to misaligned address [[PTR:0x[0-9a-f]*]] for type 'int', which requires 4 byte alignment
+    // CHECK-REFERENCE: misaligned.cpp:[[@LINE+5]]:15: runtime error: reference binding to misaligned address [[PTR:0x[0-9a-f]*]] for type 'int', which requires 4 byte alignment
+    // CHECK-REFERENCE-NEXT: UndefinedBehaviorSanitizer:
     // CHECK-REFERENCE-NEXT: [[PTR]]: note: pointer points here
     // CHECK-REFERENCE-NEXT: {{^ 00 00 00 01 02 03 04  05}}
     // CHECK-REFERENCE-NEXT: {{^             \^}}
@@ -49,14 +52,16 @@
     break;
 
   case 'm':
-    // CHECK-MEMBER: misaligned.cpp:[[@LINE+4]]:15: runtime error: member access within misaligned address [[PTR:0x[0-9a-f]*]] for type 'S', which requires 4 byte alignment
+    // CHECK-MEMBER: misaligned.cpp:[[@LINE+5]]:15: runtime error: member access within misaligned address [[PTR:0x[0-9a-f]*]] for type 'S', which requires 4 byte alignment
+    // CHECK-MEMBER-NEXT: UndefinedBehaviorSanitizer:
     // CHECK-MEMBER-NEXT: [[PTR]]: note: pointer points here
     // CHECK-MEMBER-NEXT: {{^ 00 00 00 01 02 03 04  05}}
     // CHECK-MEMBER-NEXT: {{^             \^}}
     return s->k && 0;
 
   case 'f':
-    // CHECK-MEMFUN: misaligned.cpp:[[@LINE+4]]:12: runtime error: member call on misaligned address [[PTR:0x[0-9a-f]*]] for type 'S', which requires 4 byte alignment
+    // CHECK-MEMFUN: misaligned.cpp:[[@LINE+5]]:12: runtime error: member call on misaligned address [[PTR:0x[0-9a-f]*]] for type 'S', which requires 4 byte alignment
+    // CHECK-MEMFUN-NEXT: UndefinedBehaviorSanitizer:
     // CHECK-MEMFUN-NEXT: [[PTR]]: note: pointer points here
     // CHECK-MEMFUN-NEXT: {{^ 00 00 00 01 02 03 04  05}}
     // CHECK-MEMFUN-NEXT: {{^             \^}}
@@ -65,6 +70,7 @@
   case 'n':
     // FIXME: Provide a better source location here.
     // CHECK-NEW: misaligned{{.*}}+0x{{[0-9a-f]*}}): runtime error: constructor call on misaligned address [[PTR:0x[0-9a-f]*]] for type 'S', which requires 4 byte alignment
+    // CHECK-NEW-NEXT: UndefinedBehaviorSanitizer:
     // CHECK-NEW-NEXT: [[PTR]]: note: pointer points here
     // CHECK-NEW-NEXT: {{^ 00 00 00 01 02 03 04  05}}
     // CHECK-NEW-NEXT: {{^             \^}}
Index: projects/compiler-rt/lib/ubsan/lit_tests/TypeCheck/Function/function.cpp
===================================================================
--- projects/compiler-rt/lib/ubsan/lit_tests/TypeCheck/Function/function.cpp	(revision 193231)
+++ projects/compiler-rt/lib/ubsan/lit_tests/TypeCheck/Function/function.cpp	(working copy)
@@ -9,6 +9,7 @@
 
 int main(void) {
   // CHECK: runtime error: call to function f() through pointer to incorrect function type 'void (*)(int)'
+  // CHECK-NEXT: UndefinedBehaviorSanitizer:
   // CHECK-NEXT: function.cpp:6: note: f() defined here
   reinterpret_cast<void (*)(int)>(reinterpret_cast<uintptr_t>(f))(42);
 
Index: projects/compiler-rt/lib/ubsan/lit_tests/TypeCheck/vptr.cpp
===================================================================
--- projects/compiler-rt/lib/ubsan/lit_tests/TypeCheck/vptr.cpp	(revision 193231)
+++ projects/compiler-rt/lib/ubsan/lit_tests/TypeCheck/vptr.cpp	(working copy)
@@ -76,7 +76,8 @@
     break;
 
   case 'm':
-    // CHECK-MEMBER: vptr.cpp:[[@LINE+5]]:15: runtime error: member access within address [[PTR:0x[0-9a-f]*]] which does not point to an object of type 'T'
+    // CHECK-MEMBER: vptr.cpp:[[@LINE+6]]:15: runtime error: member access within address [[PTR:0x[0-9a-f]*]] which does not point to an object of type 'T'
+    // CHECK-MEMBER-NEXT: UndefinedBehaviorSanitizer
     // CHECK-MEMBER-NEXT: [[PTR]]: note: object is of type [[DYN_TYPE:'S'|'U']]
     // CHECK-MEMBER-NEXT: {{^ .. .. .. ..  .. .. .. .. .. .. .. ..  }}
     // CHECK-MEMBER-NEXT: {{^              \^~~~~~~~~~~(~~~~~~~~~~~~)? *$}}
@@ -84,13 +85,15 @@
     return p->b;
 
     // CHECK-NULL-MEMBER: vptr.cpp:[[@LINE-2]]:15: runtime error: member access within address [[PTR:0x[0-9a-f]*]] which does not point to an object of type 'T'
+    // CHECK-NULL-MEMBER-NEXT: UndefinedBehaviorSanitizer
     // CHECK-NULL-MEMBER-NEXT: [[PTR]]: note: object has invalid vptr
     // CHECK-NULL-MEMBER-NEXT: {{^ .. .. .. ..  00 00 00 00 00 00 00 00  }}
     // CHECK-NULL-MEMBER-NEXT: {{^              \^~~~~~~~~~~(~~~~~~~~~~~~)? *$}}
     // CHECK-NULL-MEMBER-NEXT: {{^              invalid vptr}}
 
   case 'f':
-    // CHECK-MEMFUN: vptr.cpp:[[@LINE+5]]:12: runtime error: member call on address [[PTR:0x[0-9a-f]*]] which does not point to an object of type 'T'
+    // CHECK-MEMFUN: vptr.cpp:[[@LINE+6]]:12: runtime error: member call on address [[PTR:0x[0-9a-f]*]] which does not point to an object of type 'T'
+    // CHECK-MEMFUN-NEXT: UndefinedBehaviorSanitizer
     // CHECK-MEMFUN-NEXT: [[PTR]]: note: object is of type [[DYN_TYPE:'S'|'U']]
     // CHECK-MEMFUN-NEXT: {{^ .. .. .. ..  .. .. .. .. .. .. .. ..  }}
     // CHECK-MEMFUN-NEXT: {{^              \^~~~~~~~~~~(~~~~~~~~~~~~)? *$}}
@@ -98,7 +101,8 @@
     return p->g();
 
   case 'o':
-    // CHECK-OFFSET: vptr.cpp:[[@LINE+5]]:12: runtime error: member call on address [[PTR:0x[0-9a-f]*]] which does not point to an object of type 'U'
+    // CHECK-OFFSET: vptr.cpp:[[@LINE+6]]:12: runtime error: member call on address [[PTR:0x[0-9a-f]*]] which does not point to an object of type 'U'
+    // CHECK-OFFSET-NEXT: UndefinedBehaviorSanitizer
     // CHECK-OFFSET-NEXT: 0x{{[0-9a-f]*}}: note: object is base class subobject at offset {{8|16}} within object of type [[DYN_TYPE:'U']]
     // CHECK-OFFSET-NEXT: {{^ .. .. .. ..  .. .. .. .. .. .. .. ..  .. .. .. .. .. .. .. ..  .. .. .. .. .. .. .. ..  }}
     // CHECK-OFFSET-NEXT: {{^              \^                        (                         ~~~~~~~~~~~~)~~~~~~~~~~~ *$}}
@@ -106,7 +110,8 @@
     return reinterpret_cast<U*>(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: vptr.cpp:[[@LINE+6]]:5: runtime error: downcast of address [[PTR:0x[0-9a-f]*]] which does not point to an object of type 'T'
+    // CHECK-DOWNCAST-NEXT: UndefinedBehaviorSanitizer
     // CHECK-DOWNCAST-NEXT: [[PTR]]: note: object is of type [[DYN_TYPE:'S'|'U']]
     // CHECK-DOWNCAST-NEXT: {{^ .. .. .. ..  .. .. .. .. .. .. .. ..  }}
     // CHECK-DOWNCAST-NEXT: {{^              \^~~~~~~~~~~(~~~~~~~~~~~~)? *$}}
Index: projects/compiler-rt/lib/ubsan/ubsan_value.h
===================================================================
--- projects/compiler-rt/lib/ubsan/ubsan_value.h	(revision 193231)
+++ projects/compiler-rt/lib/ubsan/ubsan_value.h	(working copy)
@@ -111,6 +111,9 @@
     /// representation is that of bitcasting the floating-point value to an
     /// integer type.
     TK_Float = 0x0001,
+    /// An enum type. Lower bit is 1 for a signed underlying type, 0 for an
+    /// unsigned underlying type. Remaining bits are log_2(bit width).
+    TK_Enum = 0x0002,
     /// Any other type. The value representation is unspecified.
     TK_Unknown = 0xffff
   };
@@ -122,14 +125,15 @@
   }
 
   bool isIntegerTy() const { return getKind() == TK_Integer; }
+  bool isIntegralTy() const { return isIntegerTy() || isEnumTy(); }
   bool isSignedIntegerTy() const {
-    return isIntegerTy() && (TypeInfo & 1);
+    return isIntegralTy() && (TypeInfo & 1);
   }
   bool isUnsignedIntegerTy() const {
-    return isIntegerTy() && !(TypeInfo & 1);
+    return isIntegralTy() && !(TypeInfo & 1);
   }
   unsigned getIntegerBitWidth() const {
-    CHECK(isIntegerTy());
+    CHECK(isIntegralTy());
     return 1 << (TypeInfo >> 1);
   }
 
@@ -138,6 +142,8 @@
     CHECK(isFloatTy());
     return TypeInfo;
   }
+
+  bool isEnumTy() const { return getKind() == TK_Enum; }
 };
 
 /// \brief An opaque handle to a value.
@@ -157,7 +163,7 @@
 
   /// Is \c Val a (zero-extended) integer?
   bool isInlineInt() const {
-    CHECK(getType().isIntegerTy());
+    CHECK(getType().isIntegralTy());
     const unsigned InlineBits = sizeof(ValueHandle) * 8;
     const unsigned Bits = getType().getIntegerBitWidth();
     return Bits <= InlineBits;
Index: projects/compiler-rt/lib/ubsan/ubsan_handlers.cc
===================================================================
--- projects/compiler-rt/lib/ubsan/ubsan_handlers.cc	(revision 193231)
+++ projects/compiler-rt/lib/ubsan/ubsan_handlers.cc	(working copy)
@@ -37,19 +37,19 @@
     Loc = FallbackLoc;
 
   if (!Pointer)
-    Diag(Loc, DL_Error, "%0 null pointer of type %1")
+    Diag(Loc, DL_Error, "null", "%0 null pointer of type %1")
       << TypeCheckKinds[Data->TypeCheckKind] << Data->Type;
   else if (Data->Alignment && (Pointer & (Data->Alignment - 1)))
-    Diag(Loc, DL_Error, "%0 misaligned address %1 for type %3, "
+    Diag(Loc, DL_Error, "alignment", "%0 misaligned address %1 for type %3, "
                         "which requires %2 byte alignment")
       << TypeCheckKinds[Data->TypeCheckKind] << (void*)Pointer
       << Data->Alignment << Data->Type;
   else
-    Diag(Loc, DL_Error, "%0 address %1 with insufficient space "
+    Diag(Loc, DL_Error, "object-size", "%0 address %1 with insufficient space "
                         "for an object of type %2")
       << TypeCheckKinds[Data->TypeCheckKind] << (void*)Pointer << Data->Type;
   if (Pointer)
-    Diag(Pointer, DL_Note, "pointer points here");
+    Diag(Pointer, DL_Note, "", "pointer points here");
 }
 void __ubsan::__ubsan_handle_type_mismatch(TypeMismatchData *Data,
                                            ValueHandle Pointer) {
@@ -70,10 +70,15 @@
   if (Loc.isDisabled())
     return;
 
-  Diag(Loc, DL_Error, "%0 integer overflow: "
-                      "%1 %2 %3 cannot be represented in type %4")
-    << (Data->Type.isSignedIntegerTy() ? "signed" : "unsigned")
+  if (Data->Type.isSignedIntegerTy()) {
+    Diag(Loc, DL_Error, "signed-integer-overflow",
+         "signed integer overflow: %0 %1 %2 cannot be represented in type %3")
     << Value(Data->Type, LHS) << Operator << RHS << Data->Type;
+  } else {
+    Diag(Loc, DL_Error, "unsigned-integer-overflow",
+         "unsigned integer overflow: %0 %1 %2 cannot be represented in type %3")
+    << Value(Data->Type, LHS) << Operator << RHS << Data->Type;
+  }
 }
 
 void __ubsan::__ubsan_handle_add_overflow(OverflowData *Data,
@@ -116,12 +121,12 @@
     return;
 
   if (Data->Type.isSignedIntegerTy())
-    Diag(Loc, DL_Error,
+    Diag(Loc, DL_Error, "signed-integer-overflow",
          "negation of %0 cannot be represented in type %1; "
          "cast to an unsigned type to negate this value to itself")
       << Value(Data->Type, OldVal) << Data->Type;
   else
-    Diag(Loc, DL_Error,
+    Diag(Loc, DL_Error, "unsigned-integer-overflow",
          "negation of %0 cannot be represented in type %1")
       << Value(Data->Type, OldVal) << Data->Type;
 }
@@ -140,11 +145,15 @@
   Value LHSVal(Data->Type, LHS);
   Value RHSVal(Data->Type, RHS);
   if (RHSVal.isMinusOne())
-    Diag(Loc, DL_Error,
+    Diag(Loc, DL_Error, "signed-integer-overflow",
          "division of %0 by -1 cannot be represented in type %1")
       << LHSVal << Data->Type;
-  else
-    Diag(Loc, DL_Error, "division by zero");
+  else {
+    Diag(Loc, DL_Error,
+         Data->Type.isFloatTy() ? "float-divide-by-zero"
+                                : "integer-divide-by-zero",
+         "division by zero");
+  }
 }
 void __ubsan::__ubsan_handle_divrem_overflow_abort(OverflowData *Data,
                                                     ValueHandle LHS,
@@ -163,15 +172,15 @@
   Value LHSVal(Data->LHSType, LHS);
   Value RHSVal(Data->RHSType, RHS);
   if (RHSVal.isNegative())
-    Diag(Loc, DL_Error, "shift exponent %0 is negative") << RHSVal;
+    Diag(Loc, DL_Error, "shift", "shift exponent %0 is negative") << RHSVal;
   else if (RHSVal.getPositiveIntValue() >= Data->LHSType.getIntegerBitWidth())
-    Diag(Loc, DL_Error,
+    Diag(Loc, DL_Error, "shift",
          "shift exponent %0 is too large for %1-bit type %2")
       << RHSVal << Data->LHSType.getIntegerBitWidth() << Data->LHSType;
   else if (LHSVal.isNegative())
-    Diag(Loc, DL_Error, "left shift of negative value %0") << LHSVal;
+    Diag(Loc, DL_Error, "shift", "left shift of negative value %0") << LHSVal;
   else
-    Diag(Loc, DL_Error,
+    Diag(Loc, DL_Error, "shift",
          "left shift of %0 by %1 places cannot be represented in type %2")
       << LHSVal << RHSVal << Data->LHSType;
 }
@@ -190,7 +199,7 @@
     return;
 
   Value IndexVal(Data->IndexType, Index);
-  Diag(Loc, DL_Error, "index %0 out of bounds for type %1")
+  Diag(Loc, DL_Error, "bounds", "index %0 out of bounds for type %1")
     << IndexVal << Data->ArrayType;
 }
 void __ubsan::__ubsan_handle_out_of_bounds_abort(OutOfBoundsData *Data,
@@ -200,12 +209,13 @@
 }
 
 void __ubsan::__ubsan_handle_builtin_unreachable(UnreachableData *Data) {
-  Diag(Data->Loc, DL_Error, "execution reached a __builtin_unreachable() call");
+  Diag(Data->Loc, DL_Error, "unreachable",
+       "execution reached a __builtin_unreachable() call");
   Die();
 }
 
 void __ubsan::__ubsan_handle_missing_return(UnreachableData *Data) {
-  Diag(Data->Loc, DL_Error,
+  Diag(Data->Loc, DL_Error, "return",
        "execution reached the end of a value-returning function "
        "without returning a value");
   Die();
@@ -217,8 +227,8 @@
   if (Loc.isDisabled())
     return;
 
-  Diag(Loc, DL_Error, "variable length array bound evaluates to "
-                      "non-positive value %0")
+  Diag(Loc, DL_Error, "vla-bound", "variable length array bound evaluates to "
+                                   "non-positive value %0")
     << Value(Data->Type, Bound);
 }
 void __ubsan::__ubsan_handle_vla_bound_not_positive_abort(VLABoundData *Data,
@@ -231,14 +241,14 @@
 void __ubsan::__ubsan_handle_float_cast_overflow(FloatCastOverflowData *Data,
                                                  ValueHandle From) {
   // TODO: Add deduplication once a SourceLocation is generated for this check.
-  Diag(getCallerLocation(), DL_Error,
+  Diag(getCallerLocation(), DL_Error, "float-cast-overflow",
        "value %0 is outside the range of representable values of type %2")
     << Value(Data->FromType, From) << Data->FromType << Data->ToType;
 }
 void __ubsan::__ubsan_handle_float_cast_overflow_abort(
                                                     FloatCastOverflowData *Data,
                                                     ValueHandle From) {
-  Diag(getCallerLocation(), DL_Error,
+  Diag(getCallerLocation(), DL_Error, "float-cast-overflow",
        "value %0 is outside the range of representable values of type %2")
     << Value(Data->FromType, From) << Data->FromType << Data->ToType;
   Die();
@@ -250,7 +260,11 @@
   if (Loc.isDisabled())
     return;
 
-  Diag(Loc, DL_Error,
+  // "class E : bool" is caught by the enum sanitizer, not the bool sanitizer.
+  bool isBoolSanitizer =
+      internal_strcmp(Data->Type.getTypeName(), "'bool'") == 0;
+
+  Diag(Loc, DL_Error, Data->Type.isEnumTy() ? "enum" : "bool",
        "load of value %0, which is not a valid value for type %1")
     << Value(Data->Type, Val) << Data->Type;
 }
@@ -267,10 +281,10 @@
 
   Location Loc = getFunctionLocation(Function, &FName);
 
-  Diag(Data->Loc, DL_Error,
+  Diag(Data->Loc, DL_Error, "function",
        "call to function %0 through pointer to incorrect function type %1")
     << FName << Data->Type;
-  Diag(Loc, DL_Note, "%0 defined here") << FName;
+  Diag(Loc, DL_Note, "", "%0 defined here") << FName;
 }
 
 void __ubsan::__ubsan_handle_function_type_mismatch_abort(
Index: projects/compiler-rt/lib/ubsan/ubsan_handlers_cxx.cc
===================================================================
--- projects/compiler-rt/lib/ubsan/ubsan_handlers_cxx.cc	(revision 193231)
+++ projects/compiler-rt/lib/ubsan/ubsan_handlers_cxx.cc	(working copy)
@@ -37,24 +37,24 @@
   if (Loc.isDisabled())
     return;
 
-  Diag(Loc, DL_Error,
+  Diag(Loc, DL_Error, "vptr",
        "%0 address %1 which does not point to an object of type %2")
     << TypeCheckKinds[Data->TypeCheckKind] << (void*)Pointer << Data->Type;
 
   // If possible, say what type it actually points to.
   DynamicTypeInfo DTI = getDynamicTypeInfo((void*)Pointer);
   if (!DTI.isValid())
-    Diag(Pointer, DL_Note, "object has invalid vptr")
+    Diag(Pointer, DL_Note, "", "object has invalid vptr")
       << MangledName(DTI.getMostDerivedTypeName())
       << Range(Pointer, Pointer + sizeof(uptr), "invalid vptr");
   else if (!DTI.getOffset())
-    Diag(Pointer, DL_Note, "object is of type %0")
+    Diag(Pointer, DL_Note, "", "object is of type %0")
       << MangledName(DTI.getMostDerivedTypeName())
       << Range(Pointer, Pointer + sizeof(uptr), "vptr for %0");
   else
     // FIXME: Find the type at the specified offset, and include that
     //        in the note.
-    Diag(Pointer - DTI.getOffset(), DL_Note,
+    Diag(Pointer - DTI.getOffset(), DL_Note, "",
          "object is base class subobject at offset %0 within object of type %1")
       << DTI.getOffset() << MangledName(DTI.getMostDerivedTypeName())
       << MangledName(DTI.getSubobjectTypeName())
Index: projects/compiler-rt/lib/ubsan/ubsan_diag.cc
===================================================================
--- projects/compiler-rt/lib/ubsan/ubsan_diag.cc	(revision 193231)
+++ projects/compiler-rt/lib/ubsan/ubsan_diag.cc	(working copy)
@@ -13,6 +13,7 @@
 
 #include "ubsan_diag.h"
 #include "sanitizer_common/sanitizer_common.h"
+#include "sanitizer_common/sanitizer_flags.h"
 #include "sanitizer_common/sanitizer_libc.h"
 #include "sanitizer_common/sanitizer_report_decorator.h"
 #include "sanitizer_common/sanitizer_stacktrace.h"
@@ -268,4 +269,35 @@
   if (Loc.isMemoryLocation())
     renderMemorySnippet(Decor, Loc.getMemoryLocation(), Ranges,
                         NumRanges, Args);
+
+  if (Level == DL_Error) {
+    InternalScopedBuffer<char> summary(1024);
+    internal_snprintf(summary.data(), summary.size(),
+                      "UndefinedBehaviorSanitizer: %s", Flag);
+    switch (Loc.getKind()) {
+      case Location::LK_Null:
+        break;
+      case Location::LK_Source: {
+        SourceLocation SLoc = Loc.getSourceLocation();
+        internal_snprintf(summary.data(), summary.size(), "%s %s:%u:%u",
+                          summary.data(),
+                          SLoc.getFilename(), SLoc.getLine(), SLoc.getColumn());
+        break;
+      }
+      case Location::LK_Module: {
+        ModuleLocation MLoc = Loc.getModuleLocation();
+        internal_snprintf(
+            summary.data(), summary.size(), "%s (%s+0x%zx)", summary.data(),
+            StripPathPrefix(MLoc.getModuleName(),
+                            __sanitizer::common_flags()->strip_path_prefix),
+            MLoc.getOffset());
+        break;
+      }
+      case Location::LK_Memory:
+        internal_snprintf(summary.data(), summary.size(),
+                          " %p", summary.data(), Loc.getMemoryLocation());
+        break;
+    }
+    __sanitizer_report_error_summary(summary.data());
+  }
 }
Index: projects/compiler-rt/lib/ubsan/ubsan_diag.h
===================================================================
--- projects/compiler-rt/lib/ubsan/ubsan_diag.h	(revision 193231)
+++ projects/compiler-rt/lib/ubsan/ubsan_diag.h	(working copy)
@@ -130,6 +130,9 @@
   /// arguments.
   const char *Message;
 
+  /// The flag with which this diagnostic is associated. -fsanitize=<flag>
+  const char *Flag;
+
 public:
   /// Kinds of arguments, corresponding to members of \c Arg's union.
   enum ArgKind {
@@ -190,8 +193,13 @@
   Diag &operator=(const Diag &);
 
 public:
-  Diag(Location Loc, DiagLevel Level, const char *Message)
-    : Loc(Loc), Level(Level), Message(Message), NumArgs(0), NumRanges(0) {}
+  Diag(Location Loc, DiagLevel Level, const char *Flag, const char *Message)
+    : Loc(Loc),
+      Level(Level),
+      Message(Message),
+      Flag(Flag),
+      NumArgs(0),
+      NumRanges(0) {}
   ~Diag();
 
   Diag &operator<<(const char *Str) { return AddArg(Str); }
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to