diff --git a/Test/precision.frag b/Test/precision.frag
index f0ea6598d186890aff44333afd6cfad27fe8f58a..c9b1d7aba58b7ac02adf792e64fbedb4cd71d03d 100644
--- a/Test/precision.frag
+++ b/Test/precision.frag
@@ -35,17 +35,19 @@ void main()
         int level2_high;
         sum += level2_high;
         do {
-            if (1) {
+            if (true) {
                 precision mediump int;
                 int level4_medium;
                 sum += level4_medium;
             }
             int level3_high;
             sum += level3_high;
-        } while (1);	
+        } while (true);	
         int level2_high2;
         sum += level2_high2;
     }
     int level1_low3;
     sum += level1_low3;
+
+    sum += 4 + ((ivec2(level1_low3) * ivec2(level1_high) + ivec2((/* comma operator */level1_low3, level1_high)))).x;
 }
diff --git a/glslang/Include/intermediate.h b/glslang/Include/intermediate.h
index cbab65d0a13834026055aa3c9bac501d1b9ed2fe..c6e234c6b4b8974c616073706ea9d8ca3f3c75cb 100644
--- a/glslang/Include/intermediate.h
+++ b/glslang/Include/intermediate.h
@@ -231,6 +231,7 @@ enum TOperator {
 
 class TIntermTraverser;
 class TIntermAggregate;
+class TIntermUnary;
 class TIntermBinary;
 class TIntermConstantUnion;
 class TIntermSelection;
@@ -253,6 +254,7 @@ public:
     virtual TIntermTyped*     getAsTyped()         { return 0; }
     virtual TIntermConstantUnion*     getAsConstantUnion()         { return 0; }
     virtual TIntermAggregate* getAsAggregate()     { return 0; }
+    virtual TIntermUnary*     getAsUnaryNode()     { return 0; }
     virtual TIntermBinary*    getAsBinaryNode()    { return 0; }
     virtual TIntermSelection* getAsSelectionNode() { return 0; }
     virtual TIntermMethod*    getAsMethodNode()    { return 0; }
@@ -270,9 +272,6 @@ struct TIntermNodePair {
     TIntermNode* node2;
 };
 
-class TIntermSymbol;
-class TIntermBinary;
-
 //
 // Intermediate class for nodes that have a type.
 //
@@ -286,6 +285,7 @@ public:
     
     virtual TBasicType getBasicType() const { return type.getBasicType(); }
     virtual TQualifier& getQualifier() { return type.getQualifier(); }
+    virtual void propagatePrecision(TPrecisionQualifier);
     virtual int getNominalSize() const { return type.getNominalSize(); }
     virtual int getSize() const { return type.getInstanceSize(); }
     virtual bool isMatrix() const { return type.isMatrix(); }
@@ -428,6 +428,7 @@ public:
     virtual void traverse(TIntermTraverser*);
     virtual void setOperand(TIntermTyped* o) { operand = o; }
     virtual TIntermTyped* getOperand() { return operand; }
+    virtual TIntermUnary* getAsUnaryNode() { return this; }
     virtual bool promote(TInfoSink&);
 protected:
     TIntermTyped* operand;
diff --git a/glslang/MachineIndependent/Intermediate.cpp b/glslang/MachineIndependent/Intermediate.cpp
index 040de594a4e63d58dede8878a9efe4d8af41e525..389d4a9b743efa0a6e3525404695bda8fb1e0c7f 100644
--- a/glslang/MachineIndependent/Intermediate.cpp
+++ b/glslang/MachineIndependent/Intermediate.cpp
@@ -836,6 +836,8 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
     // Fix precision qualifiers
     if (right->getQualifier().precision > getQualifier().precision)
         getQualifier().precision = right->getQualifier().precision;
+    left->propagatePrecision(getQualifier().precision);
+    right->propagatePrecision(getQualifier().precision);
 
     //
     // Array operations.
@@ -1078,7 +1080,53 @@ bool CompareStruct(const TType& leftNodeType, constUnion* rightUnionArray, const
         }
     }
     return true;
-} 
+}
+
+void TIntermTyped::propagatePrecision(TPrecisionQualifier newPrecision)
+{
+    if (getQualifier().precision != EpqNone || (getBasicType() != EbtInt && getBasicType() != EbtFloat))
+        return;
+
+    getQualifier().precision = newPrecision;
+
+    TIntermBinary* binaryNode = getAsBinaryNode();
+    if (binaryNode) {
+        binaryNode->getLeft()->propagatePrecision(newPrecision);
+        binaryNode->getRight()->propagatePrecision(newPrecision);
+    }
+
+    TIntermUnary* unaryNode = getAsUnaryNode();
+    if (unaryNode)
+        unaryNode->getOperand()->propagatePrecision(newPrecision);
+
+    TIntermAggregate* aggregateNode = getAsAggregate();
+    if (aggregateNode) {
+        TIntermSequence operands = aggregateNode->getSequence();
+        for (unsigned int i = 0; i < operands.size(); ++i) {
+            TIntermTyped* typedNode = operands[i]->getAsTyped();
+            if (! typedNode)
+                break;
+            typedNode->propagatePrecision(newPrecision);
+        }
+    }
+
+    TIntermSelection* selectionNode = getAsSelectionNode();
+    if (selectionNode) {
+        TIntermTyped* typedNode = selectionNode->getTrueBlock()->getAsTyped();
+        if (typedNode) {
+            typedNode->propagatePrecision(newPrecision);
+            typedNode = selectionNode->getFalseBlock()->getAsTyped();
+            if (typedNode)
+                typedNode->propagatePrecision(newPrecision);
+        }
+    }
+
+    // TODO: propagate precision for
+    //    comma operator:  just through the last operand
+    //    ":?" and ",": where is this triggered?
+    //    built-in function calls: how much to propagate to arguments?
+    //    performance: don't do this for desktop profiles
+}
 
 bool CompareStructure(const TType& leftNodeType, constUnion* rightUnionArray, constUnion* leftUnionArray)
 {
diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp
index 797ec2512c541cef802ead25805836eebcd50f58..13b3bc3d0beed8b6299f3f968df887f8a5793624 100644
--- a/glslang/MachineIndependent/ParseHelper.cpp
+++ b/glslang/MachineIndependent/ParseHelper.cpp
@@ -60,7 +60,6 @@ TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, EShLangu
     defaultPrecision[EbtVoid]   = EpqNone;
     defaultPrecision[EbtDouble] = EpqNone;
     defaultPrecision[EbtBool]   = EpqNone;
-    defaultPrecision[EbtVoid]   = EpqNone;
 }
 
 //
diff --git a/glslang/MachineIndependent/intermOut.cpp b/glslang/MachineIndependent/intermOut.cpp
index 42252f8c8fe5ba8d7c63821e59bea1ca41f563f6..df07121e650bb8d6cac4473cc0847b5cd693de58 100644
--- a/glslang/MachineIndependent/intermOut.cpp
+++ b/glslang/MachineIndependent/intermOut.cpp
@@ -258,11 +258,11 @@ bool OutputAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTravers
     OutputTreeText(out, node, oit->depth);
 
     switch (node->getOp()) {
-    case EOpSequence:      out.debug << "Sequence\n"; return true;
-    case EOpComma:         out.debug << "Comma\n"; return true;
+    case EOpSequence:      out.debug << "Sequence\n";       return true;
+    case EOpComma:         out.debug << "Comma";            break;
     case EOpFunction:      out.debug << "Function Definition: " << node->getName(); break;
-    case EOpFunctionCall:  out.debug << "Function Call: " << node->getName(); break;
-    case EOpParameters:    out.debug << "Function Parameters: ";              break;
+    case EOpFunctionCall:  out.debug << "Function Call: "       << node->getName(); break;
+    case EOpParameters:    out.debug << "Function Parameters: ";                    break;
     
     case EOpConstructFloat: out.debug << "Construct float"; break;
     case EOpConstructVec2:  out.debug << "Construct vec2";  break;