HLSL: Handle const with no initializer. Fixes issue #651.
authorJohn Kessenich <cepheus@frii.com>
Fri, 30 Dec 2016 23:42:57 +0000 (16:42 -0700)
committerJohn Kessenich <cepheus@frii.com>
Fri, 30 Dec 2016 23:42:57 +0000 (16:42 -0700)
Test/baseResults/hlsl.partialInit.frag.out
Test/hlsl.partialInit.frag
glslang/MachineIndependent/ParseHelper.cpp
hlsl/hlslParseHelper.cpp
hlsl/hlslParseHelper.h

index 146af56..e0bda0e 100755 (executable)
@@ -1,4 +1,7 @@
 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
 gl_FragCoord origin is upper left
 0:? Sequence
@@ -175,6 +178,15 @@ gl_FragCoord origin is upper left
 0:?     'input' (layout(location=0 ) in 4-component vector of float)
 0:?     'gv' (global 4-component vector 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:
@@ -356,10 +368,19 @@ gl_FragCoord origin is upper left
 0:?     'input' (layout(location=0 ) in 4-component vector of float)
 0:?     'gv' (global 4-component vector 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
 // Generated by (magic number): 80001
-// Id's are bound by 90
+// Id's are bound by 92
 
                               Capability Shader
                1:             ExtInstImport  "GLSL.std.450"
@@ -451,6 +472,8 @@ gl_FragCoord origin is upper left
            84(v):     83(ptr) Variable Output
               88:             TypePointer Input 7(fvec4)
        89(input):     88(ptr) Variable Input
+              90:             TypeArray 53(fvec2) 14
+              91:          90 ConstantComposite 58 58 58
 4(PixelShaderFunction):           2 Function None 3
                5:             Label
           23(o2):     22(ptr) Variable Function
index d47751f..01aee8e 100755 (executable)
@@ -31,3 +31,6 @@ outs PixelShaderFunction(float4 input) : COLOR0
 \r
     return o4;\r
 }\r
+\r
+static const float2 cgf2a[3];\r
+static const int ci;\r
index 67bb883..bf59b81 100644 (file)
@@ -3255,7 +3255,7 @@ bool TParseContext::lineDirectiveShouldSetNextLine() const
 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 ||
         type.getQualifier().storage == EvqConstReadOnly) {
@@ -5007,7 +5007,7 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden
     if (voidErrorCheck(loc, identifier, type.getBasicType()))
         return nullptr;
 
-    if (initializer)        
+    if (initializer)
         rValueErrorCheck(loc, "initializer", initializer);
     else
         nonInitConstCheck(loc, identifier, type);
index a92ad4c..893cbfc 100755 (executable)
@@ -3893,6 +3893,23 @@ void HlslParseContext::updateImplicitArraySize(const TSourceLoc& loc, TIntermNod
 }
 
 //
+// 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,
 // copy the symbol table's read-only built-in variable to the current
 // global level, where it can be modified based on the passed in type.
@@ -4736,6 +4753,9 @@ TIntermNode* HlslParseContext::declareVariable(const TSourceLoc& loc, TString& i
     if (voidErrorCheck(loc, identifier, type.getBasicType()))
         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
     TSymbol* symbol = nullptr;
 
index d017a2a..127dc27 100755 (executable)
@@ -183,6 +183,7 @@ protected:
         int                 nextBinding; // next binding to use.
     };
 
+    void fixConstInit(const TSourceLoc&, TString& identifier, TType& type, TIntermTyped*& initializer);
     void inheritGlobalDefaults(TQualifier& dst) const;
     TVariable* makeInternalVariable(const char* name, const TType&) const;
     TVariable* declareNonArray(const TSourceLoc&, TString& identifier, TType&, bool track);