Fix crash with invalid out parameters.

Many calls to `setRefKind` failed to check the return value; if it's
false, an error has occurred and the program is in a bad state.
Specifically, there is an assignment to a variable that's not marked as
"written-to." If we continue processing the program, we're likely to
assert.

Change-Id: I2dd5d1f41aa5ca0d30f8d638f05fe2e838216d78
Bug: skia:10753
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/319116
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp
index 21b9c12..f9d2683 100644
--- a/src/sksl/SkSLIRGenerator.cpp
+++ b/src/sksl/SkSLIRGenerator.cpp
@@ -2099,11 +2099,13 @@
         if (!arguments[i]) {
             return nullptr;
         }
-        if (arguments[i] && (function.fParameters[i]->fModifiers.fFlags & Modifiers::kOut_Flag)) {
-            this->setRefKind(*arguments[i],
-                             function.fParameters[i]->fModifiers.fFlags & Modifiers::kIn_Flag ?
-                             VariableReference::kReadWrite_RefKind :
-                             VariableReference::kPointer_RefKind);
+        const Modifiers& paramModifiers = function.fParameters[i]->fModifiers;
+        if (paramModifiers.fFlags & Modifiers::kOut_Flag) {
+            if (!this->setRefKind(*arguments[i], paramModifiers.fFlags & Modifiers::kIn_Flag
+                                                         ? VariableReference::kReadWrite_RefKind
+                                                         : VariableReference::kPointer_RefKind)) {
+                return nullptr;
+            }
         }
     }
 
@@ -2359,23 +2361,23 @@
                 return nullptr;
             }
             return base;
+
         case Token::Kind::TK_MINUS:
-            if (base->kind() == Expression::Kind::kIntLiteral) {
-                return std::unique_ptr<Expression>(new IntLiteral(fContext, base->fOffset,
-                                                                  -base->as<IntLiteral>().fValue));
+            if (base->is<IntLiteral>()) {
+                return std::make_unique<IntLiteral>(fContext, base->fOffset,
+                                                    -base->as<IntLiteral>().fValue);
             }
-            if (base->kind() == Expression::Kind::kFloatLiteral) {
-                double value = -base->as<FloatLiteral>().fValue;
-                return std::unique_ptr<Expression>(new FloatLiteral(fContext, base->fOffset,
-                                                                    value));
+            if (base->is<FloatLiteral>()) {
+                return std::make_unique<FloatLiteral>(fContext, base->fOffset,
+                                                      -base->as<FloatLiteral>().fValue);
             }
             if (!baseType.isNumber() && baseType.typeKind() != Type::TypeKind::kVector) {
                 fErrors.error(expression.fOffset,
                               "'-' cannot operate on '" + baseType.displayName() + "'");
                 return nullptr;
             }
-            return std::unique_ptr<Expression>(new PrefixExpression(Token::Kind::TK_MINUS,
-                                                                    std::move(base)));
+            return std::make_unique<PrefixExpression>(Token::Kind::TK_MINUS, std::move(base));
+
         case Token::Kind::TK_PLUSPLUS:
             if (!baseType.isNumber()) {
                 fErrors.error(expression.fOffset,
@@ -2383,7 +2385,9 @@
                               "' cannot operate on '" + baseType.displayName() + "'");
                 return nullptr;
             }
-            this->setRefKind(*base, VariableReference::kReadWrite_RefKind);
+            if (!this->setRefKind(*base, VariableReference::kReadWrite_RefKind)) {
+                return nullptr;
+            }
             break;
         case Token::Kind::TK_MINUSMINUS:
             if (!baseType.isNumber()) {
@@ -2392,7 +2396,9 @@
                               "' cannot operate on '" + baseType.displayName() + "'");
                 return nullptr;
             }
-            this->setRefKind(*base, VariableReference::kReadWrite_RefKind);
+            if (!this->setRefKind(*base, VariableReference::kReadWrite_RefKind)) {
+                return nullptr;
+            }
             break;
         case Token::Kind::TK_LOGICALNOT:
             if (baseType != *fContext.fBool_Type) {
@@ -2402,8 +2408,8 @@
                 return nullptr;
             }
             if (base->kind() == Expression::Kind::kBoolLiteral) {
-                return std::unique_ptr<Expression>(
-                        new BoolLiteral(fContext, base->fOffset, !base->as<BoolLiteral>().fValue));
+                return std::make_unique<BoolLiteral>(fContext, base->fOffset,
+                                                     !base->as<BoolLiteral>().fValue);
             }
             break;
         case Token::Kind::TK_BITWISENOT:
@@ -2417,8 +2423,7 @@
         default:
             ABORT("unsupported prefix operator\n");
     }
-    return std::unique_ptr<Expression>(new PrefixExpression(expression.getToken().fKind,
-                                                            std::move(base)));
+    return std::make_unique<PrefixExpression>(expression.getToken().fKind, std::move(base));
 }
 
 std::unique_ptr<Expression> IRGenerator::convertIndex(std::unique_ptr<Expression> base,
@@ -2784,9 +2789,10 @@
                       "' cannot operate on '" + baseType.displayName() + "'");
         return nullptr;
     }
-    this->setRefKind(*base, VariableReference::kReadWrite_RefKind);
-    return std::unique_ptr<Expression>(new PostfixExpression(std::move(base),
-                                                             expression.getToken().fKind));
+    if (!this->setRefKind(*base, VariableReference::kReadWrite_RefKind)) {
+        return nullptr;
+    }
+    return std::make_unique<PostfixExpression>(std::move(base), expression.getToken().fKind);
 }
 
 void IRGenerator::checkValid(const Expression& expr) {
diff --git a/src/sksl/SkSLInliner.cpp b/src/sksl/SkSLInliner.cpp
index 2eb7758..f17b9fe 100644
--- a/src/sksl/SkSLInliner.cpp
+++ b/src/sksl/SkSLInliner.cpp
@@ -668,7 +668,7 @@
         const Variable* p = function.fDeclaration.fParameters[i];
         if (p->fModifiers.fFlags & Modifiers::kOut_Flag) {
             SkASSERT(varMap.find(p) != varMap.end());
-            if (arguments[i]->kind() == Expression::Kind::kVariableReference &&
+            if (arguments[i]->is<VariableReference>() &&
                 &arguments[i]->as<VariableReference>().fVariable == varMap[p]) {
                 // We didn't create a temporary for this parameter, so there's nothing to copy back
                 // out.
diff --git a/tests/SkSLGLSLTestbed.cpp b/tests/SkSLGLSLTestbed.cpp
index baffd8b..cbf40c1 100644
--- a/tests/SkSLGLSLTestbed.cpp
+++ b/tests/SkSLGLSLTestbed.cpp
@@ -30,6 +30,7 @@
         *inputs = program->fInputs;
         REPORTER_ASSERT(r, compiler.toGLSL(*program, &output));
         REPORTER_ASSERT(r, output != "");
+        //SkDebugf("GLSL output:\n\n%s", output.c_str());
     }
 }
 
diff --git a/tests/sksl/errors/golden/InvalidOutParams.glsl b/tests/sksl/errors/golden/InvalidOutParams.glsl
index 9d598bb..c3621d4 100644
--- a/tests/sksl/errors/golden/InvalidOutParams.glsl
+++ b/tests/sksl/errors/golden/InvalidOutParams.glsl
@@ -1,3 +1,6 @@
 ### Compilation failed:
 
-
+error: 1: cannot assign to this expression
+error: 5: cannot assign to this expression
+error: 6: cannot assign to this expression
+3 errors