From 82e0e589934a0bc2237bcc05959ca218817e105b Mon Sep 17 00:00:00 2001
From: John Kessenich <cepheus@frii.com>
Date: Thu, 26 Jan 2017 15:48:27 -0700
Subject: [PATCH] Fix issue #693. Ternary operator on void type.

---
 Test/120.frag                                  |  8 ++++++++
 Test/baseResults/120.frag.out                  | 17 ++++++++++++++++-
 glslang/MachineIndependent/Intermediate.cpp    |  8 +++++++-
 glslang/MachineIndependent/localintermediate.h |  2 +-
 4 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/Test/120.frag b/Test/120.frag
index 9035aed7b..028d30810 100644
--- a/Test/120.frag
+++ b/Test/120.frag
@@ -236,3 +236,11 @@ void foo12111()
 
     v = shadow2DRectProjGradARB(s2DRS, v, v2, v2);
 }
+
+void voidTernary()
+{
+	bool b;
+	b ? foo121111() : foo12111();
+	b ? foo121111() : 4;  // ERROR
+	b ? 3 : foo12111();   // ERROR
+}
\ No newline at end of file
diff --git a/Test/baseResults/120.frag.out b/Test/baseResults/120.frag.out
index 5df3f987b..5028b7514 100644
--- a/Test/baseResults/120.frag.out
+++ b/Test/baseResults/120.frag.out
@@ -50,7 +50,9 @@ ERROR: 0:191: 'shadow2DProjGradARB' : required extension not requested: GL_ARB_s
 ERROR: 0:209: 'shadow2DRectProjGradARB' : no matching overloaded function found 
 ERROR: 0:209: 'assign' :  cannot convert from 'const float' to 'temp 4-component vector of float'
 ERROR: 0:212: 'sampler2DRect' : Reserved word. 
-ERROR: 51 compilation errors.  No code generated.
+ERROR: 0:244: ':' :  wrong operand types: no operation ':' exists that takes a left-hand operand of type 'global void' and a right operand of type 'const int' (or there is no acceptable conversion)
+ERROR: 0:245: ':' :  wrong operand types: no operation ':' exists that takes a left-hand operand of type 'const int' and a right operand of type 'global void' (or there is no acceptable conversion)
+ERROR: 53 compilation errors.  No code generated.
 
 
 Shader version: 120
@@ -601,6 +603,19 @@ ERROR: node is still EOpNull!
 0:237          'v' (temp 4-component vector of float)
 0:237          'v2' (temp 2-component vector of float)
 0:237          'v2' (temp 2-component vector of float)
+0:240  Function Definition: voidTernary( (global void)
+0:240    Function Parameters: 
+0:?     Sequence
+0:243      Test condition and select (temp void)
+0:243        Condition
+0:243        'b' (temp bool)
+0:243        true case
+0:243        Function Call: foo121111( (global void)
+0:243        false case
+0:243        Function Call: foo12111( (global void)
+0:244      Constant:
+0:244        4 (const int)
+0:245      Function Call: foo12111( (global void)
 0:?   Linker Objects
 0:?     'lowp' (global float)
 0:?     'mediump' (global float)
diff --git a/glslang/MachineIndependent/Intermediate.cpp b/glslang/MachineIndependent/Intermediate.cpp
index 8d68517a3..af3e8119d 100644
--- a/glslang/MachineIndependent/Intermediate.cpp
+++ b/glslang/MachineIndependent/Intermediate.cpp
@@ -1232,7 +1232,7 @@ TIntermAggregate* TIntermediate::makeAggregate(const TSourceLoc& loc)
 //
 // Returns the selection node created.
 //
-TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, const TSourceLoc& loc)
+TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, const TSourceLoc& loc)
 {
     //
     // Don't prune the false path for compile-time constants; it's needed
@@ -1281,6 +1281,12 @@ TIntermTyped* TIntermediate::addMethod(TIntermTyped* object, const TType& type,
 //
 TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc& loc)
 {
+    // If it's void, go to the if-then-else selection()
+    if (trueBlock->getBasicType() == EbtVoid && falseBlock->getBasicType() == EbtVoid) {
+        TIntermNodePair pair = { trueBlock, falseBlock };
+        return addSelection(cond, pair, loc);
+    }
+
     //
     // Get compatible types.
     //
diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h
index ec58d50d4..29efb54c9 100644
--- a/glslang/MachineIndependent/localintermediate.h
+++ b/glslang/MachineIndependent/localintermediate.h
@@ -252,7 +252,7 @@ public:
     TIntermAggregate* makeAggregate(const TSourceLoc&);
     TIntermTyped* setAggregateOperator(TIntermNode*, TOperator, const TType& type, TSourceLoc);
     bool areAllChildConst(TIntermAggregate* aggrNode);
-    TIntermNode*  addSelection(TIntermTyped* cond, TIntermNodePair code, const TSourceLoc&);
+    TIntermTyped* addSelection(TIntermTyped* cond, TIntermNodePair code, const TSourceLoc&);
     TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc&);
     TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc&);
     TIntermTyped* addMethod(TIntermTyped*, const TType&, const TString*, const TSourceLoc&);
-- 
GitLab