diff options
| author | Tim Foley <tfoley@nvidia.com> | 2017-08-31 10:41:03 -0700 |
|---|---|---|
| committer | Tim Foley <tfoley@nvidia.com> | 2017-08-31 10:41:03 -0700 |
| commit | 60ed10520dd9af285e7d865445427caedc7e1ec6 (patch) | |
| tree | b7c3c0003d6d8d67f3f04f136af083deaa5e591b | |
| parent | 227f9f5a9d8ac0d88079b6175b3f31c8f05fabd0 (diff) | |
Fix some issues around cloned modifiers.
The root of the problem here is that:
- We do a shallow copy of modifiers when "lowering" declarations/statements, by just copying over the head pointer of the linked list of modifiers
- During lowering we sometimes add additional modifiers (only used during lowering), and these can thus accidentally get added to the end of the list of modifiers for the original declaration (rather than just the lowered decl)
- If the same declaration is used by multiple entry points to be output, then a modifier added by the first entry point (which could reference entry-point-specific storage) will be earlier in the modifier list and might be picked up by a later entry point, so that we dereference already released memory
The simple fix for right now is the use the support for a "shared" modifier node to ensure that each lowered declaration/statement gets a unique modifier list.
A better long-term fix is:
1. Don't use modifiers to store general side-band information, and instead use proper lookup tables that own their contents.
2. Don't use a linked list to store modifiers (this was done to make splicing easy, but now we have a whole class of bugs related to bad splices), and be willing to clone them as needed.
| -rw-r--r-- | source/core/smart-pointer.h | 5 | ||||
| -rw-r--r-- | source/slang/lower.cpp | 32 | ||||
| -rw-r--r-- | source/slang/slang.cpp | 18 |
3 files changed, 50 insertions, 5 deletions
diff --git a/source/core/smart-pointer.h b/source/core/smart-pointer.h index 87cb40d70..3e64eac96 100644 --- a/source/core/smart-pointer.h +++ b/source/core/smart-pointer.h @@ -49,6 +49,11 @@ namespace Slang SLANG_ASSERT(referenceCount != 0); return referenceCount == 1; } + + UInt debugGetReferenceCount() + { + return referenceCount; + } }; inline void addReference(RefObject* obj) diff --git a/source/slang/lower.cpp b/source/slang/lower.cpp index a1b6dcf17..7a487d29f 100644 --- a/source/slang/lower.cpp +++ b/source/slang/lower.cpp @@ -5,6 +5,19 @@ #include "type-layout.h" #include "visitor.h" +// DEBUGGING +#if 0 +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#define NOMINMAX +#include <Windows.h> +#undef WIN32_LEAN_AND_MEAN +#undef NOMINMAX +#endif +#endif + + + namespace Slang { @@ -2166,12 +2179,22 @@ struct LoweringVisitor DeclVisitor::dispatch(stmt->decl); } + Modifiers shallowCloneModifiers(Modifiers const& oldModifiers) + { + RefPtr<SharedModifiers> shared = new SharedModifiers(); + shared->next = oldModifiers.first; + + Modifiers newModifiers; + newModifiers.first = shared; + return newModifiers; + } + void lowerStmtFields( Stmt* loweredStmt, Stmt* originalStmt) { loweredStmt->loc = originalStmt->loc; - loweredStmt->modifiers = originalStmt->modifiers; + loweredStmt->modifiers = shallowCloneModifiers(originalStmt->modifiers); } void lowerScopeStmtFields( @@ -2367,7 +2390,7 @@ struct LoweringVisitor void lowerStmtCommon(Stmt* loweredStmt, Stmt* stmt) { - loweredStmt->modifiers = stmt->modifiers; + loweredStmt->modifiers = shallowCloneModifiers(stmt->modifiers); } void assign( @@ -2665,7 +2688,7 @@ struct LoweringVisitor // HACK: just doing a shallow copy of modifiers, which will // suffice for most of them, but we need to do something // better soon. - loweredDecl->modifiers = decl->modifiers; + loweredDecl->modifiers = shallowCloneModifiers(decl->modifiers); // deal with layout stuff @@ -2964,7 +2987,6 @@ struct LoweringVisitor loweredDecl); } - return LoweredDecl(loweredDecl); } @@ -3209,7 +3231,7 @@ struct LoweringVisitor primaryVarDecl->nameAndLoc.name = getName(name); primaryVarDecl->type.type = tupleType; - primaryVarDecl->modifiers = originalVarDecl->modifiers; + primaryVarDecl->modifiers = shallowCloneModifiers(originalVarDecl->modifiers); tupleDecl->primaryDecl = primaryVarDecl; diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index 293b6bf9e..65abbb3f2 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -859,6 +859,16 @@ SLANG_API int spCompile( { auto req = REQ(request); +#if 1 + // By default we'd like to catch as many internal errors as possible, + // and report them to the user nicely (rather than just crash their + // application). Internally Slang currently uses exceptions for this. + // + // TODO: Consider using `setjmp()`-style escape so that we can work + // with applications that disable exceptions. + // + // TODO: Consider supporting Windows "Structured Exception Handling" + // so that we can also recover from a wider class of crashes. try { int anyErrors = req->executeActions(); @@ -869,6 +879,14 @@ SLANG_API int spCompile( req->mSink.diagnose(Slang::SourceLoc(), Slang::Diagnostics::compilationAborted); return 1; } +#else + // When debugging, we probably don't want to filter out any errors, since + // we are probably trying to root-cause and *fix* those errors. + { + int anyErrors = req->executeActions(); + return anyErrors; + } +#endif } SLANG_API int |
