Issue 32: Guard against constructors consuming unsized arrays.
This commit is contained in:
parent
f498400945
commit
12a383379c
@ -101,4 +101,6 @@ void foo3()
|
|||||||
resize2[5] = 4.0; // ERROR
|
resize2[5] = 4.0; // ERROR
|
||||||
}
|
}
|
||||||
|
|
||||||
int[] i = int[](); // ERROR, need constructor arguments
|
int[] i = int[](); // ERROR, need constructor arguments
|
||||||
|
float emptyA[];
|
||||||
|
float b = vec4(emptyA); // ERROR, array can't be a constructor argument
|
||||||
|
|||||||
@ -24,7 +24,8 @@ ERROR: 0:93: 'length' : array must be declared with a size before using this me
|
|||||||
ERROR: 0:101: '[' : array index out of range '5'
|
ERROR: 0:101: '[' : array index out of range '5'
|
||||||
ERROR: 0:104: 'constructor' : array constructor must have at least one argument
|
ERROR: 0:104: 'constructor' : array constructor must have at least one argument
|
||||||
ERROR: 0:104: '=' : cannot convert from 'const float' to 'global implicitly-sized array of int'
|
ERROR: 0:104: '=' : cannot convert from 'const float' to 'global implicitly-sized array of int'
|
||||||
ERROR: 25 compilation errors. No code generated.
|
ERROR: 0:106: 'constructor' : array argument must be sized
|
||||||
|
ERROR: 26 compilation errors. No code generated.
|
||||||
|
|
||||||
|
|
||||||
Shader version: 130
|
Shader version: 130
|
||||||
@ -258,6 +259,11 @@ ERROR: node is still EOpNull!
|
|||||||
0:101 5 (const int)
|
0:101 5 (const int)
|
||||||
0:101 Constant:
|
0:101 Constant:
|
||||||
0:101 4.000000
|
0:101 4.000000
|
||||||
|
0:106 Sequence
|
||||||
|
0:106 move second child to first child (temp float)
|
||||||
|
0:106 'b' (global float)
|
||||||
|
0:106 Constant:
|
||||||
|
0:106 0.000000
|
||||||
0:? Linker Objects
|
0:? Linker Objects
|
||||||
0:? 'gu' (global implicitly-sized array of float)
|
0:? 'gu' (global implicitly-sized array of float)
|
||||||
0:? 'g4' (global 4-element array of float)
|
0:? 'g4' (global 4-element array of float)
|
||||||
@ -267,6 +273,8 @@ ERROR: node is still EOpNull!
|
|||||||
0:? 'f' (global float)
|
0:? 'f' (global float)
|
||||||
0:? 'gUnusedUnsized' (global implicitly-sized array of float)
|
0:? 'gUnusedUnsized' (global implicitly-sized array of float)
|
||||||
0:? 'i' (global implicitly-sized array of int)
|
0:? 'i' (global implicitly-sized array of int)
|
||||||
|
0:? 'emptyA' (global implicitly-sized array of float)
|
||||||
|
0:? 'b' (global float)
|
||||||
|
|
||||||
|
|
||||||
Linked fragment stage:
|
Linked fragment stage:
|
||||||
@ -503,6 +511,11 @@ ERROR: node is still EOpNull!
|
|||||||
0:101 5 (const int)
|
0:101 5 (const int)
|
||||||
0:101 Constant:
|
0:101 Constant:
|
||||||
0:101 4.000000
|
0:101 4.000000
|
||||||
|
0:106 Sequence
|
||||||
|
0:106 move second child to first child (temp float)
|
||||||
|
0:106 'b' (global float)
|
||||||
|
0:106 Constant:
|
||||||
|
0:106 0.000000
|
||||||
0:? Linker Objects
|
0:? Linker Objects
|
||||||
0:? 'gu' (global 4-element array of float)
|
0:? 'gu' (global 4-element array of float)
|
||||||
0:? 'g4' (global 4-element array of float)
|
0:? 'g4' (global 4-element array of float)
|
||||||
@ -512,4 +525,6 @@ ERROR: node is still EOpNull!
|
|||||||
0:? 'f' (global float)
|
0:? 'f' (global float)
|
||||||
0:? 'gUnusedUnsized' (global 1-element array of float)
|
0:? 'gUnusedUnsized' (global 1-element array of float)
|
||||||
0:? 'i' (global 1-element array of int)
|
0:? 'i' (global 1-element array of int)
|
||||||
|
0:? 'emptyA' (global 1-element array of float)
|
||||||
|
0:? 'b' (global float)
|
||||||
|
|
||||||
|
|||||||
@ -1947,9 +1947,7 @@ bool TParseContext::constructorError(TSourceLoc loc, TIntermNode* node, TFunctio
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Note: It's okay to have too many components available, but not okay to have unused
|
// Walk the arguments for first-pass checks and collection of information.
|
||||||
// arguments. 'full' will go to true when enough args have been seen. If we loop
|
|
||||||
// again, there is an extra argument, so 'overfull' will become true.
|
|
||||||
//
|
//
|
||||||
|
|
||||||
int size = 0;
|
int size = 0;
|
||||||
@ -1958,19 +1956,32 @@ bool TParseContext::constructorError(TSourceLoc loc, TIntermNode* node, TFunctio
|
|||||||
bool overFull = false;
|
bool overFull = false;
|
||||||
bool matrixInMatrix = false;
|
bool matrixInMatrix = false;
|
||||||
bool arrayArg = false;
|
bool arrayArg = false;
|
||||||
for (int i = 0; i < function.getParamCount(); ++i) {
|
for (int arg = 0; arg < function.getParamCount(); ++arg) {
|
||||||
size += function[i].type->computeNumComponents();
|
if (function[arg].type->isArray()) {
|
||||||
|
if (! function[arg].type->isExplicitlySizedArray()) {
|
||||||
if (constructingMatrix && function[i].type->isMatrix())
|
// Can't construct from an unsized array.
|
||||||
|
error(loc, "array argument must be sized", "constructor", "");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
arrayArg = true;
|
||||||
|
}
|
||||||
|
if (constructingMatrix && function[arg].type->isMatrix())
|
||||||
matrixInMatrix = true;
|
matrixInMatrix = true;
|
||||||
if (full)
|
|
||||||
|
// 'full' will go to true when enough args have been seen. If we loop
|
||||||
|
// again, there is an extra argument.
|
||||||
|
if (full) {
|
||||||
|
// For vectors and matrices, it's okay to have too many components
|
||||||
|
// available, but not okay to have unused arguments.
|
||||||
overFull = true;
|
overFull = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
size += function[arg].type->computeNumComponents();
|
||||||
if (op != EOpConstructStruct && ! type.isArray() && size >= type.computeNumComponents())
|
if (op != EOpConstructStruct && ! type.isArray() && size >= type.computeNumComponents())
|
||||||
full = true;
|
full = true;
|
||||||
if (function[i].type->getQualifier().storage != EvqConst)
|
|
||||||
|
if (function[arg].type->getQualifier().storage != EvqConst)
|
||||||
constType = false;
|
constType = false;
|
||||||
if (function[i].type->isArray())
|
|
||||||
arrayArg = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (constType)
|
if (constType)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user