diff options
| author | Yong He <yonghe@outlook.com> | 2024-03-21 15:45:27 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-03-21 15:45:27 -0700 |
| commit | dd32414bd7332c55dc37ea2972ffcca73328d834 (patch) | |
| tree | 7bcca5ab90c794bb0caaad1b78b08dfa16240d5a | |
| parent | 9bd6b233b38f8ae0de72f41939be0cb2879b9919 (diff) | |
Diagnose cyclic references in inheritance graph. (#3811)
| -rw-r--r-- | source/slang/slang-check-inheritance.cpp | 14 | ||||
| -rw-r--r-- | source/slang/slang-diagnostic-defs.h | 2 | ||||
| -rw-r--r-- | tests/bugs/gh-3808.slang | 22 |
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 |
