Add unit test demonstrating recursion codegen bug.

The generated code does not assign to sk_OutColor correctly; it assigns
into the `factorial` function name instead, which doesn't make sense.

Change-Id: Ibad1d47f2f9c4fbb410b5277cea6e1022daf8b9d
Bug: skia:10684
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/329360
Commit-Queue: John Stiles <johnstiles@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/gn/sksl_tests.gni b/gn/sksl_tests.gni
index f5ee0e6..687f8e4 100644
--- a/gn/sksl_tests.gni
+++ b/gn/sksl_tests.gni
@@ -17,6 +17,7 @@
   "$_tests/sksl/errors/GrNoFragmentProcessorLocals.fp",
   "$_tests/sksl/errors/GrNoFragmentProcessorParams.fp",
   "$_tests/sksl/errors/GrNoFragmentProcessorReturn.fp",
+  "$_tests/sksl/errors/GrRecursion.fp",
 ]
 
 sksl_fp_tests = [
diff --git a/tests/sksl/errors/GrRecursion.fp b/tests/sksl/errors/GrRecursion.fp
new file mode 100644
index 0000000..50214f9
--- /dev/null
+++ b/tests/sksl/errors/GrRecursion.fp
@@ -0,0 +1,7 @@
+int factorial(int x) {
+    return (x <= 1) ? 1 : x * factorial(x - 1);
+}
+
+void main() {
+    sk_OutColor = half4(factorial(7));
+}
diff --git a/tests/sksl/errors/golden/GrRecursion.cpp b/tests/sksl/errors/golden/GrRecursion.cpp
new file mode 100644
index 0000000..61942e1
--- /dev/null
+++ b/tests/sksl/errors/golden/GrRecursion.cpp
@@ -0,0 +1,66 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrRecursion.fp; do not modify.
+ **************************************************************************************************/
+#include "GrRecursion.h"
+
+#include "src/core/SkUtils.h"
+#include "src/gpu/GrTexture.h"
+#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
+#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
+#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
+#include "src/sksl/SkSLCPP.h"
+#include "src/sksl/SkSLUtil.h"
+class GrGLSLRecursion : public GrGLSLFragmentProcessor {
+public:
+    GrGLSLRecursion() {}
+    void emitCode(EmitArgs& args) override {
+        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+        const GrRecursion& _outer = args.fFp.cast<GrRecursion>();
+        (void) _outer;
+        SkString factorial_name;
+        const GrShaderVar factorial_args[] = { GrShaderVar("x", kInt_GrSLType)};
+        fragBuilder->emitFunction(kInt_GrSLType, "factorial", 1, factorial_args,
+R"SkSL(return x <= 1 ? 1 : x * %s(x - 1);
+)SkSL", &factorial_name);
+        fragBuilder->codeAppendf(
+R"SkSL(int _0_factorial;
+{
+    _0_factorial = 7 * %s(6);
+}
+
+%s = half4(half(_0_factorial));
+
+)SkSL"
+, factorial_name.c_str(), factorial_name.c_str());
+    }
+private:
+    void onSetData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& _proc) override {
+    }
+};
+GrGLSLFragmentProcessor* GrRecursion::onCreateGLSLInstance() const {
+    return new GrGLSLRecursion();
+}
+void GrRecursion::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
+}
+bool GrRecursion::onIsEqual(const GrFragmentProcessor& other) const {
+    const GrRecursion& that = other.cast<GrRecursion>();
+    (void) that;
+    return true;
+}
+bool GrRecursion::usesExplicitReturn() const {
+    return false;
+}
+GrRecursion::GrRecursion(const GrRecursion& src)
+: INHERITED(kGrRecursion_ClassID, src.optimizationFlags()) {
+        this->cloneAndRegisterAllChildProcessors(src);
+}
+std::unique_ptr<GrFragmentProcessor> GrRecursion::clone() const {
+    return std::make_unique<GrRecursion>(*this);
+}
+#if GR_TEST_UTILS
+SkString GrRecursion::onDumpInfo() const {
+    return SkString();
+}
+#endif
diff --git a/tests/sksl/errors/golden/GrRecursion.h b/tests/sksl/errors/golden/GrRecursion.h
new file mode 100644
index 0000000..3c96e23
--- /dev/null
+++ b/tests/sksl/errors/golden/GrRecursion.h
@@ -0,0 +1,37 @@
+
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrRecursion.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrRecursion_DEFINED
+#define GrRecursion_DEFINED
+
+#include "include/core/SkM44.h"
+#include "include/core/SkTypes.h"
+
+
+#include "src/gpu/GrFragmentProcessor.h"
+
+class GrRecursion : public GrFragmentProcessor {
+public:
+    static std::unique_ptr<GrFragmentProcessor> Make() {
+        return std::unique_ptr<GrFragmentProcessor>(new GrRecursion());
+    }
+    GrRecursion(const GrRecursion& src);
+    std::unique_ptr<GrFragmentProcessor> clone() const override;
+    const char* name() const override { return "Recursion"; }
+    bool usesExplicitReturn() const override;
+private:
+    GrRecursion()
+    : INHERITED(kGrRecursion_ClassID, kNone_OptimizationFlags) {
+    }
+    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+    void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+    bool onIsEqual(const GrFragmentProcessor&) const override;
+#if GR_TEST_UTILS
+    SkString onDumpInfo() const override;
+#endif
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+    using INHERITED = GrFragmentProcessor;
+};
+#endif