HLSL: Error if funcion with return type doesn't return a value.

This commit is contained in:
John Kessenich 2016-09-02 19:13:36 -06:00
parent 1a4b775cd5
commit a305166ea4
15 changed files with 73 additions and 53 deletions

View File

@ -2,7 +2,7 @@ hlsl.attribute.frag
Shader version: 450 Shader version: 450
gl_FragCoord origin is upper left gl_FragCoord origin is upper left
0:? Sequence 0:? Sequence
0:2 Function Definition: PixelShaderFunction(vf4; (global 4-component vector of float) 0:2 Function Definition: PixelShaderFunction(vf4; (global void)
0:2 Function Parameters: 0:2 Function Parameters:
0:2 'input' (layout(location=0 ) in 4-component vector of float) 0:2 'input' (layout(location=0 ) in 4-component vector of float)
0:? Sequence 0:? Sequence
@ -20,7 +20,7 @@ Linked fragment stage:
Shader version: 450 Shader version: 450
gl_FragCoord origin is upper left gl_FragCoord origin is upper left
0:? Sequence 0:? Sequence
0:2 Function Definition: PixelShaderFunction(vf4; (global 4-component vector of float) 0:2 Function Definition: PixelShaderFunction(vf4; (global void)
0:2 Function Parameters: 0:2 Function Parameters:
0:2 'input' (layout(location=0 ) in 4-component vector of float) 0:2 'input' (layout(location=0 ) in 4-component vector of float)
0:? Sequence 0:? Sequence

View File

@ -14,7 +14,7 @@ gl_FragCoord origin is upper left
0:3 1.000000 0:3 1.000000
0:3 true case 0:3 true case
0:4 Branch: Kill 0:4 Branch: Kill
0:8 Function Definition: PixelShaderFunction(vf4; (global 4-component vector of float) 0:8 Function Definition: PixelShaderFunction(vf4; (global void)
0:8 Function Parameters: 0:8 Function Parameters:
0:8 'input' (layout(location=0 ) in 4-component vector of float) 0:8 'input' (layout(location=0 ) in 4-component vector of float)
0:? Sequence 0:? Sequence
@ -60,7 +60,7 @@ gl_FragCoord origin is upper left
0:3 1.000000 0:3 1.000000
0:3 true case 0:3 true case
0:4 Branch: Kill 0:4 Branch: Kill
0:8 Function Definition: PixelShaderFunction(vf4; (global 4-component vector of float) 0:8 Function Definition: PixelShaderFunction(vf4; (global void)
0:8 Function Parameters: 0:8 Function Parameters:
0:8 'input' (layout(location=0 ) in 4-component vector of float) 0:8 'input' (layout(location=0 ) in 4-component vector of float)
0:? Sequence 0:? Sequence

View File

@ -11,6 +11,9 @@ gl_FragCoord origin is upper left
0:9 Function Parameters: 0:9 Function Parameters:
0:9 'inFloat1' (in 1-component vector of float) 0:9 'inFloat1' (in 1-component vector of float)
0:9 'inScalar' (in float) 0:9 'inScalar' (in float)
0:? Sequence
0:10 Branch: Return with expression
0:10 'inFloat1' (in 1-component vector of float)
0:? Linker Objects 0:? Linker Objects
0:? 'f1' (global 1-component vector of float) 0:? 'f1' (global 1-component vector of float)
0:? 'fmat11' (global 1X1 matrix of float) 0:? 'fmat11' (global 1X1 matrix of float)
@ -35,6 +38,9 @@ gl_FragCoord origin is upper left
0:9 Function Parameters: 0:9 Function Parameters:
0:9 'inFloat1' (in 1-component vector of float) 0:9 'inFloat1' (in 1-component vector of float)
0:9 'inScalar' (in float) 0:9 'inScalar' (in float)
0:? Sequence
0:10 Branch: Return with expression
0:10 'inFloat1' (in 1-component vector of float)
0:? Linker Objects 0:? Linker Objects
0:? 'f1' (global 1-component vector of float) 0:? 'f1' (global 1-component vector of float)
0:? 'fmat11' (global 1X1 matrix of float) 0:? 'fmat11' (global 1X1 matrix of float)
@ -45,7 +51,7 @@ gl_FragCoord origin is upper left
// Module Version 10000 // Module Version 10000
// Generated by (magic number): 80001 // Generated by (magic number): 80001
// Id's are bound by 38 // Id's are bound by 40
Capability Shader Capability Shader
Capability Float64 Capability Float64
@ -58,11 +64,11 @@ gl_FragCoord origin is upper left
Name 9 "inFloat1" Name 9 "inFloat1"
Name 10 "inScalar" Name 10 "inScalar"
Name 14 "f1" Name 14 "f1"
Name 20 "fmat11" Name 22 "fmat11"
Name 24 "fmat41" Name 26 "fmat41"
Name 27 "fmat12" Name 29 "fmat12"
Name 32 "dmat23" Name 34 "dmat23"
Name 37 "int44" Name 39 "int44"
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
6: TypeFloat 32 6: TypeFloat 32
@ -71,27 +77,27 @@ gl_FragCoord origin is upper left
13: TypePointer Private 6(float) 13: TypePointer Private 6(float)
14(f1): 13(ptr) Variable Private 14(f1): 13(ptr) Variable Private
15: 6(float) Constant 1065353216 15: 6(float) Constant 1065353216
17: TypeVector 6(float) 1 19: TypeVector 6(float) 1
18: TypeMatrix 17(fvec) 1 20: TypeMatrix 19(fvec) 1
19: TypePointer Private 18 21: TypePointer Private 20
20(fmat11): 19(ptr) Variable Private 22(fmat11): 21(ptr) Variable Private
21: TypeVector 6(float) 4 23: TypeVector 6(float) 4
22: TypeMatrix 21(fvec4) 1 24: TypeMatrix 23(fvec4) 1
23: TypePointer Private 22 25: TypePointer Private 24
24(fmat41): 23(ptr) Variable Private 26(fmat41): 25(ptr) Variable Private
25: TypeMatrix 17(fvec) 2 27: TypeMatrix 19(fvec) 2
26: TypePointer Private 25 28: TypePointer Private 27
27(fmat12): 26(ptr) Variable Private 29(fmat12): 28(ptr) Variable Private
28: TypeFloat 64 30: TypeFloat 64
29: TypeVector 28(float) 2 31: TypeVector 30(float) 2
30: TypeMatrix 29(fvec2) 3 32: TypeMatrix 31(fvec2) 3
31: TypePointer Private 30 33: TypePointer Private 32
32(dmat23): 31(ptr) Variable Private 34(dmat23): 33(ptr) Variable Private
33: TypeInt 32 1 35: TypeInt 32 1
34: TypeVector 33(int) 4 36: TypeVector 35(int) 4
35: TypeMatrix 34(ivec4) 4 37: TypeMatrix 36(ivec4) 4
36: TypePointer Private 35 38: TypePointer Private 37
37(int44): 36(ptr) Variable Private 39(int44): 38(ptr) Variable Private
4(PixelShaderFunction): 2 Function None 3 4(PixelShaderFunction): 2 Function None 3
5: Label 5: Label
Store 14(f1) 15 Store 14(f1) 15
@ -100,6 +106,6 @@ gl_FragCoord origin is upper left
9(inFloat1): 7(ptr) FunctionParameter 9(inFloat1): 7(ptr) FunctionParameter
10(inScalar): 7(ptr) FunctionParameter 10(inScalar): 7(ptr) FunctionParameter
12: Label 12: Label
16: 6(float) Undef 16: 6(float) Load 9(inFloat1)
ReturnValue 16 ReturnValue 16
FunctionEnd FunctionEnd

View File

@ -2,7 +2,7 @@ hlsl.scope.frag
Shader version: 450 Shader version: 450
gl_FragCoord origin is upper left gl_FragCoord origin is upper left
0:? Sequence 0:? Sequence
0:2 Function Definition: PixelShaderFunction(vf4; (global 4-component vector of float) 0:2 Function Definition: PixelShaderFunction(vf4; (global void)
0:2 Function Parameters: 0:2 Function Parameters:
0:2 'input' (layout(location=0 ) in 4-component vector of float) 0:2 'input' (layout(location=0 ) in 4-component vector of float)
0:? Sequence 0:? Sequence
@ -46,7 +46,7 @@ Linked fragment stage:
Shader version: 450 Shader version: 450
gl_FragCoord origin is upper left gl_FragCoord origin is upper left
0:? Sequence 0:? Sequence
0:2 Function Definition: PixelShaderFunction(vf4; (global 4-component vector of float) 0:2 Function Definition: PixelShaderFunction(vf4; (global void)
0:2 Function Parameters: 0:2 Function Parameters:
0:2 'input' (layout(location=0 ) in 4-component vector of float) 0:2 'input' (layout(location=0 ) in 4-component vector of float)
0:? Sequence 0:? Sequence

View File

@ -6,12 +6,13 @@ gl_FragCoord origin is upper left
0:1 Function Parameters: 0:1 Function Parameters:
0:2 Function Definition: foo2( (global void) 0:2 Function Definition: foo2( (global void)
0:2 Function Parameters: 0:2 Function Parameters:
0:5 Function Definition: PixelShaderFunction(vf4; (global 4-component vector of float) 0:5 Function Definition: PixelShaderFunction(vf4; (global void)
0:5 Function Parameters: 0:5 Function Parameters:
0:5 'input' (layout(location=0 ) in 4-component vector of float) 0:5 'input' (layout(location=0 ) in 4-component vector of float)
0:? Sequence 0:? Sequence
0:6 Function Call: foo1( (global void) 0:6 Function Call: foo1( (global void)
0:7 Function Call: foo2( (global void) 0:7 Function Call: foo2( (global void)
0:8 Branch: Return
0:? Linker Objects 0:? Linker Objects
@ -25,17 +26,18 @@ gl_FragCoord origin is upper left
0:1 Function Parameters: 0:1 Function Parameters:
0:2 Function Definition: foo2( (global void) 0:2 Function Definition: foo2( (global void)
0:2 Function Parameters: 0:2 Function Parameters:
0:5 Function Definition: PixelShaderFunction(vf4; (global 4-component vector of float) 0:5 Function Definition: PixelShaderFunction(vf4; (global void)
0:5 Function Parameters: 0:5 Function Parameters:
0:5 'input' (layout(location=0 ) in 4-component vector of float) 0:5 'input' (layout(location=0 ) in 4-component vector of float)
0:? Sequence 0:? Sequence
0:6 Function Call: foo1( (global void) 0:6 Function Call: foo1( (global void)
0:7 Function Call: foo2( (global void) 0:7 Function Call: foo2( (global void)
0:8 Branch: Return
0:? Linker Objects 0:? Linker Objects
// Module Version 10000 // Module Version 10000
// Generated by (magic number): 80001 // Generated by (magic number): 80001
// Id's are bound by 12 // Id's are bound by 13
Capability Shader Capability Shader
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"

View File

@ -1,4 +1,4 @@
float4 PixelShaderFunction(float4 input) : COLOR0 void PixelShaderFunction(float4 input) : COLOR0
{ {
[unroll]; [unroll];
[]; [];

View File

@ -4,7 +4,7 @@ void foo(float f)
discard; discard;
} }
float4 PixelShaderFunction(float4 input) : COLOR0 void PixelShaderFunction(float4 input) : COLOR0
{ {
foo(input.z); foo(input.z);
if (input.x) if (input.x)

View File

@ -7,4 +7,5 @@ int4x4 int44;
float1 ShaderFunction(float1 inFloat1, float inScalar) : COLOR0 float1 ShaderFunction(float1 inFloat1, float inScalar) : COLOR0
{ {
return inFloat1;
} }

View File

@ -1,4 +1,4 @@
float4 PixelShaderFunction(float4 input) : COLOR0 void PixelShaderFunction(float4 input) : COLOR0
{ {
int x; int x;
x; x;

View File

@ -1,8 +1,9 @@
void foo1() {} void foo1() {}
void foo2(void) {} void foo2(void) {}
float4 PixelShaderFunction(float4 input) : COLOR0 void PixelShaderFunction(float4 input) : COLOR0
{ {
foo1(); foo1();
foo2(); foo2();
return;
} }

View File

@ -2,5 +2,5 @@
// For the version, it uses the latest git tag followed by the number of commits. // For the version, it uses the latest git tag followed by the number of commits.
// For the date, it uses the current date (when then script is run). // For the date, it uses the current date (when then script is run).
#define GLSLANG_REVISION "Overload400-PrecQual.1460" #define GLSLANG_REVISION "Overload400-PrecQual.1461"
#define GLSLANG_DATE "02-Sep-2016" #define GLSLANG_DATE "02-Sep-2016"

View File

@ -1036,7 +1036,7 @@ TIntermAggregate* TParseContext::handleFunctionDefinition(const TSourceLoc& loc,
error(loc, "can't find function", function.getName().c_str(), ""); error(loc, "can't find function", function.getName().c_str(), "");
// Note: 'prevDec' could be 'function' if this is the first time we've seen function // Note: 'prevDec' could be 'function' if this is the first time we've seen function
// as it would have just been put in the symbol table. Otherwise, we're looking up // as it would have just been put in the symbol table. Otherwise, we're looking up
// an earlier occurance. // an earlier occurrence.
if (prevDec && prevDec->isDefined()) { if (prevDec && prevDec->isDefined()) {
// Then this function already has a body. // Then this function already has a body.

View File

@ -1496,20 +1496,16 @@ bool HlslGrammar::acceptParameterDeclaration(TFunction& function)
// parsing the body (compound_statement). // parsing the body (compound_statement).
bool HlslGrammar::acceptFunctionDefinition(TFunction& function, TIntermNode*& node) bool HlslGrammar::acceptFunctionDefinition(TFunction& function, TIntermNode*& node)
{ {
TFunction* functionDeclarator = parseContext.handleFunctionDeclarator(token.loc, function, false /* not prototype */); TFunction& functionDeclarator = parseContext.handleFunctionDeclarator(token.loc, function, false /* not prototype */);
TSourceLoc loc = token.loc; TSourceLoc loc = token.loc;
// This does a pushScope() // This does a pushScope()
node = parseContext.handleFunctionDefinition(loc, *functionDeclarator); node = parseContext.handleFunctionDefinition(loc, functionDeclarator);
// compound_statement // compound_statement
TIntermNode* functionBody = nullptr; TIntermNode* functionBody = nullptr;
if (acceptCompoundStatement(functionBody)) { if (acceptCompoundStatement(functionBody)) {
node = intermediate.growAggregate(node, functionBody); parseContext.handleFunctionBody(loc, functionDeclarator, functionBody, node);
intermediate.setAggregateOperator(node, EOpFunction, functionDeclarator->getType(), loc);
node->getAsAggregate()->setName(functionDeclarator->getMangledName().c_str());
parseContext.popScope();
return true; return true;
} }

View File

@ -686,7 +686,7 @@ TIntermTyped* HlslParseContext::handleDotDereference(const TSourceLoc& loc, TInt
// Handle seeing a function declarator in the grammar. This is the precursor // Handle seeing a function declarator in the grammar. This is the precursor
// to recognizing a function prototype or function definition. // to recognizing a function prototype or function definition.
// //
TFunction* HlslParseContext::handleFunctionDeclarator(const TSourceLoc& loc, TFunction& function, bool prototype) TFunction& HlslParseContext::handleFunctionDeclarator(const TSourceLoc& loc, TFunction& function, bool prototype)
{ {
// //
// Multiple declarations of the same function name are allowed. // Multiple declarations of the same function name are allowed.
@ -720,7 +720,7 @@ TFunction* HlslParseContext::handleFunctionDeclarator(const TSourceLoc& loc, TFu
// in which case, we need to use the parameter names from this one, and not the one that's // in which case, we need to use the parameter names from this one, and not the one that's
// being redeclared. So, pass back this declaration, not the one in the symbol table. // being redeclared. So, pass back this declaration, not the one in the symbol table.
// //
return &function; return function;
} }
// //
@ -798,6 +798,18 @@ TIntermAggregate* HlslParseContext::handleFunctionDefinition(const TSourceLoc& l
return paramNodes; return paramNodes;
} }
void HlslParseContext::handleFunctionBody(const TSourceLoc& loc, TFunction& function, TIntermNode* functionBody, TIntermNode*& node)
{
node = intermediate.growAggregate(node, functionBody);
intermediate.setAggregateOperator(node, EOpFunction, function.getType(), loc);
node->getAsAggregate()->setName(function.getMangledName().c_str());
popScope();
if (function.getType().getBasicType() != EbtVoid && ! functionReturnsValue)
error(loc, "function does not return a value:", "", function.getName().c_str());
}
// AST I/O is done through shader globals declared in the 'in' or 'out' // AST I/O is done through shader globals declared in the 'in' or 'out'
// storage class. An HLSL entry point has a return value, input parameters // storage class. An HLSL entry point has a return value, input parameters
// and output parameters. These need to get remapped to the AST I/O. // and output parameters. These need to get remapped to the AST I/O.
@ -839,6 +851,7 @@ void HlslParseContext::remapEntrypointIO(TFunction& function)
// if necessary. // if necessary.
TIntermNode* HlslParseContext::handleReturnValue(const TSourceLoc& loc, TIntermTyped* value) TIntermNode* HlslParseContext::handleReturnValue(const TSourceLoc& loc, TIntermTyped* value)
{ {
functionReturnsValue = true;
TIntermTyped* converted = value; TIntermTyped* converted = value;
if (currentFunctionType->getBasicType() == EbtVoid) { if (currentFunctionType->getBasicType() == EbtVoid) {

View File

@ -83,8 +83,9 @@ public:
TIntermTyped* handleBinaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right); TIntermTyped* handleBinaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right);
TIntermTyped* handleUnaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* childNode); TIntermTyped* handleUnaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* childNode);
TIntermTyped* handleDotDereference(const TSourceLoc&, TIntermTyped* base, const TString& field); TIntermTyped* handleDotDereference(const TSourceLoc&, TIntermTyped* base, const TString& field);
TFunction* handleFunctionDeclarator(const TSourceLoc&, TFunction& function, bool prototype); TFunction& handleFunctionDeclarator(const TSourceLoc&, TFunction& function, bool prototype);
TIntermAggregate* handleFunctionDefinition(const TSourceLoc&, TFunction&); TIntermAggregate* handleFunctionDefinition(const TSourceLoc&, TFunction&);
void handleFunctionBody(const TSourceLoc&, TFunction&, TIntermNode* functionBody, TIntermNode*& node);
void remapEntrypointIO(TFunction& function); void remapEntrypointIO(TFunction& function);
TIntermNode* handleReturnValue(const TSourceLoc&, TIntermTyped*); TIntermNode* handleReturnValue(const TSourceLoc&, TIntermTyped*);
void handleFunctionArgument(TFunction*, TIntermTyped*& arguments, TIntermTyped* newArg); void handleFunctionArgument(TFunction*, TIntermTyped*& arguments, TIntermTyped* newArg);