summaryrefslogtreecommitdiffstats
path: root/source/core
diff options
context:
space:
mode:
authorTim Foley <tfoley@nvidia.com>2017-07-19 09:36:35 -0700
committerTim Foley <tfoley@nvidia.com>2017-07-19 18:15:37 -0700
commit3f48e1c0d84bf4909954154ad147559656e87516 (patch)
tree0b93a109d51e6565560ad785519a863386490e2a /source/core
parenta2b8b4c20632d79721052abd232fe2d1bdf2700d (diff)
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.
Diffstat (limited to 'source/core')
-rw-r--r--source/core/common.h29
-rw-r--r--source/core/exception.h16
-rw-r--r--source/core/slang-string.cpp8
-rw-r--r--source/core/slang-string.h4
-rw-r--r--source/core/smart-pointer.h5
5 files changed, 53 insertions, 9 deletions
diff --git a/source/core/common.h b/source/core/common.h
index 25e85dc66..f0f6902d1 100644
--- a/source/core/common.h
+++ b/source/core/common.h
@@ -34,6 +34,35 @@ namespace Slang
v0 = _Move(v1);
v1 = _Move(tmp);
}
+
+#ifdef _MSC_VER
+#define SLANG_RETURN_NEVER __declspec(noreturn)
+#else
+#efine SLANG_RETURN_NEVER /* empty */
+#endif
+
+ SLANG_RETURN_NEVER void signalUnexpectedError(char const* message);
}
+#define SLANG_UNEXPECTED(reason) \
+ Slang::signalUnexpectedError("unexpected: " reason)
+
+#define SLANG_UNIMPLEMENTED_X(what) \
+ Slang::signalUnexpectedError("unimplemented: " what)
+
+#define SLANG_UNREACHABLE(msg) \
+ Slang::signalUnexpectedError("unreachable code executed: " msg)
+
+#ifdef _DEBUG
+#define SLANG_EXPECT(VALUE, MSG) if(VALUE) {} else Slang::signalUnexpectedError("assertion failed: '" MSG "'")
+#define SLANG_ASSERT(VALUE) SLANG_EXPECT(VALUE, #VALUE)
+#else
+#define SLANG_EXPECT(VALUE, MSG) do {} while(0)
+#define SLANG_ASSERT(VALUE) do {} while(0)
+#endif
+
+#define SLANG_RELEASE_ASSERT(VALUE) if(VALUE) {} else Slang::signalUnexpectedError("assertion failed")
+#define SLANG_RELEASE_EXPECT(VALUE, WHAT) if(VALUE) {} else SLANG_UNEXPECTED(WHAT)
+
+
#endif
diff --git a/source/core/exception.h b/source/core/exception.h
index dc674de7f..aedb62add 100644
--- a/source/core/exception.h
+++ b/source/core/exception.h
@@ -111,12 +111,16 @@ namespace Slang
}
};
- #define SLANG_UNEXPECTED(reason) \
- throw Slang::Exception("unexpected: " reason)
-
- #define SLANG_UNIMPLEMENTED_X(what) \
- throw Slang::NotImplementedException("unimplemented: " what)
-
+ class InternalError : public Exception
+ {
+ public:
+ InternalError()
+ {}
+ InternalError(const String & message)
+ : Exception(message)
+ {
+ }
+ };
}
#endif \ No newline at end of file
diff --git a/source/core/slang-string.cpp b/source/core/slang-string.cpp
index 8938db595..459396f69 100644
--- a/source/core/slang-string.cpp
+++ b/source/core/slang-string.cpp
@@ -3,6 +3,14 @@
namespace Slang
{
+ // TODO: this belongs in a different file:
+
+ SLANG_RETURN_NEVER void signalUnexpectedError(char const* message)
+ {
+ throw InternalError(message);
+ }
+
+
// OSString
OSString::OSString()
diff --git a/source/core/slang-string.h b/source/core/slang-string.h
index 3c1b48e8c..552afe833 100644
--- a/source/core/slang-string.h
+++ b/source/core/slang-string.h
@@ -1,8 +1,10 @@
#ifndef FUNDAMENTAL_LIB_STRING_H
#define FUNDAMENTAL_LIB_STRING_H
+
#include <string.h>
#include <cstdlib>
#include <stdio.h>
+
#include "smart-pointer.h"
#include "common.h"
#include "hash.h"
@@ -80,7 +82,7 @@ namespace Slang
static StringRepresentation* createWithCapacityAndLength(UInt capacity, UInt length)
{
- assert(capacity >= length);
+ SLANG_ASSERT(capacity >= length);
void* allocation = operator new(sizeof(StringRepresentation) + capacity + 1);
StringRepresentation* obj = new(allocation) StringRepresentation();
obj->capacity = capacity;
diff --git a/source/core/smart-pointer.h b/source/core/smart-pointer.h
index fea149e06..87cb40d70 100644
--- a/source/core/smart-pointer.h
+++ b/source/core/smart-pointer.h
@@ -1,6 +1,7 @@
#ifndef FUNDAMENTAL_LIB_SMART_POINTER_H
#define FUNDAMENTAL_LIB_SMART_POINTER_H
+#include "common.h"
#include "type-traits.h"
#include <assert.h>
@@ -36,7 +37,7 @@ namespace Slang
void releaseReference()
{
- assert(referenceCount != 0);
+ SLANG_ASSERT(referenceCount != 0);
if(--referenceCount == 0)
{
delete this;
@@ -45,7 +46,7 @@ namespace Slang
bool isUniquelyReferenced()
{
- assert(referenceCount != 0);
+ SLANG_ASSERT(referenceCount != 0);
return referenceCount == 1;
}
};