summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2024-03-21 15:45:27 -0700
committerGitHub <noreply@github.com>2024-03-21 15:45:27 -0700
commitdd32414bd7332c55dc37ea2972ffcca73328d834 (patch)
tree7bcca5ab90c794bb0caaad1b78b08dfa16240d5a
parent9bd6b233b38f8ae0de72f41939be0cb2879b9919 (diff)
Diagnose cyclic references in inheritance graph. (#3811)
-rw-r--r--source/slang/slang-check-inheritance.cpp14
-rw-r--r--source/slang/slang-diagnostic-defs.h2
-rw-r--r--tests/bugs/gh-3808.slang22
3 files changed, 38 insertions, 0 deletions
diff --git a/source/slang/slang-check-inheritance.cpp b/source/slang/slang-check-inheritance.cpp
index 5fff47cf1..18624424c 100644
--- a/source/slang/slang-check-inheritance.cpp
+++ b/source/slang/slang-check-inheritance.cpp
@@ -569,6 +569,18 @@ namespace Slang
// later.
}
+ // If we still cannot find a facet, then there is a true cycle in
+ // the inheritance graph, which is an error in the user code.
+ if (!foundFacet.getImpl())
+ {
+ if (!bases.isEmpty())
+ {
+ auto baseDecl = (*bases.begin())->facetImpl.origin.declRef.getDecl();
+ getSink()->diagnose(baseDecl, Diagnostics::cyclicReferenceInInheritance, baseDecl);
+ }
+ return;
+ }
+
// At this point we definitely have a facet we'd like to
// add to the output, whether it was found via the true
// C3 approach, or our relaxed rule above.
@@ -793,6 +805,8 @@ namespace Slang
{
for (auto base : *this)
{
+ if (base->facets.isEmpty())
+ continue;
if (base->facets.getTail().containsMatchFor(facet))
return true;
}
diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h
index 7a72daa5e..6299d6666 100644
--- a/source/slang/slang-diagnostic-defs.h
+++ b/source/slang/slang-diagnostic-defs.h
@@ -470,6 +470,8 @@ DIAGNOSTIC(30510, Error, loopInDiffFuncRequireUnrollOrMaxIters, "loops inside a
// TODO: need to assign numbers to all these extra diagnostics...
DIAGNOSTIC(39999, Fatal, cyclicReference, "cyclic reference '$0'.")
+DIAGNOSTIC(39999, Error, cyclicReferenceInInheritance, "cyclic reference in inheritance graph '$0'.")
+
DIAGNOSTIC(39999, Error, localVariableUsedBeforeDeclared, "local variable '$0' is being used before its declaration.")
DIAGNOSTIC(39999, Error, variableUsedInItsOwnDefinition, "the initial-value expression for variable '$0' depends on the value of the variable itself")
DIAGNOSTIC(39901, Fatal , cannotProcessInclude, "internal compiler error: cannot process '__include' in the current semantic checking context.")
diff --git a/tests/bugs/gh-3808.slang b/tests/bugs/gh-3808.slang
new file mode 100644
index 000000000..088a41985
--- /dev/null
+++ b/tests/bugs/gh-3808.slang
@@ -0,0 +1,22 @@
+//TEST:SIMPLE(filecheck=CHECK): -target spirv -emit-spirv-directly
+
+// CHECK: cyclic reference
+interface IFoo { void ff(); }
+interface I : IFoo,K { void doThing(); } // ': I' is the problem.
+interface J : K {}
+interface K : I { void doThingK(); }
+struct S<T: I> {
+ T t;
+}
+
+void t<T : I>(T j)
+{
+ j.doThing();
+}
+
+[shader("compute")]
+[numthreads(1,1,1)]
+void main()
+{
+
+} \ No newline at end of file