ubsan_diag.cc revision ba3fde65b900ce9d0ecdf034dfe3825eea810434
1//===-- ubsan_diag.cc -----------------------------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// Diagnostic reporting for the UBSan runtime. 11// 12//===----------------------------------------------------------------------===// 13 14#include "ubsan_diag.h" 15#include <stdio.h> 16#include <unistd.h> 17#include <limits.h> 18 19using namespace __ubsan; 20 21Diag &Diag::operator<<(const TypeDescriptor &V) { 22 return AddArg(V.getTypeName()); 23} 24 25Diag &Diag::operator<<(const Value &V) { 26 if (V.getType().isSignedIntegerTy()) 27 AddArg(V.getSIntValue()); 28 else if (V.getType().isUnsignedIntegerTy()) 29 AddArg(V.getUIntValue()); 30 else if (V.getType().isFloatTy()) 31 AddArg(V.getFloatValue()); 32 else 33 AddArg("<unknown>"); 34 return *this; 35} 36 37/// Hexadecimal printing for numbers too large for fprintf to handle directly. 38static void PrintHex(UIntMax Val) { 39#if HAVE_INT128_T 40 fprintf(stderr, "0x%08x%08x%08x%08x", 41 (unsigned int)(Val >> 96), 42 (unsigned int)(Val >> 64), 43 (unsigned int)(Val >> 32), 44 (unsigned int)(Val)); 45#else 46 UNREACHABLE("long long smaller than 64 bits?"); 47#endif 48} 49 50Diag::~Diag() { 51 // FIXME: This is non-portable. 52 bool UseAnsiColor = isatty(STDERR_FILENO); 53 if (UseAnsiColor) 54 fprintf(stderr, "\033[1m"); 55 if (Loc.isInvalid()) 56 fprintf(stderr, "<unknown>:"); 57 else { 58 fprintf(stderr, "%s:%d:", Loc.getFilename(), Loc.getLine()); 59 if (Loc.getColumn()) 60 fprintf(stderr, "%d:", Loc.getColumn()); 61 } 62 if (UseAnsiColor) 63 fprintf(stderr, "\033[31m"); 64 fprintf(stderr, " fatal error: "); 65 if (UseAnsiColor) 66 fprintf(stderr, "\033[0;1m"); 67 for (const char *Msg = Message; *Msg; ++Msg) { 68 if (*Msg != '%') 69 fputc((unsigned char)*Msg, stderr); 70 else { 71 const Arg &A = Args[*++Msg - '0']; 72 switch (A.Kind) { 73 case AK_String: 74 fprintf(stderr, "%s", A.String); 75 break; 76 case AK_SInt: 77 // 'long long' is guaranteed to be at least 64 bits wide. 78 if (A.SInt >= INT64_MIN && A.SInt <= INT64_MAX) 79 fprintf(stderr, "%lld", (long long)A.SInt); 80 else 81 PrintHex(A.SInt); 82 break; 83 case AK_UInt: 84 if (A.UInt <= UINT64_MAX) 85 fprintf(stderr, "%llu", (unsigned long long)A.UInt); 86 else 87 PrintHex(A.UInt); 88 break; 89 case AK_Float: 90 fprintf(stderr, "%Lg", (long double)A.Float); 91 break; 92 case AK_Pointer: 93 fprintf(stderr, "0x%zx", (uptr)A.Pointer); 94 break; 95 } 96 } 97 } 98 fputc('\n', stderr); 99 if (UseAnsiColor) 100 fprintf(stderr, "\033[0m"); 101 fflush(stderr); 102} 103