From 78fe3ace85c177e4b5a1572139dcc699aa503975 Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Mon, 2 Dec 2013 16:38:53 +0000 Subject: [PATCH] Fix crash from attempting ES precision propagation through a constant folded built-in function call when the expression tree has unknown precisions. git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@24267 e7fa87d3-cd2b-0410-9028-fcbf551c1848 --- Test/300.frag | 6 +++++ Test/baseResults/300.frag.out | 16 +++++++++++-- glslang/MachineIndependent/Intermediate.cpp | 25 ++++++++++++--------- 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/Test/300.frag b/Test/300.frag index e8efb4e1..6fa7e336 100644 --- a/Test/300.frag +++ b/Test/300.frag @@ -129,5 +129,11 @@ void foo23() textureOffset(s2DShadow, c3D, ivec2(-9, 8), c1D); } +void foo324(void) +{ + float p = pow(3.2, 4.6); + p += sin(0.4); +} + float imageBuffer; // ERROR, reserved float uimage2DRect; // ERROR, reserved diff --git a/Test/baseResults/300.frag.out b/Test/baseResults/300.frag.out index bada84d8..11567cab 100644 --- a/Test/baseResults/300.frag.out +++ b/Test/baseResults/300.frag.out @@ -33,8 +33,8 @@ ERROR: 0:122: '=' : can't use with samplers or structs containing samplers ERROR: 0:123: '==' : can't use with samplers or structs containing samplers ERROR: 0:129: 'texel offset' : value is out of range: [gl_MinProgramTexelOffset, gl_MaxProgramTexelOffset] ERROR: 0:129: 'texel offset' : value is out of range: [gl_MinProgramTexelOffset, gl_MaxProgramTexelOffset] -ERROR: 0:132: 'imageBuffer' : Reserved word. -ERROR: 0:132: '' : syntax error +ERROR: 0:138: 'imageBuffer' : Reserved word. +ERROR: 0:138: '' : syntax error ERROR: 36 compilation errors. No code generated. @@ -280,6 +280,18 @@ ERROR: node is still EOpNull! 0:129 -9 (const int) 0:129 8 (const int) 0:129 'c1D' (smooth in lowp float) +0:132 Function Definition: foo324( (void) +0:132 Function Parameters: +0:134 Sequence +0:134 Sequence +0:134 move second child to first child (lowp float) +0:134 'p' (lowp float) +0:134 Constant: +0:134 210.712306 +0:135 add second child into first child (lowp float) +0:135 'p' (lowp float) +0:135 Constant: +0:135 0.389418 0:? Linker Objects 0:? 's2D' (uniform lowp sampler2D) 0:? 's3D' (uniform lowp sampler3D) diff --git a/glslang/MachineIndependent/Intermediate.cpp b/glslang/MachineIndependent/Intermediate.cpp index 41f5ea58..eaa070ee 100644 --- a/glslang/MachineIndependent/Intermediate.cpp +++ b/glslang/MachineIndependent/Intermediate.cpp @@ -299,18 +299,21 @@ TIntermTyped* TIntermediate::addBuiltInFunctionCall(TSourceLoc loc, TOperator op // setAggregateOperater() calls fold() for constant folding TIntermTyped* node = setAggregateOperator(childNode, op, returnType, loc); - TPrecisionQualifier correctPrecision = returnType.getQualifier().precision; - if (correctPrecision == EpqNone && profile == EEsProfile) { - // find the maximum precision from the arguments, for the built-in's return precision - TIntermSequence& sequence = node->getAsAggregate()->getSequence(); - for (unsigned int arg = 0; arg < sequence.size(); ++arg) - correctPrecision = std::max(correctPrecision, sequence[arg]->getAsTyped()->getQualifier().precision); - } + // if not folded, we'll still have an aggregate node to propagate precision with + if (node->getAsAggregate()) { + TPrecisionQualifier correctPrecision = returnType.getQualifier().precision; + if (correctPrecision == EpqNone && profile == EEsProfile) { + // find the maximum precision from the arguments, for the built-in's return precision + TIntermSequence& sequence = node->getAsAggregate()->getSequence(); + for (unsigned int arg = 0; arg < sequence.size(); ++arg) + correctPrecision = std::max(correctPrecision, sequence[arg]->getAsTyped()->getQualifier().precision); + } - // Propagate precision through this node and its children. That algorithm stops - // when a precision is found, so start by clearing this subroot precision - node->getQualifier().precision = EpqNone; - node->propagatePrecision(correctPrecision); + // Propagate precision through this node and its children. That algorithm stops + // when a precision is found, so start by clearing this subroot precision + node->getQualifier().precision = EpqNone; + node->propagatePrecision(correctPrecision); + } return node; }