translator: Fail compilation if precision emu unsupported.

The fuzzer uncovered a case where we were trying to emulate precision
on HLSL 3.0, causing an ASSERT crash.

BUG=chromium:653276

Change-Id: I2e666a1ff4f605541e25f04264146063559cb835
Reviewed-on: https://chromium-review.googlesource.com/394237
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Olli Etuaho <oetuaho@nvidia.com>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
diff --git a/src/compiler/translator/Compiler.cpp b/src/compiler/translator/Compiler.cpp
index 74c0104..547c09b 100644
--- a/src/compiler/translator/Compiler.cpp
+++ b/src/compiler/translator/Compiler.cpp
@@ -15,6 +15,7 @@
 #include "compiler/translator/CallDAG.h"
 #include "compiler/translator/DeferGlobalInitializers.h"
 #include "compiler/translator/EmulateGLFragColorBroadcast.h"
+#include "compiler/translator/EmulatePrecision.h"
 #include "compiler/translator/ForLoopUnroll.h"
 #include "compiler/translator/Initialize.h"
 #include "compiler/translator/InitializeParseContext.h"
@@ -329,6 +330,18 @@
         if (success && shouldRunLoopAndIndexingValidation(compileOptions))
             success = validateLimitations(root);
 
+        // Fail compilation if precision emulation not supported.
+        if (success && getResources().WEBGL_debug_shader_precision &&
+            getPragma().debugShaderPrecision)
+        {
+            if (!EmulatePrecision::SupportedInLanguage(outputType))
+            {
+                infoSink.info.prefix(EPrefixError);
+                infoSink.info << "Precision emulation not supported for this output type.";
+                success = false;
+            }
+        }
+
         // Unroll for-loop markup needs to happen after validateLimitations pass.
         if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX))
         {
diff --git a/src/compiler/translator/EmulatePrecision.cpp b/src/compiler/translator/EmulatePrecision.cpp
index 7b4f87b..a3025f0 100644
--- a/src/compiler/translator/EmulatePrecision.cpp
+++ b/src/compiler/translator/EmulatePrecision.cpp
@@ -91,6 +91,7 @@
 
 RoundingHelperWriter *RoundingHelperWriter::createHelperWriter(const ShShaderOutput outputLanguage)
 {
+    ASSERT(EmulatePrecision::SupportedInLanguage(outputLanguage));
     switch (outputLanguage)
     {
         case SH_HLSL_4_1_OUTPUT:
@@ -98,9 +99,6 @@
         case SH_ESSL_OUTPUT:
             return new RoundingHelperWriterESSL(outputLanguage);
         default:
-            // Other languages not yet supported
-            ASSERT(outputLanguage == SH_GLSL_COMPATIBILITY_OUTPUT ||
-                   IsGLSL130OrNewer(outputLanguage));
             return new RoundingHelperWriterGLSL(outputLanguage);
     }
 }
@@ -705,3 +703,17 @@
         roundingHelperWriter->writeCompoundAssignmentHelper(sink, it->lType, it->rType, "*", "mul");
 }
 
+// static
+bool EmulatePrecision::SupportedInLanguage(const ShShaderOutput outputLanguage)
+{
+    switch (outputLanguage)
+    {
+        case SH_HLSL_4_1_OUTPUT:
+        case SH_ESSL_OUTPUT:
+            return true;
+        default:
+            // Other languages not yet supported
+            return (outputLanguage == SH_GLSL_COMPATIBILITY_OUTPUT ||
+                    IsGLSL130OrNewer(outputLanguage));
+    }
+}
diff --git a/src/compiler/translator/EmulatePrecision.h b/src/compiler/translator/EmulatePrecision.h
index c2b9857..f23e40b 100644
--- a/src/compiler/translator/EmulatePrecision.h
+++ b/src/compiler/translator/EmulatePrecision.h
@@ -32,6 +32,8 @@
                                const int shaderVersion,
                                const ShShaderOutput outputLanguage);
 
+    static bool SupportedInLanguage(const ShShaderOutput outputLanguage);
+
   private:
     struct TypePair
     {