aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Fischer <greg@lunarg.com>2023-01-10 18:50:18 -0700
committerGreg Fischer <greg@lunarg.com>2023-01-11 16:53:39 -0700
commit9b67d41b8521e6db57192fff1e91b9c131ded4ef (patch)
treeeb7973ea8406bd6e91a6e1ecc1e3119fc66b0887
parent06a7078ce74ab5c7801a165b8145859678831fb8 (diff)
downloadglslang-9b67d41b8521e6db57192fff1e91b9c131ded4ef.tar.gz
Fix crash on bad structure member reference
Fixes #3105
-rw-r--r--Test/baseResults/struct.error.frag.out37
-rw-r--r--Test/struct.error.frag14
-rw-r--r--glslang/MachineIndependent/ParseHelper.cpp20
-rw-r--r--gtests/AST.FromFile.cpp1
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",