From 9b67d41b8521e6db57192fff1e91b9c131ded4ef Mon Sep 17 00:00:00 2001 From: Greg Fischer Date: Tue, 10 Jan 2023 18:50:18 -0700 Subject: Fix crash on bad structure member reference Fixes #3105 --- Test/baseResults/struct.error.frag.out | 37 ++++++++++++++++++++++++++++++ Test/struct.error.frag | 14 +++++++++++ glslang/MachineIndependent/ParseHelper.cpp | 20 +++++++++++----- gtests/AST.FromFile.cpp | 1 + 4 files changed, 66 insertions(+), 6 deletions(-) create mode 100644 Test/baseResults/struct.error.frag.out create mode 100644 Test/struct.error.frag diff --git a/Test/baseResults/struct.error.frag.out b/Test/baseResults/struct.error.frag.out new file mode 100644 index 00000000..5b0993a1 --- /dev/null +++ b/Test/baseResults/struct.error.frag.out @@ -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 + diff --git a/Test/struct.error.frag b/Test/struct.error.frag new file mode 100644 index 00000000..29aba00b --- /dev/null +++ b/Test/struct.error.frag @@ -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 +} + diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index f86e78ba..515137b7 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -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()) diff --git a/gtests/AST.FromFile.cpp b/gtests/AST.FromFile.cpp index 81633f97..12e0137d 100644 --- a/gtests/AST.FromFile.cpp +++ b/gtests/AST.FromFile.cpp @@ -211,6 +211,7 @@ INSTANTIATE_TEST_SUITE_P( "runtimeArray.vert", "simpleFunctionCall.frag", "stringToDouble.vert", + "struct.error.frag", "structAssignment.frag", "structDeref.frag", "structure.frag", -- cgit v1.2.3