HLSL: Handle const with no initializer. Fixes issue #651.

This commit is contained in:
John Kessenich 2016-12-30 16:42:57 -07:00
parent 53864846a9
commit aa6d56298d
5 changed files with 50 additions and 3 deletions

View File

@ -1,4 +1,7 @@
hlsl.partialInit.frag hlsl.partialInit.frag
WARNING: 0:35: 'cgf2a' : variable with qualifier 'const' not initialized; zero initializing
WARNING: 0:36: 'ci' : variable with qualifier 'const' not initialized; zero initializing
Shader version: 450 Shader version: 450
gl_FragCoord origin is upper left gl_FragCoord origin is upper left
0:? Sequence 0:? Sequence
@ -175,6 +178,15 @@ gl_FragCoord origin is upper left
0:? 'input' (layout(location=0 ) in 4-component vector of float) 0:? 'input' (layout(location=0 ) in 4-component vector of float)
0:? 'gv' (global 4-component vector of float) 0:? 'gv' (global 4-component vector of float)
0:? 'gfa' (global 3-element array of float) 0:? 'gfa' (global 3-element array of float)
0:? 'cgf2a' (const 3-element array of 2-component vector of float)
0:? 0.000000
0:? 0.000000
0:? 0.000000
0:? 0.000000
0:? 0.000000
0:? 0.000000
0:? 'ci' (const int)
0:? 0 (const int)
Linked fragment stage: Linked fragment stage:
@ -356,10 +368,19 @@ gl_FragCoord origin is upper left
0:? 'input' (layout(location=0 ) in 4-component vector of float) 0:? 'input' (layout(location=0 ) in 4-component vector of float)
0:? 'gv' (global 4-component vector of float) 0:? 'gv' (global 4-component vector of float)
0:? 'gfa' (global 3-element array of float) 0:? 'gfa' (global 3-element array of float)
0:? 'cgf2a' (const 3-element array of 2-component vector of float)
0:? 0.000000
0:? 0.000000
0:? 0.000000
0:? 0.000000
0:? 0.000000
0:? 0.000000
0:? 'ci' (const int)
0:? 0 (const int)
// Module Version 10000 // Module Version 10000
// Generated by (magic number): 80001 // Generated by (magic number): 80001
// Id's are bound by 90 // Id's are bound by 92
Capability Shader Capability Shader
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
@ -451,6 +472,8 @@ gl_FragCoord origin is upper left
84(v): 83(ptr) Variable Output 84(v): 83(ptr) Variable Output
88: TypePointer Input 7(fvec4) 88: TypePointer Input 7(fvec4)
89(input): 88(ptr) Variable Input 89(input): 88(ptr) Variable Input
90: TypeArray 53(fvec2) 14
91: 90 ConstantComposite 58 58 58
4(PixelShaderFunction): 2 Function None 3 4(PixelShaderFunction): 2 Function None 3
5: Label 5: Label
23(o2): 22(ptr) Variable Function 23(o2): 22(ptr) Variable Function

View File

@ -31,3 +31,6 @@ outs PixelShaderFunction(float4 input) : COLOR0
return o4; return o4;
} }
static const float2 cgf2a[3];
static const int ci;

View File

@ -3255,7 +3255,7 @@ bool TParseContext::lineDirectiveShouldSetNextLine() const
void TParseContext::nonInitConstCheck(const TSourceLoc& loc, TString& identifier, TType& type) void TParseContext::nonInitConstCheck(const TSourceLoc& loc, TString& identifier, TType& type)
{ {
// //
// Make the qualifier make sense, given that there is an initializer. // Make the qualifier make sense, given that there is not an initializer.
// //
if (type.getQualifier().storage == EvqConst || if (type.getQualifier().storage == EvqConst ||
type.getQualifier().storage == EvqConstReadOnly) { type.getQualifier().storage == EvqConstReadOnly) {
@ -5007,7 +5007,7 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden
if (voidErrorCheck(loc, identifier, type.getBasicType())) if (voidErrorCheck(loc, identifier, type.getBasicType()))
return nullptr; return nullptr;
if (initializer) if (initializer)
rValueErrorCheck(loc, "initializer", initializer); rValueErrorCheck(loc, "initializer", initializer);
else else
nonInitConstCheck(loc, identifier, type); nonInitConstCheck(loc, identifier, type);

View File

@ -3892,6 +3892,23 @@ void HlslParseContext::updateImplicitArraySize(const TSourceLoc& loc, TIntermNod
symbol->getWritableType().setImplicitArraySize(index + 1); symbol->getWritableType().setImplicitArraySize(index + 1);
} }
//
// Enforce non-initializer type/qualifier rules.
//
void HlslParseContext::fixConstInit(const TSourceLoc& loc, TString& identifier, TType& type, TIntermTyped*& initializer)
{
//
// Make the qualifier make sense, given that there is an initializer.
//
if (initializer == nullptr) {
if (type.getQualifier().storage == EvqConst ||
type.getQualifier().storage == EvqConstReadOnly) {
initializer = intermediate.makeAggregate(loc);
warn(loc, "variable with qualifier 'const' not initialized; zero initializing", identifier.c_str(), "");
}
}
}
// //
// See if the identifier is a built-in symbol that can be redeclared, and if so, // See if the identifier is a built-in symbol that can be redeclared, and if so,
// copy the symbol table's read-only built-in variable to the current // copy the symbol table's read-only built-in variable to the current
@ -4736,6 +4753,9 @@ TIntermNode* HlslParseContext::declareVariable(const TSourceLoc& loc, TString& i
if (voidErrorCheck(loc, identifier, type.getBasicType())) if (voidErrorCheck(loc, identifier, type.getBasicType()))
return nullptr; return nullptr;
// make const and initialization consistent
fixConstInit(loc, identifier, type, initializer);
// Check for redeclaration of built-ins and/or attempting to declare a reserved name // Check for redeclaration of built-ins and/or attempting to declare a reserved name
TSymbol* symbol = nullptr; TSymbol* symbol = nullptr;

View File

@ -183,6 +183,7 @@ protected:
int nextBinding; // next binding to use. int nextBinding; // next binding to use.
}; };
void fixConstInit(const TSourceLoc&, TString& identifier, TType& type, TIntermTyped*& initializer);
void inheritGlobalDefaults(TQualifier& dst) const; void inheritGlobalDefaults(TQualifier& dst) const;
TVariable* makeInternalVariable(const char* name, const TType&) const; TVariable* makeInternalVariable(const char* name, const TType&) const;
TVariable* declareNonArray(const TSourceLoc&, TString& identifier, TType&, bool track); TVariable* declareNonArray(const TSourceLoc&, TString& identifier, TType&, bool track);