summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Foley <tfoley@nvidia.com>2017-08-31 10:41:03 -0700
committerTim Foley <tfoley@nvidia.com>2017-08-31 10:41:03 -0700
commit60ed10520dd9af285e7d865445427caedc7e1ec6 (patch)
treeb7c3c0003d6d8d67f3f04f136af083deaa5e591b
parent227f9f5a9d8ac0d88079b6175b3f31c8f05fabd0 (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.h5
-rw-r--r--source/slang/lower.cpp32
-rw-r--r--source/slang/slang.cpp18
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