Index: src/AST/AssertAcyclic.cpp
===================================================================
--- src/AST/AssertAcyclic.cpp	(revision 5684736fd985e020109cb45c53aa88513ff724e3)
+++ src/AST/AssertAcyclic.cpp	(revision 5684736fd985e020109cb45c53aa88513ff724e3)
@@ -0,0 +1,51 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2019 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// AssertAcyclic.cpp -- Check that ast::ptr does not form a cycle.
+//
+// Author           : Andrew Beach
+// Created On       : Thu Jun 06 15:00:00 2019
+// Last Modified By : Andrew Beach
+// Last Modified On : Thu Jun 06 15:00:00 2019
+// Update Count     : 0
+//
+
+#include "AssertAcyclic.hpp"
+
+#include "AST/Pass.hpp"
+
+namespace {
+
+class NoStrongCyclesCore : public ast::WithGuards {
+    std::vector<const ast::Node *> parents;
+public:
+	void previsit ( const ast::Node * node ) {
+		for (auto & p : parents) {
+			assert(p != node);
+		}
+		parents.push_back(node);
+		GuardAction( [this]() { parents.pop_back(); } );
+	}
+};
+
+}
+
+namespace ast {
+
+void assertAcyclic( const std::list< ast::ptr< ast::Decl > > translationUnit ) {
+   	Pass<NoStrongCyclesCore> visitor;
+	for ( auto & decl : translationUnit ) {
+		decl->accept( visitor );
+	}
+}
+
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/AST/AssertAcyclic.hpp
===================================================================
--- src/AST/AssertAcyclic.hpp	(revision 5684736fd985e020109cb45c53aa88513ff724e3)
+++ src/AST/AssertAcyclic.hpp	(revision 5684736fd985e020109cb45c53aa88513ff724e3)
@@ -0,0 +1,35 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// AssertAcyclic.hpp -- Check that ast::ptr does not form a cycle.
+//
+// Author           : Andrew Beach
+// Created On       : Thr May 6 15:00:00 2019
+// Last Modified By : Andrew Beach
+// Last Modified On : Thr May 6 15:00:00 2019
+// Update Count     : 0
+//
+
+#pragma once
+
+#include <list>
+
+#include "Node.hpp"
+namespace ast {
+    class Decl;
+};
+
+namespace ast {
+
+void assertAcyclic( const std::list< ast::ptr< ast::Decl > > translationUnit );
+
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/AST/module.mk
===================================================================
--- src/AST/module.mk	(revision 2b59f556da930033369d1ca9b86be75a4b277ff7)
+++ src/AST/module.mk	(revision 5684736fd985e020109cb45c53aa88513ff724e3)
@@ -16,4 +16,5 @@
 
 SRC_AST = \
+	AST/AssertAcyclic.cpp \
 	AST/Attribute.cpp \
 	AST/Convert.cpp \
Index: src/Makefile.in
===================================================================
--- src/Makefile.in	(revision 2b59f556da930033369d1ca9b86be75a4b277ff7)
+++ src/Makefile.in	(revision 5684736fd985e020109cb45c53aa88513ff724e3)
@@ -165,12 +165,12 @@
 libdemangle_a_LIBADD =
 am__dirstamp = $(am__leading_dot)dirstamp
-am__objects_1 = AST/Attribute.$(OBJEXT) AST/Convert.$(OBJEXT) \
-	AST/Decl.$(OBJEXT) AST/DeclReplacer.$(OBJEXT) \
-	AST/Expr.$(OBJEXT) AST/GenericSubstitution.$(OBJEXT) \
-	AST/Init.$(OBJEXT) AST/LinkageSpec.$(OBJEXT) \
-	AST/Node.$(OBJEXT) AST/Pass.$(OBJEXT) AST/Print.$(OBJEXT) \
-	AST/Stmt.$(OBJEXT) AST/SymbolTable.$(OBJEXT) \
-	AST/Type.$(OBJEXT) AST/TypeEnvironment.$(OBJEXT) \
-	AST/TypeSubstitution.$(OBJEXT)
+am__objects_1 = AST/AssertAcyclic.$(OBJEXT) AST/Attribute.$(OBJEXT) \
+	AST/Convert.$(OBJEXT) AST/Decl.$(OBJEXT) \
+	AST/DeclReplacer.$(OBJEXT) AST/Expr.$(OBJEXT) \
+	AST/GenericSubstitution.$(OBJEXT) AST/Init.$(OBJEXT) \
+	AST/LinkageSpec.$(OBJEXT) AST/Node.$(OBJEXT) \
+	AST/Pass.$(OBJEXT) AST/Print.$(OBJEXT) AST/Stmt.$(OBJEXT) \
+	AST/SymbolTable.$(OBJEXT) AST/Type.$(OBJEXT) \
+	AST/TypeEnvironment.$(OBJEXT) AST/TypeSubstitution.$(OBJEXT)
 am__objects_2 = CodeGen/CodeGenerator.$(OBJEXT) \
 	CodeGen/FixMain.$(OBJEXT) CodeGen/GenType.$(OBJEXT) \
@@ -577,4 +577,5 @@
 @WITH_LIBTCMALLOC_TRUE@TCMALLOCFLAG = -DTCMALLOC
 SRC_AST = \
+	AST/AssertAcyclic.cpp \
 	AST/Attribute.cpp \
 	AST/Convert.cpp \
@@ -744,4 +745,6 @@
 	@$(MKDIR_P) AST/$(DEPDIR)
 	@: > AST/$(DEPDIR)/$(am__dirstamp)
+AST/AssertAcyclic.$(OBJEXT): AST/$(am__dirstamp) \
+	AST/$(DEPDIR)/$(am__dirstamp)
 AST/Attribute.$(OBJEXT): AST/$(am__dirstamp) \
 	AST/$(DEPDIR)/$(am__dirstamp)
@@ -1193,4 +1196,5 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MakeLibCfa.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/AssertAcyclic.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/Attribute.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/Convert.Po@am__quote@
