From 5e604a6f39ef8e8086702d41113ea78856804c99 Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Fri, 11 May 2018 13:56:14 -0700 Subject: Cleanups around behavior when the compiler fails (#553) * Cleanups around behavior when the compiler fails * Add another case where we try to `noteInternalErrorLoc()` if an exception in thrown. This one is the in the logic for emitting an IR instruciton. This could be improved by adding another layer at the function level (as a catch-all for instructions with no location), but something is better than nothing. * Change a bunch of `assert()`s over to `SLANG_ASSERT()`s, so that we can theoretically take more control over them (e.g., make release builds with asserts enabled) * Some other small cleanups around the assertions we perform. In the survey I made, I didn't really see many obvious "smoking gun" cases where we could produce a significantly better error message for some of the unimplemented/unexpected paths, other than to actually implement the missing functionality. * fixup --- source/slang/emit.cpp | 53 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 17 deletions(-) (limited to 'source/slang/emit.cpp') diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index bf7fceb0e..edb5d5cb2 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -3453,11 +3453,11 @@ struct EmitVisitor for (UInt ee = 0; ee < elementCount; ++ee) { IRInst* irElementIndex = ii->getElementIndex(ee); - assert(irElementIndex->op == kIROp_IntLit); + SLANG_RELEASE_ASSERT(irElementIndex->op == kIROp_IntLit); IRConstant* irConst = (IRConstant*)irElementIndex; UInt elementIndex = (UInt)irConst->u.intVal; - assert(elementIndex < 4); + SLANG_RELEASE_ASSERT(elementIndex < 4); char const* kComponents[] = { "x", "y", "z", "w" }; emit(kComponents[elementIndex]); @@ -3513,6 +3513,25 @@ struct EmitVisitor EmitContext* ctx, IRInst* inst, IREmitMode mode) + { + try + { + emitIRInstImpl(ctx, inst, mode); + } + // Don't emit any context message for an explicit `AbortCompilationException` + // because it should only happen when an error is already emitted. + catch(AbortCompilationException&) { throw; } + catch(...) + { + ctx->shared->entryPoint->compileRequest->noteInternalErrorLoc(inst->sourceLoc); + throw; + } + } + + void emitIRInstImpl( + EmitContext* ctx, + IRInst* inst, + IREmitMode mode) { if (shouldFoldIRInstIntoUseSites(ctx, inst, mode)) { @@ -3584,11 +3603,11 @@ struct EmitVisitor for (UInt ee = 0; ee < elementCount; ++ee) { IRInst* irElementIndex = ii->getElementIndex(ee); - assert(irElementIndex->op == kIROp_IntLit); + SLANG_RELEASE_ASSERT(irElementIndex->op == kIROp_IntLit); IRConstant* irConst = (IRConstant*)irElementIndex; UInt elementIndex = (UInt)irConst->u.intVal; - assert(elementIndex < 4); + SLANG_RELEASE_ASSERT(elementIndex < 4); char const* kComponents[] = { "x", "y", "z", "w" }; emit(kComponents[elementIndex]); @@ -3609,11 +3628,11 @@ struct EmitVisitor for (UInt ee = 0; ee < elementCount; ++ee) { IRInst* irElementIndex = ii->getElementIndex(ee); - assert(irElementIndex->op == kIROp_IntLit); + SLANG_RELEASE_ASSERT(irElementIndex->op == kIROp_IntLit); IRConstant* irConst = (IRConstant*)irElementIndex; UInt elementIndex = (UInt)irConst->u.intVal; - assert(elementIndex < 4); + SLANG_RELEASE_ASSERT(elementIndex < 4); char const* kComponents[] = { "x", "y", "z", "w" }; emit(kComponents[elementIndex]); @@ -3717,7 +3736,7 @@ struct EmitVisitor if (argIndex >= argCount) { - assert(!"not enough arguments for branch"); + SLANG_UNEXPECTED("not enough arguments for branch"); break; } @@ -3822,7 +3841,7 @@ struct EmitVisitor // Start by emitting the non-terminator instructions in the block. auto terminator = block->getLastInst(); - assert(as(terminator)); + SLANG_ASSERT(as(terminator)); for (auto inst = block->getFirstInst(); inst != terminator; inst = inst->getNextInst()) { emitIRInst(ctx, inst, IREmitMode::Default); @@ -5003,7 +5022,7 @@ struct EmitVisitor Emit(ctx->shared->uniqueIDCounter++); auto varLayout = getVarLayout(ctx, varDecl); - assert(varLayout); + SLANG_RELEASE_ASSERT(varLayout); EmitVarChain blockChain(varLayout); @@ -5051,7 +5070,7 @@ struct EmitVisitor emit(getIRName(varDecl)); auto varLayout = getVarLayout(ctx, varDecl); - assert(varLayout); + SLANG_RELEASE_ASSERT(varLayout); EmitVarChain blockChain(varLayout); @@ -5077,7 +5096,7 @@ struct EmitVisitor if(auto structType = as(elementType)) { auto structTypeLayout = typeLayout.As(); - assert(structTypeLayout); + SLANG_RELEASE_ASSERT(structTypeLayout); UInt fieldIndex = 0; for(auto ff : structType->getFields()) @@ -5133,7 +5152,7 @@ struct EmitVisitor IRParameterBlockType* type) { auto varLayout = getVarLayout(ctx, varDecl); - assert(varLayout); + SLANG_RELEASE_ASSERT(varLayout); EmitVarChain blockChain(varLayout); @@ -5180,7 +5199,7 @@ struct EmitVisitor } auto varLayout = getVarLayout(ctx, varDecl); - assert(varLayout); + SLANG_RELEASE_ASSERT(varLayout); EmitVarChain blockChain(varLayout); @@ -5218,7 +5237,7 @@ struct EmitVisitor if(auto structType = as(elementType)) { auto structTypeLayout = typeLayout.As(); - assert(structTypeLayout); + SLANG_RELEASE_ASSERT(structTypeLayout); UInt fieldIndex = 0; for(auto ff : structType->getFields()) @@ -5501,13 +5520,13 @@ struct EmitVisitor { // We expect to see only a single block auto block = valDecl->getFirstBlock(); - assert(block); - assert(!block->getNextBlock()); + SLANG_RELEASE_ASSERT(block); + SLANG_RELEASE_ASSERT(!block->getNextBlock()); // We expect the terminator to be a `return` // instruction with a value. auto returnInst = (IRReturnVal*) block->getLastInst(); - assert(returnInst->op == kIROp_ReturnVal); + SLANG_RELEASE_ASSERT(returnInst->op == kIROp_ReturnVal); // Now we want to emit the expression form of // the value being returned, and force any -- cgit v1.2.3