From 3f48e1c0d84bf4909954154ad147559656e87516 Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Wed, 19 Jul 2017 09:36:35 -0700 Subject: Try to improve handling of failures during compilation The change is mostly about trying to make sure the compiler "fails safe" when it encounters an internal assumption that isn't met. Most internal errors will now throw exceptions (yes, exceptions are evil, but this will work for now), and these get caught in `spCompile` so that they don't propagate to the user (they just see a message that compilation aborted due to an internal error). Subsequent changes are going to need to work on diagnosing as many of these situations as possible, so that users can at least know what construct in their code was unexpected or unhandled by the compiler. --- source/slang/lower.cpp | 77 +++++++++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 36 deletions(-) (limited to 'source/slang/lower.cpp') diff --git a/source/slang/lower.cpp b/source/slang/lower.cpp index c61003bc6..52b865ba3 100644 --- a/source/slang/lower.cpp +++ b/source/slang/lower.cpp @@ -186,7 +186,7 @@ class TupleVarDecl : public VarDeclBase public: virtual void accept(IDeclVisitor *, void *) override { - throw "unexpected"; + SLANG_UNEXPECTED("tuples should not appear in lowered code"); } TupleTypeModifier* tupleType; @@ -201,7 +201,7 @@ class TupleExpr : public ExpressionSyntaxNode public: virtual void accept(IExprVisitor *, void *) override { - throw "unexpected"; + SLANG_UNEXPECTED("tuples should not appear in lowered code"); } struct Element @@ -225,7 +225,7 @@ class VaryingTupleVarDecl : public VarDeclBase public: virtual void accept(IDeclVisitor *, void *) override { - throw "unexpected"; + SLANG_UNEXPECTED("tuples should not appear in lowered code"); } }; @@ -236,7 +236,7 @@ class VaryingTupleExpr : public ExpressionSyntaxNode public: virtual void accept(IExprVisitor *, void *) override { - throw "unexpected"; + SLANG_UNEXPECTED("tuples should not appear in lowered code"); } struct Element @@ -667,10 +667,10 @@ struct LoweringVisitor for (auto dd : decl->tupleDecls) { auto tupleVarMod = dd->FindModifier(); - assert(tupleVarMod); + SLANG_RELEASE_ASSERT(tupleVarMod); auto tupleFieldMod = tupleVarMod->tupleField; - assert(tupleFieldMod); - assert(tupleFieldMod->decl); + SLANG_RELEASE_ASSERT(tupleFieldMod); + SLANG_RELEASE_ASSERT(tupleFieldMod->decl); TupleExpr::Element elem; elem.tupleFieldDeclRef = makeDeclRef(tupleFieldMod->decl); @@ -799,7 +799,7 @@ struct LoweringVisitor if (leftTuple->primaryExpr) { - assert(rightTuple->primaryExpr); + SLANG_RELEASE_ASSERT(rightTuple->primaryExpr); resultTuple->primaryExpr = createAssignExpr( leftTuple->primaryExpr, @@ -807,7 +807,7 @@ struct LoweringVisitor } auto elementCount = leftTuple->tupleElements.Count(); - assert(elementCount == rightTuple->tupleElements.Count()); + SLANG_RELEASE_ASSERT(elementCount == rightTuple->tupleElements.Count()); for (UInt ee = 0; ee < elementCount; ++ee) { auto leftElement = leftTuple->tupleElements[ee]; @@ -827,7 +827,7 @@ struct LoweringVisitor } else { - assert(!leftTuple && !rightTuple); + SLANG_RELEASE_ASSERT(!leftTuple && !rightTuple); } auto leftVaryingTuple = leftExpr.As(); @@ -838,10 +838,10 @@ struct LoweringVisitor resultTuple->Type.type = lowerType(leftExpr->Type.type); resultTuple->Position = leftExpr->Position; - assert(resultTuple->Type.type); + SLANG_RELEASE_ASSERT(resultTuple->Type.type); UInt elementCount = leftVaryingTuple->elements.Count(); - assert(elementCount == rightVaryingTuple->elements.Count()); + SLANG_RELEASE_ASSERT(elementCount == rightVaryingTuple->elements.Count()); for (UInt ee = 0; ee < elementCount; ++ee) { @@ -1027,7 +1027,7 @@ struct LoweringVisitor auto loweredExpr = new VaryingTupleExpr(); loweredExpr->Type.type = getSubscripResultType(baseExpr->Type.type); - assert(loweredExpr->Type.type); + SLANG_RELEASE_ASSERT(loweredExpr->Type.type); for (auto elem : baseVaryingTuple->elements) { @@ -1100,7 +1100,7 @@ struct LoweringVisitor RefPtr resultExpr = new AggTypeCtorExpr(); resultExpr->Type = varyingTupleExpr->Type; resultExpr->base.type = varyingTupleExpr->Type.type; - assert(resultExpr->Type.type); + SLANG_RELEASE_ASSERT(resultExpr->Type.type); for (auto elem : varyingTupleExpr->elements) { @@ -1214,6 +1214,11 @@ struct LoweringVisitor return loweredExpr; } + DiagnosticSink* getSink() + { + return &shared->compileRequest->mSink; + } + RefPtr visitMemberExpressionSyntaxNode( MemberExpressionSyntaxNode* expr) { @@ -1244,8 +1249,8 @@ struct LoweringVisitor return tupleFieldExpr; auto tupleFieldTupleExpr = tupleFieldExpr.As(); - assert(tupleFieldTupleExpr); - assert(!tupleFieldTupleExpr->primaryExpr); + SLANG_RELEASE_ASSERT(tupleFieldTupleExpr); + SLANG_RELEASE_ASSERT(!tupleFieldTupleExpr->primaryExpr); RefPtr loweredPrimaryExpr = new MemberExpressionSyntaxNode(); @@ -1274,11 +1279,11 @@ struct LoweringVisitor } } - assert(!"unexpected"); + SLANG_DIAGNOSE_UNEXPECTED(getSink(), expr, "failed to find tuple field during lowering"); } // Default handling: - assert(!dynamic_cast(loweredDeclRef.getDecl())); + SLANG_RELEASE_ASSERT(!dynamic_cast(loweredDeclRef.getDecl())); RefPtr loweredExpr = new MemberExpressionSyntaxNode(); lowerExprCommon(loweredExpr, expr); @@ -1344,7 +1349,7 @@ struct LoweringVisitor return state->loweredStmt; } - assert(!"unexepcted"); + SLANG_DIAGNOSE_UNEXPECTED(getSink(), originalStmt, "failed to find outer statement during lowering"); return nullptr; } @@ -1755,7 +1760,7 @@ struct LoweringVisitor if (auto litVal = dynamic_cast(val)) return val; - throw 99; + SLANG_UNEXPECTED("unhandled value kind"); } RefPtr translateSubstitutions( @@ -1871,7 +1876,7 @@ struct LoweringVisitor // translated, which the user will maintain via pua/pop. // - assert(parentDecl); + SLANG_RELEASE_ASSERT(parentDecl); addMember(parentDecl, decl); } @@ -2337,7 +2342,7 @@ struct LoweringVisitor continue; // TODO: need to extract the initializer for this field - assert(!info.initExpr); + SLANG_RELEASE_ASSERT(!info.initExpr); RefPtr fieldInitExpr; String fieldName = info.name + "_" + dd.GetName(); @@ -2346,7 +2351,7 @@ struct LoweringVisitor Decl* originalFieldDecl; shared->mapLoweredDeclToOriginal.TryGetValue(dd, originalFieldDecl); - assert(originalFieldDecl); + SLANG_RELEASE_ASSERT(originalFieldDecl); RefPtr fieldLayout; if(info.tupleTypeLayout) @@ -2477,7 +2482,7 @@ struct LoweringVisitor RefPtr tupleTypeLayout) { // Not handling initializers just yet... - assert(!initExpr); + SLANG_RELEASE_ASSERT(!initExpr); // We'll need a placeholder declaration to wrap the whole thing up: RefPtr tupleDecl = new TupleVarDecl(); @@ -2745,7 +2750,7 @@ struct LoweringVisitor // declarations. // We can't easily support `in out` declarations with this approach - assert(!(inRes && outRes)); + SLANG_RELEASE_ASSERT(!(inRes && outRes)); RefPtr loweredExpr; if (inRes) @@ -2764,7 +2769,7 @@ struct LoweringVisitor VaryingParameterDirection::Output); } - assert(loweredExpr); + SLANG_RELEASE_ASSERT(loweredExpr); auto loweredDecl = createVaryingTupleVarDecl( decl, loweredExpr); @@ -2987,7 +2992,7 @@ struct LoweringVisitor RefPtr globalVarExpr; // Handle system-value inputs/outputs - assert(varLayout); + SLANG_RELEASE_ASSERT(varLayout); auto systemValueSemantic = varLayout->systemValueSemantic; if (systemValueSemantic.Length() != 0) { @@ -3124,7 +3129,7 @@ struct LoweringVisitor } else { - assert(!"unhandled"); + getSink()->diagnose(info.varChain->varDecl, Diagnostics::unknownSystemValueSemantic, systemValueSemantic); } } @@ -3202,7 +3207,7 @@ struct LoweringVisitor RefPtr varType, RefPtr varLayout) { - assert(varLayout); + SLANG_RELEASE_ASSERT(varLayout); if (auto basicType = varType->As()) { @@ -3252,7 +3257,7 @@ struct LoweringVisitor RefPtr tupleExpr = new VaryingTupleExpr(); tupleExpr->Type.type = varType; - assert(tupleExpr->Type.type); + SLANG_RELEASE_ASSERT(tupleExpr->Type.type); for (auto fieldDeclRef : getMembersOfType(aggTypeDeclRef)) { @@ -3271,14 +3276,14 @@ struct LoweringVisitor // Need to find the layout for the given field... Decl* originalFieldDecl = nullptr; shared->mapLoweredDeclToOriginal.TryGetValue(fieldDeclRef.getDecl(), originalFieldDecl); - assert(originalFieldDecl); + SLANG_RELEASE_ASSERT(originalFieldDecl); auto structTypeLayout = varLayout->typeLayout.As(); - assert(structTypeLayout); + SLANG_RELEASE_EXPECT(structTypeLayout, "expected a structure type layout"); RefPtr fieldLayout; structTypeLayout->mapVarToLayout.TryGetValue(originalFieldDecl, fieldLayout); - assert(fieldLayout); + SLANG_RELEASE_ASSERT(fieldLayout); auto loweredFieldExpr = lowerShaderParameterToGLSLGLobalsRec( fieldInfo, @@ -3414,7 +3419,7 @@ struct LoweringVisitor { RefPtr paramLayout; entryPointLayout->mapVarToLayout.TryGetValue(paramDecl.Ptr(), paramLayout); - assert(paramLayout); + SLANG_RELEASE_ASSERT(paramLayout); RefPtr localVarDecl = new Variable(); localVarDecl->Position = paramDecl->Position; @@ -3657,13 +3662,13 @@ static RefPtr getGlobalStructLayout( auto elementTypeStructLayout = elementTypeLayout.As(); // We expect all constant buffers to contain `struct` types for now - assert(elementTypeStructLayout); + SLANG_RELEASE_ASSERT(elementTypeStructLayout); globalStructLayout = elementTypeStructLayout.Ptr(); } else { - assert(!"unexpected"); + SLANG_UNEXPECTED("unhandled type for global-scope parameter layout"); } return globalStructLayout; } -- cgit v1.2.3