diff --git a/src/core/Context.cpp b/src/core/Context.cpp index 4c024d41..d43e8135 100644 --- a/src/core/Context.cpp +++ b/src/core/Context.cpp @@ -182,9 +182,9 @@ void Context::unregisterPlugin(Plugin *plugin) m_plugins.remove(make_pair(plugin, false)); } -void Context::logError(const char* error) const +void Context::logError(const char* error, MessageType type) const { - Message msg(ERROR, this); + Message msg(type, this); msg << error << endl << msg.INDENT << "Kernel: " << msg.CURRENT_KERNEL << endl diff --git a/src/core/Context.h b/src/core/Context.h old mode 100644 new mode 100755 index c853cf6f..364bd6cf --- a/src/core/Context.h +++ b/src/core/Context.h @@ -27,7 +27,7 @@ namespace oclgrind Memory* getGlobalMemory() const; bool isThreadSafe() const; - void logError(const char* error) const; + void logError(const char* error, MessageType type = OCLGRIND_ERROR) const; // Simulation callbacks void notifyInstructionExecuted(const WorkItem *workItem, diff --git a/src/core/KernelInvocation.cpp b/src/core/KernelInvocation.cpp old mode 100644 new mode 100755 index a54f8654..9fe4e225 --- a/src/core/KernelInvocation.cpp +++ b/src/core/KernelInvocation.cpp @@ -164,7 +164,7 @@ void KernelInvocation::run(const Context *context, Kernel *kernel, << endl << err.what() << endl << "When allocating kernel constants for '" << kernel->getName() << "'"; - context->logError(info.str().c_str()); + context->logError(info.str().c_str(), OCLGRIND_ERROR_FATAL); return; } @@ -268,7 +268,7 @@ void KernelInvocation::runWorker() info << "OCLGRIND FATAL ERROR " << "(" << err.getFile() << ":" << err.getLine() << ")" << endl << err.what(); - m_context->logError(info.str().c_str()); + m_context->logError(info.str().c_str(), OCLGRIND_ERROR_FATAL); if (workerState.workGroup) delete workerState.workGroup; diff --git a/src/core/WorkGroup.cpp b/src/core/WorkGroup.cpp old mode 100644 new mode 100755 index 2c891c61..ed0f9492 --- a/src/core/WorkGroup.cpp +++ b/src/core/WorkGroup.cpp @@ -125,7 +125,7 @@ size_t WorkGroup::async_copy( (itr->first.srcStride != copy.srcStride) || (itr->first.destStride != copy.destStride)) { - Context::Message msg(ERROR, m_context); + Context::Message msg(OCLGRIND_ERROR_DIVERGENCE, m_context); msg << "Work-group divergence detected (async copy)" << endl << msg.INDENT << "Kernel: " << msg.CURRENT_KERNEL << endl @@ -180,7 +180,7 @@ void WorkGroup::clearBarrier() // Check for divergence if (m_barrier->workItems.size() != m_workItems.size()) { - Context::Message msg(ERROR, m_context); + Context::Message msg(OCLGRIND_ERROR_DIVERGENCE, m_context); msg << "Work-group divergence detected (barrier)" << endl << msg.INDENT << "Kernel: " << msg.CURRENT_KERNEL << endl @@ -247,7 +247,7 @@ void WorkGroup::clearBarrier() // Check that all work-items registered the copy if (cItr->second.size() != m_workItems.size()) { - Context::Message msg(ERROR, m_context); + Context::Message msg(OCLGRIND_ERROR_DIVERGENCE, m_context); msg << "Work-group divergence detected (async copy)" << endl << msg.INDENT << "Kernel: " << msg.CURRENT_KERNEL << endl @@ -385,7 +385,7 @@ void WorkGroup::notifyBarrier(WorkItem *workItem, if (divergence) { - Context::Message msg(ERROR, m_context); + Context::Message msg(OCLGRIND_ERROR_DIVERGENCE, m_context); msg << "Work-group divergence detected (barrier)" << endl << msg.INDENT << "Kernel: " << msg.CURRENT_KERNEL << endl diff --git a/src/core/WorkItem.cpp b/src/core/WorkItem.cpp old mode 100644 new mode 100755 index c5faaf00..54f6e5fa --- a/src/core/WorkItem.cpp +++ b/src/core/WorkItem.cpp @@ -1154,7 +1154,7 @@ INSTRUCTION(load) if (address & (alignment-1)) { m_context->logError("Invalid memory load - source pointer is " - "not aligned to the pointed type"); + "not aligned to the pointed type", OCLGRIND_ERROR_UNALIGNED); } // Load data @@ -1374,7 +1374,7 @@ INSTRUCTION(store) if (address & (alignment-1)) { m_context->logError("Invalid memory store - source pointer is " - "not aligned to the pointed type"); + "not aligned to the pointed type", OCLGRIND_ERROR_UNALIGNED); } // Store data diff --git a/src/core/WorkItemBuiltins.cpp b/src/core/WorkItemBuiltins.cpp old mode 100644 new mode 100755 index 1f1427c5..918ea5f7 --- a/src/core/WorkItemBuiltins.cpp +++ b/src/core/WorkItemBuiltins.cpp @@ -284,7 +284,7 @@ namespace oclgrind size_t address = PARG(0); // Verify the address is 4-byte aligned if ((address & 0x3) != 0) { - workItem->m_context->logError("Unaligned address on atomic_add"); + workItem->m_context->logError("Unaligned address on atomic_add", OCLGRIND_ERROR_UNALIGNED); } uint32_t old = memory->atomic(AtomicAdd, address, UARG(1)); result.setUInt(old); @@ -298,7 +298,7 @@ namespace oclgrind size_t address = PARG(0); // Verify the address is 4-byte aligned if ((address & 0x3) != 0) { - workItem->m_context->logError("Unaligned address on atomic_and"); + workItem->m_context->logError("Unaligned address on atomic_and", OCLGRIND_ERROR_UNALIGNED); } uint32_t old = memory->atomic(AtomicAnd, address, UARG(1)); result.setUInt(old); @@ -312,7 +312,7 @@ namespace oclgrind size_t address = PARG(0); // Verify the address is 4-byte aligned if ((address & 0x3) != 0) { - workItem->m_context->logError("Unaligned address on atomic_cmpxchg"); + workItem->m_context->logError("Unaligned address on atomic_cmpxchg", OCLGRIND_ERROR_UNALIGNED); } uint32_t old = memory->atomicCmpxchg(address, UARG(1), UARG(2)); result.setUInt(old); @@ -326,7 +326,7 @@ namespace oclgrind size_t address = PARG(0); // Verify the address is 4-byte aligned if ((address & 0x3) != 0) { - workItem->m_context->logError("Unaligned address on atomic_dec"); + workItem->m_context->logError("Unaligned address on atomic_dec", OCLGRIND_ERROR_UNALIGNED); } uint32_t old = memory->atomic(AtomicDec, address); result.setUInt(old); @@ -340,7 +340,7 @@ namespace oclgrind size_t address = PARG(0); // Verify the address is 4-byte aligned if ((address & 0x3) != 0) { - workItem->m_context->logError("Unaligned address on atomic_dec"); + workItem->m_context->logError("Unaligned address on atomic_dec", OCLGRIND_ERROR_UNALIGNED); } uint32_t old = memory->atomic(AtomicInc, address); result.setUInt(old); @@ -354,7 +354,7 @@ namespace oclgrind size_t address = PARG(0); // Verify the address is 4-byte aligned if ((address & 0x3) != 0) { - workItem->m_context->logError("Unaligned address on atomic_max"); + workItem->m_context->logError("Unaligned address on atomic_max", OCLGRIND_ERROR_UNALIGNED); } uint32_t old = memory->atomic(AtomicMax, address, UARG(1)); result.setUInt(old); @@ -368,7 +368,7 @@ namespace oclgrind size_t address = PARG(0); // Verify the address is 4-byte aligned if ((address & 0x3) != 0) { - workItem->m_context->logError("Unaligned address on atomic_min"); + workItem->m_context->logError("Unaligned address on atomic_min", OCLGRIND_ERROR_UNALIGNED); } uint32_t old = memory->atomic(AtomicMin, address, UARG(1)); result.setUInt(old); @@ -382,7 +382,7 @@ namespace oclgrind size_t address = PARG(0); // Verify the address is 4-byte aligned if ((address & 0x3) != 0) { - workItem->m_context->logError("Unaligned address on atomic_or"); + workItem->m_context->logError("Unaligned address on atomic_or", OCLGRIND_ERROR_UNALIGNED); } uint32_t old = memory->atomic(AtomicOr, address, UARG(1)); result.setUInt(old); @@ -396,7 +396,7 @@ namespace oclgrind size_t address = PARG(0); // Verify the address is 4-byte aligned if ((address & 0x3) != 0) { - workItem->m_context->logError("Unaligned address on atomic_sub"); + workItem->m_context->logError("Unaligned address on atomic_sub", OCLGRIND_ERROR_UNALIGNED); } uint32_t old = memory->atomic(AtomicSub, address, UARG(1)); result.setUInt(old); @@ -410,7 +410,7 @@ namespace oclgrind size_t address = PARG(0); // Verify the address is 4-byte aligned if ((address & 0x3) != 0) { - workItem->m_context->logError("Unaligned address on atomic_xchg"); + workItem->m_context->logError("Unaligned address on atomic_xchg", OCLGRIND_ERROR_UNALIGNED); } uint32_t old = memory->atomic(AtomicXchg, address, UARG(1)); result.setUInt(old); @@ -424,7 +424,7 @@ namespace oclgrind size_t address = PARG(0); // Verify the address is 4-byte aligned if ((address & 0x3) != 0) { - workItem->m_context->logError("Unaligned address on atomic_xor"); + workItem->m_context->logError("Unaligned address on atomic_xor", OCLGRIND_ERROR_UNALIGNED); } uint32_t old = memory->atomic(AtomicXor, address, UARG(1)); result.setUInt(old); diff --git a/src/core/common.cpp b/src/core/common.cpp old mode 100644 new mode 100755 index 1e8f44c7..41cc84a8 --- a/src/core/common.cpp +++ b/src/core/common.cpp @@ -765,6 +765,11 @@ namespace oclgrind } } + MessageType getMessageBaseType(MessageType type) + { + return (MessageType)(type & 0x3); + } + FatalError::FatalError(const string& msg, const string& file, size_t line) : std::runtime_error(msg) { diff --git a/src/core/common.h b/src/core/common.h old mode 100644 new mode 100755 index e77a3114..1da4635d --- a/src/core/common.h +++ b/src/core/common.h @@ -89,10 +89,20 @@ namespace oclgrind // Enumeration for different log message types enum MessageType { - DEBUG, - INFO, - WARNING, - ERROR, + // Base types + OCLGRIND_DEBUG = 0, + OCLGRIND_INFO = 1, + OCLGRIND_WARNING = 2, + OCLGRIND_ERROR = 3, + // Special warning types + OCLGRIND_WARNING_UNINITIALIZED = OCLGRIND_WARNING + 4, + // Special error types + OCLGRIND_ERROR_DIVERGENCE = OCLGRIND_ERROR + 4, + OCLGRIND_ERROR_INVALID_ACCESS = OCLGRIND_ERROR + 8, + OCLGRIND_ERROR_DATA_RACE = OCLGRIND_ERROR + 12, + OCLGRIND_ERROR_UNALIGNED = OCLGRIND_ERROR + 16, + OCLGRIND_ERROR_ARRAY_BOUNDS = OCLGRIND_ERROR + 20, + OCLGRIND_ERROR_FATAL = OCLGRIND_ERROR + 24, }; // 3-dimensional size @@ -188,6 +198,9 @@ namespace oclgrind // Print data in a human readable format (according to its type) void printTypedData(const llvm::Type *type, const unsigned char *data); + // Return the base type for a message type + MessageType getMessageBaseType(MessageType type); + // Exception class for raising fatal errors class FatalError : std::runtime_error { diff --git a/src/kernel/oclgrind-kernel.cpp b/src/kernel/oclgrind-kernel.cpp index 1ce599d6..ee95e489 100644 --- a/src/kernel/oclgrind-kernel.cpp +++ b/src/kernel/oclgrind-kernel.cpp @@ -46,9 +46,16 @@ int main(int argc, char *argv[]) static bool parseArguments(int argc, char *argv[]) { + // Collect all diagnostic options before writing them to environment + std::vector diagnosticOptions; + for (int i = 1; i < argc; i++) { - if (!strcmp(argv[i], "--build-options")) + if (!strncmp(argv[i], "-W", 2)) + { + diagnosticOptions.push_back(argv[i]); + } + else if (!strcmp(argv[i], "--build-options")) { if (++i >= argc) { @@ -135,6 +142,15 @@ static bool parseArguments(int argc, char *argv[]) { setEnvironment("OCLGRIND_QUICK", "1"); } + else if (!strcmp(argv[i], "--stop-errors")) + { + if (++i >= argc) + { + cerr << "Missing argument to --stop-errors" << endl; + return false; + } + setEnvironment("OCLGRIND_STOP_ERRORS", argv[i]); + } else if (!strcmp(argv[i], "--uniform-writes")) { setEnvironment("OCLGRIND_UNIFORM_WRITES", "1"); @@ -174,6 +190,20 @@ static bool parseArguments(int argc, char *argv[]) } } + // Set diagnostic options + if(diagnosticOptions.size()) + { + std::stringstream options; + options << diagnosticOptions.front(); + + for(int i = 1; i < diagnosticOptions.size(); ++i) + { + options << " " << diagnosticOptions[i]; + } + + setEnvironment("OCLGRIND_DIAGNOSTIC_OPTIONS", options.str().c_str()); + } + if (simfile == NULL) { printUsage(); @@ -210,6 +240,10 @@ static void printUsage() "Redirect log/error messages to a file" << endl << " --max-errors NUM " "Limit the number of error/warning messages" << endl + << " -Wall " + "Enable all error/warning messages" << endl + << " -W[no-]MSG_GROUP " + "Enable/disable specific message group" << endl << " --num-threads NUM " "Set the number of worker threads to use" << endl << " --pch-dir DIR " @@ -218,6 +252,8 @@ static void printUsage() "Load colon separated list of plugin libraries" << endl << " -q --quick " "Only run first and last work-group" << endl + << " --stop-errors NUM " + "Abort the execution after NUM error/warning messages" << endl << " --uniform-writes " "Don't suppress uniform write-write data-races" << endl << " --uninitialized " diff --git a/src/plugins/InteractiveDebugger.cpp b/src/plugins/InteractiveDebugger.cpp old mode 100644 new mode 100755 index 012e0099..7bed0dac --- a/src/plugins/InteractiveDebugger.cpp +++ b/src/plugins/InteractiveDebugger.cpp @@ -200,7 +200,7 @@ void InteractiveDebugger::kernelEnd(const KernelInvocation *kernelInvocation) void InteractiveDebugger::log(MessageType type, const char *message) { - if (type == ERROR) + if (getMessageBaseType(type) == OCLGRIND_ERROR) m_forceBreak = true; } diff --git a/src/plugins/Logger.cpp b/src/plugins/Logger.cpp old mode 100644 new mode 100755 index acc88966..6cbc1376 --- a/src/plugins/Logger.cpp +++ b/src/plugins/Logger.cpp @@ -17,6 +17,7 @@ using namespace oclgrind; using namespace std; #define DEFAULT_MAX_ERRORS 1000 +#define DEFAULT_STOP_ERRORS -1 unsigned Logger::m_numErrors = 0; @@ -37,6 +38,17 @@ Logger::Logger(const Context *context) m_log = &cerr; } } + m_stopErrors = DEFAULT_STOP_ERRORS; + const char *stopErrors = getenv("OCLGRIND_STOP_ERRORS"); + if (stopErrors) + { + char *next; + m_stopErrors = strtoul(stopErrors, &next, 10); + if (strlen(next)) + { + cerr << "Oclgrind: Invalid value for OCLGRIND_STOP_ERRORS" << endl; + } + } m_maxErrors = DEFAULT_MAX_ERRORS; const char *maxErrors = getenv("OCLGRIND_MAX_ERRORS"); @@ -49,6 +61,13 @@ Logger::Logger(const Context *context) cerr << "Oclgrind: Invalid value for OCLGRIND_MAX_ERRORS" << endl; } } + + m_diagnosticOptions = std::map(); + char *diagnosticOptions = getenv("OCLGRIND_DIAGNOSTIC_OPTIONS"); + if (diagnosticOptions) + { + parseDiagnosticOptions(diagnosticOptions); + } } Logger::~Logger() @@ -65,9 +84,15 @@ void Logger::log(MessageType type, const char *message) lock_guard lock(logMutex); // Limit number of errors/warning printed - if (type == ERROR || type == WARNING) + if (!hasDiagnosticOption(type) && type != OCLGRIND_ERROR_FATAL) { - if (m_numErrors == m_maxErrors) + return; + } + + MessageType baseType = getMessageBaseType(type); + if (baseType == OCLGRIND_ERROR || baseType == OCLGRIND_WARNING) + { + if (m_numErrors == m_maxErrors && hasDiagnosticOption(OCLGRIND_INFO)) { *m_log << endl << "Oclgrind: " << m_numErrors << " errors generated - suppressing further errors" @@ -78,4 +103,148 @@ void Logger::log(MessageType type, const char *message) } *m_log << endl << message << endl; + + if (m_numErrors == m_stopErrors) + { + *m_log << endl << "Oclgrind: " + << "Error limit reached - aborting execution" + << endl << endl; + exit(1); + } +} + +bool Logger::hasDiagnosticOption(MessageType optType) +{ + return m_diagnosticOptions[optType]; +} + +void Logger::enableDiagnosticOption(MessageType optType, bool status) +{ + m_diagnosticOptions[optType] = status; +} + +void Logger::enableAllDiagnostics() +{ + // Turn on generic groups + enableDiagnosticOption(OCLGRIND_INFO); + enableDiagnosticOption(OCLGRIND_DEBUG); + enableDiagnosticOption(OCLGRIND_WARNING); + enableDiagnosticOption(OCLGRIND_ERROR); + // Turn on specific groups + enableDiagnosticOption(OCLGRIND_WARNING_UNINITIALIZED); + enableDiagnosticOption(OCLGRIND_ERROR_DIVERGENCE); + enableDiagnosticOption(OCLGRIND_ERROR_INVALID_ACCESS); + enableDiagnosticOption(OCLGRIND_ERROR_DATA_RACE); + enableDiagnosticOption(OCLGRIND_ERROR_UNALIGNED); + enableDiagnosticOption(OCLGRIND_ERROR_ARRAY_BOUNDS); +} + +void Logger::logBadDiagnosticOption(const char* opt, bool isInvalid) +{ + std::stringstream msg; + msg << (isInvalid ? "Invalid" : "Unknown") + << " diagnostic option '" << opt << "'."; + log(OCLGRIND_WARNING, msg.str().c_str()); +} + +bool Logger::parseDiagnosticOptions(char *options) +{ + if (options == NULL) + { + return true; + } + + std::vector invalidOptions; + std::vector unknownOptions; + + for (char *opt = strtok(options, " "); opt; opt = strtok(NULL, " ")) + { + bool isPositive = strncmp(opt, "-Wno-", 5); + char *opt_type = NULL; + + if (isPositive) + { + if (strlen(opt) <= 2) + { + invalidOptions.push_back(opt); + continue; + } + else + { + opt_type = opt + 2; + } + } + else + { + if (strlen(opt) <= 5) + { + invalidOptions.push_back(opt); + continue; + } + else + { + opt_type = opt + 5; + } + } + + assert(opt_type); + + if (!strcmp(opt_type, "all") && isPositive) + { + enableAllDiagnostics(); + } + else if (!strcmp(opt_type, "generic")) + { + enableDiagnosticOption(OCLGRIND_WARNING, isPositive); + enableDiagnosticOption(OCLGRIND_ERROR, isPositive); + } + else if (!strcmp(opt_type, "info")) + { + enableDiagnosticOption(OCLGRIND_INFO, isPositive); + } + else if (!strcmp(opt_type, "debug")) + { + enableDiagnosticOption(OCLGRIND_DEBUG, isPositive); + } + else if (!strcmp(opt_type, "uninitialized")) + { + enableDiagnosticOption(OCLGRIND_WARNING_UNINITIALIZED, isPositive); + } + else if (!strcmp(opt_type, "divergence")) + { + enableDiagnosticOption(OCLGRIND_ERROR_DIVERGENCE, isPositive); + } + else if (!strcmp(opt_type, "invalid-access")) + { + enableDiagnosticOption(OCLGRIND_ERROR_INVALID_ACCESS, isPositive); + } + else if (!strcmp(opt_type, "data-race")) + { + enableDiagnosticOption(OCLGRIND_ERROR_DATA_RACE, isPositive); + } + else if (!strcmp(opt_type, "unaligned")) + { + enableDiagnosticOption(OCLGRIND_ERROR_UNALIGNED, isPositive); + } + else if (!strcmp(opt_type, "array-bounds")) + { + enableDiagnosticOption(OCLGRIND_ERROR_ARRAY_BOUNDS, isPositive); + } + else + { + unknownOptions.push_back(opt); + } + } + + for (int i = 0; i < invalidOptions.size(); ++i) + { + logBadDiagnosticOption(invalidOptions[i], true); + } + + for (int i = 0; i < unknownOptions.size(); ++i) + { + logBadDiagnosticOption(unknownOptions[i]); + } + + return (!invalidOptions.size() && !unknownOptions.size()); } diff --git a/src/plugins/Logger.h b/src/plugins/Logger.h index 62bbcc82..07c283ce 100644 --- a/src/plugins/Logger.h +++ b/src/plugins/Logger.h @@ -22,6 +22,14 @@ namespace oclgrind std::ostream *m_log; unsigned m_maxErrors; + int m_stopErrors; + std::map m_diagnosticOptions; static unsigned m_numErrors; - }; + + bool hasDiagnosticOption(MessageType optType); + void enableDiagnosticOption(MessageType optType, bool status = true); + void enableAllDiagnostics(); + void logBadDiagnosticOption(const char* opt, bool isInvalid = false); + bool parseDiagnosticOptions(char *options); +}; } diff --git a/src/plugins/MemCheck.cpp b/src/plugins/MemCheck.cpp old mode 100644 new mode 100755 index a42c75b1..68a75f6b --- a/src/plugins/MemCheck.cpp +++ b/src/plugins/MemCheck.cpp @@ -173,7 +173,7 @@ void MemCheck::checkLoad(const Memory *memory, if (memory->getBuffer(address)->flags & CL_MEM_WRITE_ONLY) { - m_context->logError("Invalid read from write-only buffer"); + m_context->logError("Invalid read from write-only buffer", OCLGRIND_ERROR_INVALID_ACCESS); } // Check if memory location is currently mapped for writing @@ -201,7 +201,7 @@ void MemCheck::checkStore(const Memory *memory, if (memory->getBuffer(address)->flags & CL_MEM_READ_ONLY) { - m_context->logError("Invalid write to read-only buffer"); + m_context->logError("Invalid write to read-only buffer", OCLGRIND_ERROR_INVALID_ACCESS); } // Check if memory location is currently mapped @@ -220,7 +220,7 @@ void MemCheck::checkStore(const Memory *memory, void MemCheck::logInvalidAccess(bool read, unsigned addrSpace, size_t address, size_t size) const { - Context::Message msg(ERROR, m_context); + Context::Message msg(OCLGRIND_ERROR_INVALID_ACCESS, m_context); msg << "Invalid " << (read ? "read" : "write") << " of size " << size << " at " << getAddressSpaceName(addrSpace) diff --git a/src/plugins/RaceDetector.cpp b/src/plugins/RaceDetector.cpp old mode 100644 new mode 100755 index 72dfc13e..dd6a85d3 --- a/src/plugins/RaceDetector.cpp +++ b/src/plugins/RaceDetector.cpp @@ -306,7 +306,7 @@ void RaceDetector::logRace(const Race& race) const else raceType = "Write-write"; - Context::Message msg(ERROR, m_context); + Context::Message msg(OCLGRIND_ERROR_DATA_RACE, m_context); msg << raceType << " data race at " << getAddressSpaceName(race.addrspace) << " memory address 0x" << hex << race.address << endl diff --git a/src/plugins/Uninitialized.cpp b/src/plugins/Uninitialized.cpp old mode 100644 new mode 100755 index 766bd41f..e3cc9ea9 --- a/src/plugins/Uninitialized.cpp +++ b/src/plugins/Uninitialized.cpp @@ -1845,7 +1845,7 @@ void Uninitialized::loadShadowMemory(unsigned addrSpace, size_t address, TypedVa void Uninitialized::logUninitializedAddress(unsigned int addrSpace, size_t address, bool write) const { - Context::Message msg(WARNING, m_context); + Context::Message msg(OCLGRIND_WARNING_UNINITIALIZED, m_context); msg << "Uninitialized address used to " << (write ? "write to " : "read from ") << getAddressSpaceName(addrSpace) << " memory address 0x" << hex << address << endl @@ -1858,7 +1858,7 @@ void Uninitialized::logUninitializedAddress(unsigned int addrSpace, size_t addre void Uninitialized::logUninitializedCF() const { - Context::Message msg(WARNING, m_context); + Context::Message msg(OCLGRIND_WARNING_UNINITIALIZED, m_context); msg << "Controlflow depends on uninitialized value" << endl << msg.INDENT << "Kernel: " << msg.CURRENT_KERNEL << endl @@ -1869,7 +1869,7 @@ void Uninitialized::logUninitializedCF() const void Uninitialized::logUninitializedIndex() const { - Context::Message msg(WARNING, m_context); + Context::Message msg(OCLGRIND_WARNING_UNINITIALIZED, m_context); msg << "Instruction depends on an uninitialized index value" << endl << msg.INDENT << "Kernel: " << msg.CURRENT_KERNEL << endl @@ -1880,7 +1880,7 @@ void Uninitialized::logUninitializedIndex() const void Uninitialized::logUninitializedWrite(unsigned int addrSpace, size_t address) const { - Context::Message msg(WARNING, m_context); + Context::Message msg(OCLGRIND_WARNING_UNINITIALIZED, m_context); msg << "Uninitialized value written to " << getAddressSpaceName(addrSpace) << " memory address 0x" << hex << address << endl diff --git a/src/runtime/oclgrind b/src/runtime/oclgrind index 3c36f785..8e715569 100755 --- a/src/runtime/oclgrind +++ b/src/runtime/oclgrind @@ -34,6 +34,10 @@ function usage echo "Redirect log/error messages to a file" echo -n " --max-errors NUM " echo "Limit the number of error/warning messages" + echo -n " -Wall " + echo "Enable all error/warning messages" + echo -n " -W[no-]MSG_GROUP " + echo "Enable/disable specific message group" echo -n " --num-threads NUM " echo "Set the number of worker threads to use" echo -n " --pch-dir DIR " @@ -42,6 +46,8 @@ function usage echo "Load colon separated list of plugin libraries" echo -n " -q --quick " echo "Only run first and last work-group" + echo -n " --stop-errors NUM " + echo "Abort the execution after NUM error/warning messages" echo -n " --uniform-writes " echo "Don't suppress uniform write-write data-races" echo -n " --uninitialized " @@ -54,10 +60,16 @@ function usage echo } +# Collect all diagnostic options before writing them to environment +diagnosticOptions=() + # Parse arguments while [ $# -gt 0 -a "${1:0:1}" == "-" ] do - if [ "$1" == "--build-options" ] + if [ "${1:1:1}" == "W" ] + then + diagnosticOptions+=("$1") + elif [ "$1" == "--build-options" ] then shift export OCLGRIND_BUILD_OPTIONS="$1" @@ -106,6 +118,10 @@ do elif [ "$1" == "-q" -o "$1" == "--quick" ] then export OCLGRIND_QUICK=1 + elif [ "$1" == "--stop-errors" ] + then + shift + export OCLGRIND_STOP_ERRORS="$1" elif [ "$1" == "--uniform-writes" ] then export OCLGRIND_UNIFORM_WRITES=1 @@ -130,6 +146,9 @@ do shift done +# Set diagnostic options +export OCLGRIND_DIAGNOSTIC_OPTIONS="${diagnosticOptions[@]}" + # Ensure target command supplied if [ $# -lt 1 ] then diff --git a/tests/run_test.py b/tests/run_test.py index 63d17b35..3b631720 100644 --- a/tests/run_test.py +++ b/tests/run_test.py @@ -44,6 +44,9 @@ os.environ["OCLGRIND_DATA_RACES"] = "1" os.environ["OCLGRIND_UNINITIALIZED"] = "1" +# Enable all diagnostic output +os.environ["OCLGRIND_DIAGNOSTIC_OPTIONS"] = "-Wall" + def fail(ret=1): print 'FAILED' sys.exit(ret)