diff --git a/Test/410.geom b/Test/410.geom
index 116d6fecb753a7cd5097621615bd127d98847acd..8775aeb159438038860c5490f5cfd93fb6cefae6 100644
--- a/Test/410.geom
+++ b/Test/410.geom
@@ -32,3 +32,8 @@ void foo()
     vec4 v = gl_in[1].gl_Position;    // ERROR, not included in the redeclaration
     gl_Position = vec4(1.0);          // ERROR, not included in the redeclaration
 }
+
+float foo5()
+{
+    return 4;  // implicit conversion of return type
+}
diff --git a/Test/420.geom b/Test/420.geom
index e883f0b84d3a40676509cf63c3a58f55e33928f3..43903bc7074043d7d3c14c0d0b6bc0f2d7783a44 100644
--- a/Test/420.geom
+++ b/Test/420.geom
@@ -48,3 +48,8 @@ out gl_PerVertex {
     float gl_PointSize[1];  // ERROR, adding array
     float gl_ClipDistance;  // ERROR, removing array
 };
+
+float foo5()
+{
+    return i;  // implicit conversion of return type
+}
diff --git a/Test/baseResults/120.frag.out b/Test/baseResults/120.frag.out
index 2c14ba3600b5997218d70144aa3e966635c7d6a3..fcd749bb11037693b9d3ac3c19383b25a42ef590 100644
--- a/Test/baseResults/120.frag.out
+++ b/Test/baseResults/120.frag.out
@@ -27,7 +27,7 @@ ERROR: 0:91: 'int' :  main function cannot return a value
 ERROR: 0:92: 'main' : function cannot take any parameter(s) 
 ERROR: 0:94: 'a' : variables with qualifier 'const' must be initialized 
 ERROR: 0:97: 'out' : overloaded functions must have the same parameter storage qualifiers for argument 1
-ERROR: 0:99: 'return' : function return is not matching type: 
+ERROR: 0:99: 'return' : type does not match, or is not convertible to, the function's return type 
 ERROR: 0:115: 'return' : void function cannot return a value 
 ERROR: 0:125: 'gl_TexCoord' : redeclaration of array with size 
 ERROR: 0:152: 'matrixCompMult' : no matching overloaded function found 
@@ -291,8 +291,7 @@ ERROR: node is still EOpNull!
 0:113  Function Definition: v2( (void)
 0:113    Function Parameters: 
 0:115    Sequence
-0:115      Branch: Return with expression
-0:115        Function Call: v1( (void)
+0:115      Branch: Return
 0:118  Function Definition: atest( (void)
 0:118    Function Parameters: 
 0:120    Sequence
@@ -650,8 +649,7 @@ ERROR: node is still EOpNull!
 0:113  Function Definition: v2( (void)
 0:113    Function Parameters: 
 0:115    Sequence
-0:115      Branch: Return with expression
-0:115        Function Call: v1( (void)
+0:115      Branch: Return
 0:118  Function Definition: atest( (void)
 0:118    Function Parameters: 
 0:120    Sequence
diff --git a/Test/baseResults/300scope.vert.out b/Test/baseResults/300scope.vert.out
index 00c7460051f34546f896a714bad43b15d691f52b..a6e40bad5961d915eec8bffa2f514d10776c4787 100644
--- a/Test/baseResults/300scope.vert.out
+++ b/Test/baseResults/300scope.vert.out
@@ -44,16 +44,12 @@ ERROR: node is still EOpNull!
 0:25    Function Parameters: 
 0:25      'x' (in highp float)
 0:27    Sequence
-0:27      Branch: Return with expression
-0:27        Constant:
-0:27          1.000000
+0:27      Branch: Return
 0:29  Function Definition: radians(b1; (bool)
 0:29    Function Parameters: 
 0:29      'x' (in bool)
 0:31    Sequence
-0:31      Branch: Return with expression
-0:31        Constant:
-0:31          true (const bool)
+0:31      Branch: Return
 0:36  Function Definition: main( (void)
 0:36    Function Parameters: 
 0:?     Sequence
@@ -157,16 +153,12 @@ ERROR: node is still EOpNull!
 0:25    Function Parameters: 
 0:25      'x' (in highp float)
 0:27    Sequence
-0:27      Branch: Return with expression
-0:27        Constant:
-0:27          1.000000
+0:27      Branch: Return
 0:29  Function Definition: radians(b1; (bool)
 0:29    Function Parameters: 
 0:29      'x' (in bool)
 0:31    Sequence
-0:31      Branch: Return with expression
-0:31        Constant:
-0:31          true (const bool)
+0:31      Branch: Return
 0:36  Function Definition: main( (void)
 0:36    Function Parameters: 
 0:?     Sequence
diff --git a/Test/baseResults/410.geom.out b/Test/baseResults/410.geom.out
index ae3c81e0d1a53fca0bb853a5839e48ec674c5272..0e7c7cccabcf120d1ceeb9456176c4fbc3789f87 100644
--- a/Test/baseResults/410.geom.out
+++ b/Test/baseResults/410.geom.out
@@ -7,6 +7,7 @@ ERROR: 0:32: 'gl_Position' :  no such field in structure
 ERROR: 0:32: '=' :  cannot convert from 'block{in float gl_PointSize}' to '4-component vector of float'
 ERROR: 0:33: 'gl_Position' : member of nameless block was not redeclared 
 ERROR: 0:33: 'assign' :  cannot convert from 'const 4-component vector of float' to 'layout(stream=0 ) gl_Position void'
+WARNING: 0:38: 'return' : type conversion on return values was not explicitly allowed until version 420 
 ERROR: 7 compilation errors.  No code generated.
 
 
@@ -46,6 +47,12 @@ ERROR: node is still EOpNull!
 0:33        'anon@0' (layout(stream=0 ) out block{layout(stream=0 ) gl_PointSize float gl_PointSize, })
 0:33        Constant:
 0:33          0 (const uint)
+0:36  Function Definition: foo5( (float)
+0:36    Function Parameters: 
+0:38    Sequence
+0:38      Branch: Return with expression
+0:38        Constant:
+0:38          4.000000
 0:?   Linker Objects
 0:?     'gl_in' (in implicitly-sized array of block{in float gl_PointSize})
 0:?     'anon@0' (layout(stream=0 ) out block{layout(stream=0 ) gl_PointSize float gl_PointSize, })
@@ -93,6 +100,12 @@ ERROR: node is still EOpNull!
 0:33        'anon@0' (layout(stream=0 ) out block{layout(stream=0 ) gl_PointSize float gl_PointSize, })
 0:33        Constant:
 0:33          0 (const uint)
+0:36  Function Definition: foo5( (float)
+0:36    Function Parameters: 
+0:38    Sequence
+0:38      Branch: Return with expression
+0:38        Constant:
+0:38          4.000000
 0:?   Linker Objects
 0:?     'gl_in' (in 2-element array of block{in float gl_PointSize})
 0:?     'anon@0' (layout(stream=0 ) out block{layout(stream=0 ) gl_PointSize float gl_PointSize, })
diff --git a/Test/baseResults/420.geom.out b/Test/baseResults/420.geom.out
index 6ed558b3b7b0a9f1754e47e3c748be615038f6e8..1b927b82cc1ca784c7e5d4d863050837c602ac4f 100644
--- a/Test/baseResults/420.geom.out
+++ b/Test/baseResults/420.geom.out
@@ -114,6 +114,12 @@ ERROR: node is still EOpNull!
 0:44            0 (const int)
 0:44          Constant:
 0:44            1 (const int)
+0:52  Function Definition: foo5( (float)
+0:52    Function Parameters: 
+0:54    Sequence
+0:54      Branch: Return with expression
+0:54        Convert int to float (float)
+0:54          'i' (int)
 0:?   Linker Objects
 0:?     'i' (int)
 0:?     'gl_in' (in 3-element array of block{in 4-component vector of float gl_Position, in float gl_PointSize, in implicitly-sized array of float gl_ClipDistance})
@@ -235,6 +241,12 @@ ERROR: node is still EOpNull!
 0:44            0 (const int)
 0:44          Constant:
 0:44            1 (const int)
+0:52  Function Definition: foo5( (float)
+0:52    Function Parameters: 
+0:54    Sequence
+0:54      Branch: Return with expression
+0:54        Convert int to float (float)
+0:54          'i' (int)
 0:?   Linker Objects
 0:?     'i' (int)
 0:?     'gl_in' (in 3-element array of block{in 4-component vector of float gl_Position, in float gl_PointSize, in 1-element array of float gl_ClipDistance})
diff --git a/Test/baseResults/array.frag.out b/Test/baseResults/array.frag.out
index f4c167bf23b66f5cc47187e5e81e0c3eada49c4e..f20b9676a48f97d23af869c74c2526b0cd06d093 100644
--- a/Test/baseResults/array.frag.out
+++ b/Test/baseResults/array.frag.out
@@ -19,7 +19,7 @@ ERROR: 0:63: '' : array size required
 ERROR: 0:66: '=' :  cannot convert from '3-component vector of float' to 'float'
 ERROR: 0:76: 'bar' : no matching overloaded function found 
 ERROR: 0:79: '' : array size required 
-ERROR: 0:84: 'return' : function return is not matching type: 
+ERROR: 0:84: 'return' : type does not match, or is not convertible to, the function's return type 
 ERROR: 0:93: 'length' :  array must be declared with a size before using this method
 ERROR: 0:101: '[' :  array index out of range '5'
 ERROR: 23 compilation errors.  No code generated.
diff --git a/Todo.txt b/Todo.txt
index 125a8e527f8b9a63ecf6b2a38934ba6ded0eb2b9..a516949bf1cc6719b37d7d5d8b815ea5e243eaea 100644
--- a/Todo.txt
+++ b/Todo.txt
@@ -115,20 +115,21 @@ Shader Functionality to Implement/Finish
         + layout qualifiers for primitive types
       - Polymorphic functions: Run-time selection of what function gets called, through the new keyword subroutine.
       - 64bit floating point numbers with the new type keyword double.  Built-in functions extended for doubles, and new function matching rules are added to both allow implicit conversions when calling a function and preserve most existing function matching once doubles are included. 
-      + More implicit conversions
+      + More implicit conversions 
          + float to double, and similarly for all floating-point vector and matrix types
          + int to uint, and similarly for all integer vector types
          + int to double, and similarly for all vectors of integers and doubles.
          + uint to double, and similarly for all vectors of integers and doubles.
-      - Cube map array textures and texture functions texture(), textureSize(), textureLod(), and textureGrad().
-      - Sampler arrays can take a variable index now, as long as it's value is uniform for all uses.
+      + Cube map array textures and texture functions texture(), textureSize(), textureLod(), and textureGrad().
+      + Sampler arrays can take a variable index now, as long as it's value is uniform for all uses.
       - Per-sample shading. Including sample input mask gl_SampleMaskIn[] and per-sample interpolation, with explicit interpolation built-ins interpolateAtCentroid(), interpolateAtSample(), and interpolateAtOffset().
       - New precise qualifier to disallow optimizations that re-order operations or treat different instances of the same operator with different precision.
       - Add a fused multiply and add built-in, fma(), in relation to the new precise qualifier. (Because ā€œa * b + cā€ will require two operations under new rules for precise.)
       - Added new built-in floating-point functions 
          - frexp() and ldexp()
-         - packUnorm2x16(), packUnorm4x8(),packSnorm4x8(), and packDouble2x32()
-         - unpackUnorm2x16(), unpackUnorm4x8(),unpackSnorm4x8(), and unpackDouble2x32()
+         + packUnorm2x16(), unpackUnorm2x16(),
+         - packUnorm4x8(),packSnorm4x8(), and packDouble2x32()
+         - unpackUnorm4x8(),unpackSnorm4x8(), and unpackDouble2x32()
       - Add new built-in integer functions
          - uaddCarry() andusubBorrow()
          - umulExtended() andimulExtended()
@@ -186,8 +187,7 @@ Shader Functionality to Implement/Finish
       - Allow .length() to be applied to vectors and matrices, returning the number of components or columns.
       + Clarify that .length() returns an int type and can be used as a constant integer expression.
       + Allow swizzle operations on scalars.
-      - Positive signed decimal literals, as well as octal and hexadecimal, can set all 32 bits. This includes setting the sign bit to create a negative value.
-      - Make GLSL consistent with the API regarding user clipping, by no longer referring to gl_Position when gl_ClipVertex is not written. Rather, user clipping becomes undefined.
+      + Positive signed decimal literals, as well as octal and hexadecimal, can set all 32 bits. This includes setting the sign bit to create a negative value.
       - Clarified that a comma sequence-operator expression cannot be a constant expression. E.g., ā€œ(2,3)ā€ is not allowed, semantically, 
             as a valid constant expression 3, even though it is an expression that will evaluate to 3.
       + Use vec2 instead of vec3 for coordinate in textureGather*(sampler2DRect,...).
diff --git a/glslang/MachineIndependent/Intermediate.cpp b/glslang/MachineIndependent/Intermediate.cpp
index f02e12040d633f01d673e9b6869a0810f172414e..8cdde85b93cca5aa5acfc0f18cc74a0c03cd5321 100644
--- a/glslang/MachineIndependent/Intermediate.cpp
+++ b/glslang/MachineIndependent/Intermediate.cpp
@@ -372,7 +372,7 @@ TIntermTyped* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator o
 // For implicit conversions, 'op' is not the requested conversion, it is the explicit 
 // operation requiring the implicit conversion.
 //
-// Returns the node representing the conversion, which could be the same
+// Returns a node representing the conversion, which could be the same
 // node passed in if no conversion was needed.
 //
 // Return 0 if a conversion can't be done.
@@ -455,6 +455,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
     case EOpMatrixTimesScalar:
 
     case EOpFunctionCall:
+    case EOpReturn:
     case EOpAssign:
     case EOpAddAssign:
     case EOpSubAssign:
diff --git a/glslang/MachineIndependent/glslang.y b/glslang/MachineIndependent/glslang.y
index a2157bcb19d4f03f927df25ab223e8ab4d70bd90..0105070a744bfbc3dd36956c8f830b95248e9b63 100644
--- a/glslang/MachineIndependent/glslang.y
+++ b/glslang/MachineIndependent/glslang.y
@@ -2395,12 +2395,22 @@ jump_statement
             parseContext.error($1.loc, "non-void function must return a value", "return", "");
     }
     | RETURN expression SEMICOLON {
-        $$ = parseContext.intermediate.addBranch(EOpReturn, $2, $1.loc);
         parseContext.functionReturnsValue = true;
-        if (parseContext.currentFunctionType->getBasicType() == EbtVoid)
+        if (parseContext.currentFunctionType->getBasicType() == EbtVoid) {
             parseContext.error($1.loc, "void function cannot return a value", "return", "");
-        else if (*(parseContext.currentFunctionType) != $2->getType())
-            parseContext.error($1.loc, "function return is not matching type:", "return", "");
+            $$ = parseContext.intermediate.addBranch(EOpReturn, $1.loc);
+        } else if (*(parseContext.currentFunctionType) != $2->getType()) {
+            TIntermTyped* converted = parseContext.intermediate.addConversion(EOpReturn, *parseContext.currentFunctionType, $2);
+            if (converted) {
+                if (parseContext.version < 420)
+                    parseContext.warn($1.loc, "type conversion on return values was not explicitly allowed until version 420", "return", "");
+                $$ = parseContext.intermediate.addBranch(EOpReturn, converted, $1.loc);
+            } else {
+                parseContext.error($1.loc, "type does not match, or is not convertible to, the function's return type", "return", "");
+                $$ = parseContext.intermediate.addBranch(EOpReturn, $2, $1.loc);
+            }
+        } else
+		    $$ = parseContext.intermediate.addBranch(EOpReturn, $2, $1.loc);
     }
     | DISCARD SEMICOLON {
         parseContext.requireStage($1.loc, EShLangFragment, "discard");