Validate opaque operands against binary operators

Add checks that opaque operands can only be used with array indexing
and field section, as mentioned in ESSL 3.10 section 4.1.7.

BUG=angleproject:2028

Change-Id: I41b7f10785bf712dfc999f85ebff925341c51911
Reviewed-on: https://chromium-review.googlesource.com/497767
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index 81a8370..7210de5 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -3769,8 +3769,24 @@
                                         TIntermTyped *right,
                                         const TSourceLoc &loc)
 {
-    // TODO(jie.a.chen@intel.com): Validate opaque type variables can only be operands in array
-    // indexing, structure member selection, and parentheses expressions.
+    // Check opaque types are not allowed to be operands in expressions other than array indexing
+    // and structure member selection.
+    if (IsOpaqueType(left->getBasicType()) || IsOpaqueType(right->getBasicType()))
+    {
+        switch (op)
+        {
+            case EOpIndexDirect:
+            case EOpIndexIndirect:
+                break;
+            case EOpIndexDirectStruct:
+                UNREACHABLE();
+
+            default:
+                error(loc, "Invalid operation for variables with an opaque type",
+                      GetOperatorString(op));
+                return false;
+        }
+    }
 
     if (left->getType().getStruct() || right->getType().getStruct())
     {