CXX := clang++
CXXFLAGS := -g -std=c++11
+ifeq ($(OPTIMIZED),1)
+ CXXFLAGS += -O2
+endif
+
FILES := test.cc zcpointer.cc
+DEPS := $(FILES) zcpointer.h Makefile
+
all: test-zc test-tr
test: test-zc test-tr
./test-zc
./test-tr
-test-zc: $(FILES) zcpointer.h
+test-zc: $(DEPS)
$(CXX) $(CXXFLAGS) $(FILES) -o $@
-test-tr: $(FILES) zcpointer.h
+test-tr: $(DEPS)
$(CXX) -DZCPOINTER_TRACK_REFS=1 $(CXXFLAGS) $(FILES) -o $@
clean:
// limitations under the License.
#include <iostream>
+#include <stdexcept>
#include <vector>
#include "zcpointer.h"
void DoThing() {}
};
-#define EXPECT(expr) do { if (!(expr)) { throw std::logic_error(#expr); } } while(0)
+class TestFailure : public std::logic_error {
+ public:
+ using std::logic_error::logic_error;
+};
+
+#define STRING(x) QUOTE(x)
+#define QUOTE(x) #x
+#define AT_FILE_LINE " @ " __FILE__ ":" STRING(__LINE__)
+
+#define EXPECT(expr) do { if (!(expr)) { throw TestFailure(#expr AT_FILE_LINE); } } while(0)
#if defined(ZCPOINTER_TRACK_REFS) && ZCPOINTER_TRACK_REFS
#define EXPECT_UAF(expr) do { \
try { \
(expr); \
- throw std::logic_error("Expected use-after-free: " #expr); \
+ throw TestFailure("Expected use-after-free: " #expr AT_FILE_LINE); \
} catch (zc::UseAfterFreeError) {} \
} while(0)
#define EXPECT_UAF(expr) do { \
std::cout << ">>> ZCPOINTER_TRACK_REFS not enabled, cannot catch UAF" << std::endl; \
- (expr); \
+ try { \
+ (expr); \
+ } catch (std::logic_error& e) { \
+ std::cout << ">>> Caught error: " << typeid(e).name() << ": " << e.what() << std::endl; \
+ } \
} while(0)
#endif
try {
test.test();
std::cout << "+++ PASS " << test.name << " +++" << std::endl;
- } catch (const std::logic_error& e) {
+ } catch (const TestFailure& e) {
passed = false;
std::cout << "!!! FAIL " << test.name
<< ": Assertion failure: " << e.what() << " ===" << std::endl;