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
gl_FragCoord origin is upper left
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 'input' (layout(location=0 ) in 4-component vector of float)
0:? Sequence
@ -20,7 +20,7 @@ Linked fragment stage:
Shader version: 450
gl_FragCoord origin is upper left
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 'input' (layout(location=0 ) in 4-component vector of float)
0:? Sequence

View File

@ -14,7 +14,7 @@ gl_FragCoord origin is upper left
0:3 1.000000
0:3 true case
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 'input' (layout(location=0 ) in 4-component vector of float)
0:? Sequence
@ -60,7 +60,7 @@ gl_FragCoord origin is upper left
0:3 1.000000
0:3 true case
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 'input' (layout(location=0 ) in 4-component vector of float)
0:? Sequence

View File

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

View File

@ -2,7 +2,7 @@ hlsl.scope.frag
Shader version: 450
gl_FragCoord origin is upper left
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 'input' (layout(location=0 ) in 4-component vector of float)
0:? Sequence
@ -46,7 +46,7 @@ Linked fragment stage:
Shader version: 450
gl_FragCoord origin is upper left
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 'input' (layout(location=0 ) in 4-component vector of float)
0:? Sequence

View File

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

View File

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

View File

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

View File

@ -7,4 +7,5 @@ int4x4 int44;
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;
x;

View File

@ -1,8 +1,9 @@
void foo1() {}
void foo2(void) {}
float4 PixelShaderFunction(float4 input) : COLOR0
void PixelShaderFunction(float4 input) : COLOR0
{
foo1();
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 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"

View File

@ -1036,7 +1036,7 @@ TIntermAggregate* TParseContext::handleFunctionDefinition(const TSourceLoc& loc,
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
// 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()) {
// Then this function already has a body.

View File

@ -1496,20 +1496,16 @@ bool HlslGrammar::acceptParameterDeclaration(TFunction& function)
// parsing the body (compound_statement).
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;
// This does a pushScope()
node = parseContext.handleFunctionDefinition(loc, *functionDeclarator);
node = parseContext.handleFunctionDefinition(loc, functionDeclarator);
// compound_statement
TIntermNode* functionBody = nullptr;
if (acceptCompoundStatement(functionBody)) {
node = intermediate.growAggregate(node, functionBody);
intermediate.setAggregateOperator(node, EOpFunction, functionDeclarator->getType(), loc);
node->getAsAggregate()->setName(functionDeclarator->getMangledName().c_str());
parseContext.popScope();
parseContext.handleFunctionBody(loc, functionDeclarator, functionBody, node);
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
// 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.
@ -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
// 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;
}
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'
// 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.
@ -839,6 +851,7 @@ void HlslParseContext::remapEntrypointIO(TFunction& function)
// if necessary.
TIntermNode* HlslParseContext::handleReturnValue(const TSourceLoc& loc, TIntermTyped* value)
{
functionReturnsValue = true;
TIntermTyped* converted = value;
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* handleUnaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* childNode);
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&);
void handleFunctionBody(const TSourceLoc&, TFunction&, TIntermNode* functionBody, TIntermNode*& node);
void remapEntrypointIO(TFunction& function);
TIntermNode* handleReturnValue(const TSourceLoc&, TIntermTyped*);
void handleFunctionArgument(TFunction*, TIntermTyped*& arguments, TIntermTyped* newArg);