diff options
author | Greg Fischer <greg@lunarg.com> | 2023-01-10 18:50:18 -0700 |
---|---|---|
committer | Greg Fischer <greg@lunarg.com> | 2023-01-11 16:53:39 -0700 |
commit | 9b67d41b8521e6db57192fff1e91b9c131ded4ef (patch) | |
tree | eb7973ea8406bd6e91a6e1ecc1e3119fc66b0887 | |
parent | 06a7078ce74ab5c7801a165b8145859678831fb8 (diff) | |
download | glslang-9b67d41b8521e6db57192fff1e91b9c131ded4ef.tar.gz |
Fix crash on bad structure member reference
Fixes #3105
-rw-r--r-- | Test/baseResults/struct.error.frag.out | 37 | ||||
-rw-r--r-- | Test/struct.error.frag | 14 | ||||
-rw-r--r-- | glslang/MachineIndependent/ParseHelper.cpp | 20 | ||||
-rw-r--r-- | gtests/AST.FromFile.cpp | 1 |
4 files changed, 66 insertions, 6 deletions
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", |