GLSL/SPV: Fix #1900: Drop const on literal when doing an object copy.
authorJohn Kessenich <cepheus@frii.com>
Fri, 20 Sep 2019 12:01:42 +0000 (06:01 -0600)
committerJohn Kessenich <cepheus@frii.com>
Fri, 20 Sep 2019 12:08:49 +0000 (06:08 -0600)
Test/baseResults/nonuniform.frag.out
Test/nonuniform.frag
glslang/MachineIndependent/ParseHelper.cpp

index 0df8cfc..9054c2c 100644 (file)
@@ -40,6 +40,13 @@ ERROR: node is still EOpNull!
 0:27                2 (const int)
 0:28      'nu_li' ( nonuniform temp int)
 0:29      'nu_li' ( nonuniform temp int)
+0:30      move second child to first child ( temp int)
+0:30        'nu_li' ( nonuniform temp int)
+0:30        indirect index ( nonuniform temp int)
+0:30          'table' ( temp 5-element array of int)
+0:30          copy object ( nonuniform temp int)
+0:30            Constant:
+0:30              3 (const int)
 0:?   Linker Objects
 0:?     'nonuniformEXT' ( global int)
 0:?     'nu_inv4' ( smooth nonuniform in 4-component vector of float)
@@ -83,6 +90,13 @@ ERROR: node is still EOpNull!
 0:27                2 (const int)
 0:28      'nu_li' ( nonuniform temp int)
 0:29      'nu_li' ( nonuniform temp int)
+0:30      move second child to first child ( temp int)
+0:30        'nu_li' ( nonuniform temp int)
+0:30        indirect index ( nonuniform temp int)
+0:30          'table' ( temp 5-element array of int)
+0:30          copy object ( nonuniform temp int)
+0:30            Constant:
+0:30              3 (const int)
 0:?   Linker Objects
 0:?     'nonuniformEXT' ( global int)
 0:?     'nu_inv4' ( smooth nonuniform in 4-component vector of float)
index 3f3dd67..e98aacc 100644 (file)
@@ -22,12 +22,12 @@ void main()
     nonuniformEXT const int nu_ci = 2; // ERROR, const\r
 \r
     foo(nu_li, nu_li);\r
-\r
+    int table[5];\r
     int a;\r
     nu_li = nonuniformEXT(a) + nonuniformEXT(a * 2);\r
     nu_li = nonuniformEXT(a, a);       // ERROR, too many arguments\r
     nu_li = nonuniformEXT();           // ERROR, no arguments\r
+    nu_li = table[nonuniformEXT(3)];\r
 }\r
-\r
 layout(location=1) in struct S { float a; nonuniformEXT float b; } ins;  // ERROR, not on member\r
 layout(location=3) in inbName { float a; nonuniformEXT float b; } inb;   // ERROR, not on member\r
index 17b6fe8..b5ea803 100644 (file)
@@ -2774,10 +2774,25 @@ bool TParseContext::builtInName(const TString& identifier)
 //
 bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, TFunction& function, TOperator op, TType& type)
 {
-    type.shallowCopy(function.getType());
+    // See if the constructor does not establish the main type, only requalifies
+    // it, in which case the type comes from the argument instead of from the
+    // constructor function.
+    switch (op) {
+    case EOpConstructNonuniform:
+        if (node != nullptr && node->getAsTyped() != nullptr) {
+            type.shallowCopy(node->getAsTyped()->getType());
+            type.getQualifier().makeTemporary();
+            type.getQualifier().nonUniform = true;
+        }
+        break;
+    default:
+        type.shallowCopy(function.getType());
+        break;
+    }
 
+    // See if it's a matrix
     bool constructingMatrix = false;
-    switch(op) {
+    switch (op) {
 #ifndef GLSLANG_WEB
     case EOpConstructTextureSampler:
         return constructorTextureSamplerError(loc, function);
@@ -2871,6 +2886,8 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
             }
         }
     }
+    if (op == EOpConstructNonuniform)
+        constType = false;
 
 #ifndef GLSLANG_WEB
     switch (op) {
@@ -7093,8 +7110,7 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T
 
     case EOpConstructNonuniform:
         // Make a nonuniform copy of node
-        newNode = intermediate.addBuiltInFunctionCall(node->getLoc(), EOpCopyObject, true, node, node->getType());
-        newNode->getWritableType().getQualifier().nonUniform = true;
+        newNode = intermediate.addBuiltInFunctionCall(node->getLoc(), EOpCopyObject, true, node, type);
         return newNode;
 
     case EOpConstructReference: