Fix crash on bad structure member reference

Fixes #3105
This commit is contained in:
Greg Fischer 2023-01-10 18:50:18 -07:00
parent 06a7078ce7
commit 9b67d41b85
4 changed files with 66 additions and 6 deletions

View File

@ -0,0 +1,37 @@
struct.error.frag
ERROR: 0:12: 'z' : no such field in structure
ERROR: 1 compilation errors. No code generated.
Shader version: 460
ERROR: node is still EOpNull!
0:7 Function Definition: test( ( global structure{ global float x})
0:7 Function Parameters:
0:8 Sequence
0:8 Branch: Return with expression
0:8 Constant:
0:8 1.000000
0:11 Function Definition: main( ( global void)
0:11 Function Parameters:
0:12 Sequence
0:12 Function Call: test( ( global structure{ global float x})
0:? Linker Objects
Linked fragment stage:
Shader version: 460
ERROR: node is still EOpNull!
0:7 Function Definition: test( ( global structure{ global float x})
0:7 Function Parameters:
0:8 Sequence
0:8 Branch: Return with expression
0:8 Constant:
0:8 1.000000
0:11 Function Definition: main( ( global void)
0:11 Function Parameters:
0:12 Sequence
0:12 Function Call: test( ( global structure{ global float x})
0:? Linker Objects

14
Test/struct.error.frag Normal file
View File

@ -0,0 +1,14 @@
#version 460
struct A {
float x;
};
A test() {
return A(1.0);
}
void main() {
test().z; // A.z does not exist, causes a crash
}

View File

@ -1035,14 +1035,22 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm
inheritMemoryQualifiers(base->getQualifier(), result->getWritableType().getQualifier());
} else {
auto baseSymbol = base;
while (baseSymbol->getAsSymbolNode() == nullptr)
baseSymbol = baseSymbol->getAsBinaryNode()->getLeft();
TString structName;
structName.append("\'").append(baseSymbol->getAsSymbolNode()->getName().c_str()).append( "\'");
error(loc, "no such field in structure", field.c_str(), structName.c_str());
while (baseSymbol->getAsSymbolNode() == nullptr) {
auto binaryNode = baseSymbol->getAsBinaryNode();
if (binaryNode == nullptr) break;
baseSymbol = binaryNode->getLeft();
}
if (baseSymbol->getAsSymbolNode() != nullptr) {
TString structName;
structName.append("\'").append(baseSymbol->getAsSymbolNode()->getName().c_str()).append("\'");
error(loc, "no such field in structure", field.c_str(), structName.c_str());
} else {
error(loc, "no such field in structure", field.c_str(), "");
}
}
} else
error(loc, "does not apply to this type:", field.c_str(), base->getType().getCompleteString(intermediate.getEnhancedMsgs()).c_str());
error(loc, "does not apply to this type:", field.c_str(),
base->getType().getCompleteString(intermediate.getEnhancedMsgs()).c_str());
// Propagate noContraction up the dereference chain
if (base->getQualifier().isNoContraction())

View File

@ -211,6 +211,7 @@ INSTANTIATE_TEST_SUITE_P(
"runtimeArray.vert",
"simpleFunctionCall.frag",
"stringToDouble.vert",
"struct.error.frag",
"structAssignment.frag",
"structDeref.frag",
"structure.frag",