From 479132914528d9eba880f177651729cc4379919f Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 9 Jul 2013 15:55:07 -0400 Subject: Protect against integer overflows when generating index buffers for line loop and triangle fan drawing. Issue 444 Signed-off-by: Jamie Madil Signed-off-by: Shannon Woods Author: Geoff Lang --- src/libGLESv2/renderer/Renderer11.cpp | 27 ++++++++++++++++++++------- src/libGLESv2/renderer/Renderer9.cpp | 14 +++++++++++++- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/libGLESv2/renderer/Renderer11.cpp b/src/libGLESv2/renderer/Renderer11.cpp index 72885dd5..e544b40c 100644 --- a/src/libGLESv2/renderer/Renderer11.cpp +++ b/src/libGLESv2/renderer/Renderer11.cpp @@ -1130,7 +1130,13 @@ void Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, } } - const int spaceNeeded = (count + 1) * sizeof(unsigned int); + if (static_cast(count + 1) > (std::numeric_limits::max() / sizeof(unsigned int))) + { + ERR("Could not create a 32-bit looping index buffer for GL_LINE_LOOP, too many indices required."); + return gl::error(GL_OUT_OF_MEMORY); + } + + const unsigned int spaceNeeded = (count + 1) * sizeof(unsigned int); if (!mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT)) { ERR("Could not reserve enough space in looping index buffer for GL_LINE_LOOP."); @@ -1224,8 +1230,15 @@ void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indic } } - const int numTris = count - 2; - const int spaceNeeded = (numTris * 3) * sizeof(unsigned int); + const unsigned int numTris = count - 2; + + if (numTris * 3 > (std::numeric_limits::max() / sizeof(unsigned int))) + { + ERR("Could not create a scratch index buffer for GL_TRIANGLE_FAN, too many indices required."); + return gl::error(GL_OUT_OF_MEMORY); + } + + const unsigned int spaceNeeded = (numTris * 3) * sizeof(unsigned int); if (!mTriangleFanIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT)) { ERR("Could not reserve enough space in scratch index buffer for GL_TRIANGLE_FAN."); @@ -1246,7 +1259,7 @@ void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indic switch (type) { case GL_NONE: // Non-indexed draw - for (int i = 0; i < numTris; i++) + for (unsigned int i = 0; i < numTris; i++) { data[i*3 + 0] = 0; data[i*3 + 1] = i + 1; @@ -1254,7 +1267,7 @@ void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indic } break; case GL_UNSIGNED_BYTE: - for (int i = 0; i < numTris; i++) + for (unsigned int i = 0; i < numTris; i++) { data[i*3 + 0] = static_cast(indices)[0]; data[i*3 + 1] = static_cast(indices)[i + 1]; @@ -1262,7 +1275,7 @@ void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indic } break; case GL_UNSIGNED_SHORT: - for (int i = 0; i < numTris; i++) + for (unsigned int i = 0; i < numTris; i++) { data[i*3 + 0] = static_cast(indices)[0]; data[i*3 + 1] = static_cast(indices)[i + 1]; @@ -1270,7 +1283,7 @@ void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indic } break; case GL_UNSIGNED_INT: - for (int i = 0; i < numTris; i++) + for (unsigned int i = 0; i < numTris; i++) { data[i*3 + 0] = static_cast(indices)[0]; data[i*3 + 1] = static_cast(indices)[i + 1]; diff --git a/src/libGLESv2/renderer/Renderer9.cpp b/src/libGLESv2/renderer/Renderer9.cpp index 696bcca3..4aecd4ae 100644 --- a/src/libGLESv2/renderer/Renderer9.cpp +++ b/src/libGLESv2/renderer/Renderer9.cpp @@ -1471,7 +1471,13 @@ void Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, } } - const int spaceNeeded = (count + 1) * sizeof(unsigned int); + if (static_cast(count + 1) > (std::numeric_limits::max() / sizeof(unsigned int))) + { + ERR("Could not create a 32-bit looping index buffer for GL_LINE_LOOP, too many indices required."); + return gl::error(GL_OUT_OF_MEMORY); + } + + const unsigned int spaceNeeded = (count + 1) * sizeof(unsigned int); if (!mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT)) { ERR("Could not reserve enough space in looping index buffer for GL_LINE_LOOP."); @@ -1543,6 +1549,12 @@ void Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, } } + if (static_cast(count + 1) > (std::numeric_limits::max() / sizeof(unsigned short))) + { + ERR("Could not create a 16-bit looping index buffer for GL_LINE_LOOP, too many indices required."); + return gl::error(GL_OUT_OF_MEMORY); + } + const int spaceNeeded = (count + 1) * sizeof(unsigned short); if (!mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_SHORT)) { -- cgit v1.2.3 From 0c8b4e563e2926f37b5b357c1fafb7115d272e03 Mon Sep 17 00:00:00 2001 From: Geoff Lang Date: Tue, 9 Jul 2013 15:58:36 -0400 Subject: Protect against integer overflows in the VertexBuffer class by validating the reserved space. Issue 444 Signed-off-by: Jamie Madil Signed-off-by: Shannon Woods Author: Geoff Lang --- src/libGLESv2/renderer/VertexBuffer.cpp | 22 +++++++++++++++++++--- src/libGLESv2/renderer/VertexBuffer.h | 4 ++-- src/libGLESv2/renderer/VertexDataManager.cpp | 15 ++++++++++++--- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/libGLESv2/renderer/VertexBuffer.cpp b/src/libGLESv2/renderer/VertexBuffer.cpp index 16e14865..a8589465 100644 --- a/src/libGLESv2/renderer/VertexBuffer.cpp +++ b/src/libGLESv2/renderer/VertexBuffer.cpp @@ -125,14 +125,30 @@ int VertexBufferInterface::storeRawData(const void* data, unsigned int size) return oldWritePos; } -void VertexBufferInterface::reserveVertexSpace(const gl::VertexAttribute &attribute, GLsizei count, GLsizei instances) +bool VertexBufferInterface::reserveVertexSpace(const gl::VertexAttribute &attribute, GLsizei count, GLsizei instances) { - mReservedSpace += mVertexBuffer->getSpaceRequired(attribute, count, instances); + unsigned int requiredSpace = mVertexBuffer->getSpaceRequired(attribute, count, instances); + + // Protect against integer overflow + if (mReservedSpace + requiredSpace < mReservedSpace) + { + return false; + } + + mReservedSpace += requiredSpace; + return true; } -void VertexBufferInterface::reserveRawDataSpace(unsigned int size) +bool VertexBufferInterface::reserveRawDataSpace(unsigned int size) { + // Protect against integer overflow + if (mReservedSpace + size < mReservedSpace) + { + return false; + } + mReservedSpace += size; + return true; } VertexBuffer* VertexBufferInterface::getVertexBuffer() const diff --git a/src/libGLESv2/renderer/VertexBuffer.h b/src/libGLESv2/renderer/VertexBuffer.h index 6ecffd0c..c474b05c 100644 --- a/src/libGLESv2/renderer/VertexBuffer.h +++ b/src/libGLESv2/renderer/VertexBuffer.h @@ -60,8 +60,8 @@ class VertexBufferInterface VertexBufferInterface(rx::Renderer *renderer, bool dynamic); virtual ~VertexBufferInterface(); - void reserveVertexSpace(const gl::VertexAttribute &attribute, GLsizei count, GLsizei instances); - void reserveRawDataSpace(unsigned int size); + bool reserveVertexSpace(const gl::VertexAttribute &attribute, GLsizei count, GLsizei instances); + bool reserveRawDataSpace(unsigned int size); unsigned int getBufferSize() const; diff --git a/src/libGLESv2/renderer/VertexDataManager.cpp b/src/libGLESv2/renderer/VertexDataManager.cpp index ec858572..fd869b10 100644 --- a/src/libGLESv2/renderer/VertexDataManager.cpp +++ b/src/libGLESv2/renderer/VertexDataManager.cpp @@ -116,12 +116,18 @@ GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], if (staticBuffer->getBufferSize() == 0) { int totalCount = elementsInBuffer(attribs[i], buffer->size()); - staticBuffer->reserveVertexSpace(attribs[i], totalCount, 0); + if (!staticBuffer->reserveVertexSpace(attribs[i], totalCount, 0)) + { + return GL_OUT_OF_MEMORY; + } } } else { - mStreamingBuffer->reserveVertexSpace(attribs[i], count, instances); + if (!mStreamingBuffer->reserveVertexSpace(attribs[i], count, instances)) + { + return GL_OUT_OF_MEMORY; + } } } } @@ -217,7 +223,10 @@ GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], mCurrentValue[i][3] != attribs[i].mCurrentValue[3]) { unsigned int requiredSpace = sizeof(float) * 4; - buffer->reserveRawDataSpace(requiredSpace); + if (!buffer->reserveRawDataSpace(requiredSpace)) + { + return GL_OUT_OF_MEMORY; + } int streamOffset = buffer->storeRawData(attribs[i].mCurrentValue, requiredSpace); if (streamOffset == -1) { -- cgit v1.2.3 From 6322ef4790e5c546c1d9bfaf5877ffc6048bc541 Mon Sep 17 00:00:00 2001 From: Geoff Lang Date: Tue, 9 Jul 2013 16:02:30 -0400 Subject: Protect against integer overflows in the IndexBuffer class by validating that the new write position will not overflow. Issue 444 Signed-off-by: Jamie Madil Signed-off-by: Shannon Woods Author: Geoff Lang --- src/libGLESv2/renderer/IndexBuffer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libGLESv2/renderer/IndexBuffer.cpp b/src/libGLESv2/renderer/IndexBuffer.cpp index 16fd7823..3d5d7a7c 100644 --- a/src/libGLESv2/renderer/IndexBuffer.cpp +++ b/src/libGLESv2/renderer/IndexBuffer.cpp @@ -130,12 +130,13 @@ bool StreamingIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum { bool result = true; unsigned int curBufferSize = getBufferSize(); + unsigned int writePos = getWritePosition(); if (size > curBufferSize) { result = setBufferSize(std::max(size, 2 * curBufferSize), indexType); setWritePosition(0); } - else if (getWritePosition() + size > curBufferSize) + else if (writePos + size > curBufferSize || writePos + size < writePos) { if (!discard()) { -- cgit v1.2.3 From 7891ba45345d5c4ebb0b75343190109335d7dda4 Mon Sep 17 00:00:00 2001 From: Shannon Woods Date: Thu, 11 Jul 2013 13:10:36 -0400 Subject: Bump ANGLE version --- src/common/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/version.h b/src/common/version.h index 6c6cee6b..5ea84259 100644 --- a/src/common/version.h +++ b/src/common/version.h @@ -1,7 +1,7 @@ #define MAJOR_VERSION 1 #define MINOR_VERSION 2 #define BUILD_VERSION 0 -#define BUILD_REVISION 2424 +#define BUILD_REVISION 2425 #define STRINGIFY(x) #x #define MACRO_STRINGIFY(x) STRINGIFY(x) -- cgit v1.2.3 From 9c414aca1d9f635ace998ce0651b791abb6674a8 Mon Sep 17 00:00:00 2001 From: Jamie Madill Date: Fri, 12 Jul 2013 15:56:28 -0400 Subject: Add *.orig and *.rej to .gitignore. TRAC #23509 Signed-off-by: Shannon Woods Signed-off-by: Nicolas Capens Authored-by: Jamie Madill --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 2b3d19b4..da50cf1b 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,6 @@ patches-* ipch debug.txt *.opensdf +*.orig +*.rej -- cgit v1.2.3 From 57a045443cebf1bb035bfa9cc63d392d875136ed Mon Sep 17 00:00:00 2001 From: Jamie Madill Date: Fri, 12 Jul 2013 16:05:23 -0400 Subject: Move the code for parsing indexed expressions from the grammar to TParseContext. TRAC #23509 Signed-off-by: Shannon Woods Signed-off-by: Nicolas Capens Authored-by: Jamie Madill --- src/compiler/ParseHelper.cpp | 128 ++++++++++++++++++++++++++++++++++++++ src/compiler/ParseHelper.h | 1 + src/compiler/glslang.y | 74 +--------------------- src/compiler/glslang_tab.cpp | 142 +++++++++++-------------------------------- src/compiler/glslang_tab.h | 4 +- 5 files changed, 167 insertions(+), 182 deletions(-) diff --git a/src/compiler/ParseHelper.cpp b/src/compiler/ParseHelper.cpp index fd2e9539..b84a1755 100644 --- a/src/compiler/ParseHelper.cpp +++ b/src/compiler/ParseHelper.cpp @@ -1447,6 +1447,134 @@ bool TParseContext::structNestingErrorCheck(const TSourceLoc& line, const TField return false; } +// +// Parse an array index expression +// +TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, const TSourceLoc& location, TIntermTyped *indexExpression) +{ + TIntermTyped *indexedExpression = NULL; + + if (!baseExpression->isArray() && !baseExpression->isMatrix() && !baseExpression->isVector()) + { + if (baseExpression->getAsSymbolNode()) + { + error(location, " left of '[' is not of type array, matrix, or vector ", baseExpression->getAsSymbolNode()->getSymbol().c_str()); + } + else + { + error(location, " left of '[' is not of type array, matrix, or vector ", "expression"); + } + recover(); + } + + if (indexExpression->getQualifier() == EvqConst) + { + int index = indexExpression->getAsConstantUnion()->getIConst(0); + if (index < 0) + { + std::stringstream infoStream; + infoStream << index; + std::string info = infoStream.str(); + error(location, "negative index", info.c_str()); + recover(); + index = 0; + } + if (baseExpression->getType().getQualifier() == EvqConst) + { + if (baseExpression->isArray()) + { + // constant folding for arrays + indexedExpression = addConstArrayNode(index, baseExpression, location); + } + else if (baseExpression->isVector()) + { + // constant folding for vectors + TVectorFields fields; + fields.num = 1; + fields.offsets[0] = index; // need to do it this way because v.xy sends fields integer array + indexedExpression = addConstVectorNode(fields, baseExpression, location); + } + else if (baseExpression->isMatrix()) + { + // constant folding for matrices + indexedExpression = addConstMatrixNode(index, baseExpression, location); + } + } + else + { + if (baseExpression->isArray()) + { + if (index >= baseExpression->getType().getArraySize()) + { + std::stringstream extraInfoStream; + extraInfoStream << "array index out of range '" << index << "'"; + std::string extraInfo = extraInfoStream.str(); + error(location, "", "[", extraInfo.c_str()); + recover(); + index = baseExpression->getType().getArraySize() - 1; + } + } + else if ((baseExpression->isVector() || baseExpression->isMatrix()) && baseExpression->getType().getNominalSize() <= index) + { + std::stringstream extraInfoStream; + extraInfoStream << "field selection out of range '" << index << "'"; + std::string extraInfo = extraInfoStream.str(); + error(location, "", "[", extraInfo.c_str()); + recover(); + index = baseExpression->getType().getNominalSize() - 1; + } + + indexExpression->getAsConstantUnion()->getUnionArrayPointer()->setIConst(index); + indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, indexExpression, location); + } + } + else + { + indexedExpression = intermediate.addIndex(EOpIndexIndirect, baseExpression, indexExpression, location); + } + + if (indexedExpression == 0) + { + ConstantUnion *unionArray = new ConstantUnion[1]; + unionArray->setFConst(0.0f); + indexedExpression = intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst), location); + } + else if (baseExpression->isArray()) + { + const TType &baseType = baseExpression->getType(); + if (baseType.getStruct()) + { + TType copyOfType(baseType.getStruct()); + indexedExpression->setType(copyOfType); + } + else + { + indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), EvqTemporary, baseExpression->getNominalSize(), baseExpression->isMatrix())); + } + + if (baseExpression->getType().getQualifier() == EvqConst) + { + indexedExpression->getTypePointer()->setQualifier(EvqConst); + } + } + else if (baseExpression->isMatrix()) + { + TQualifier qualifier = baseExpression->getType().getQualifier() == EvqConst ? EvqConst : EvqTemporary; + indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), qualifier, baseExpression->getNominalSize())); + } + else if (baseExpression->isVector()) + { + TQualifier qualifier = baseExpression->getType().getQualifier() == EvqConst ? EvqConst : EvqTemporary; + indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), qualifier)); + } + else + { + indexedExpression->setType(baseExpression->getType()); + } + + return indexedExpression; +} + // // Parse an array of strings using yyparse. // diff --git a/src/compiler/ParseHelper.h b/src/compiler/ParseHelper.h index b2025b84..4b2f6c34 100644 --- a/src/compiler/ParseHelper.h +++ b/src/compiler/ParseHelper.h @@ -117,6 +117,7 @@ struct TParseContext { TIntermTyped* addConstMatrixNode(int , TIntermTyped*, const TSourceLoc&); TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, const TSourceLoc& line); TIntermTyped* addConstStruct(TString& , TIntermTyped*, const TSourceLoc&); + TIntermTyped* addIndexExpression(TIntermTyped *baseExpression, const TSourceLoc& location, TIntermTyped *indexExpression); // Performs an error check for embedded struct declarations. // Returns true if an error was raised due to the declaration of diff --git a/src/compiler/glslang.y b/src/compiler/glslang.y index 2c25d5b1..cbb66025 100644 --- a/src/compiler/glslang.y +++ b/src/compiler/glslang.y @@ -259,79 +259,7 @@ postfix_expression $$ = $1; } | postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET { - if (!$1->isArray() && !$1->isMatrix() && !$1->isVector()) { - if ($1->getAsSymbolNode()) - context->error(@2, " left of '[' is not of type array, matrix, or vector ", $1->getAsSymbolNode()->getSymbol().c_str()); - else - context->error(@2, " left of '[' is not of type array, matrix, or vector ", "expression"); - context->recover(); - } - if ($3->getQualifier() == EvqConst) { - int index = $3->getAsConstantUnion()->getIConst(0); - if (index < 0) { - std::stringstream infoStream; - infoStream << index; - std::string info = infoStream.str(); - context->error(@3, "negative index", info.c_str()); - context->recover(); - index = 0; - } - if ($1->getType().getQualifier() == EvqConst) { - if ($1->isArray()) { // constant folding for arrays - $$ = context->addConstArrayNode(index, $1, @2); - } else if ($1->isVector()) { // constant folding for vectors - TVectorFields fields; - fields.num = 1; - fields.offsets[0] = index; // need to do it this way because v.xy sends fields integer array - $$ = context->addConstVectorNode(fields, $1, @2); - } else if ($1->isMatrix()) { // constant folding for matrices - $$ = context->addConstMatrixNode(index, $1, @2); - } - } else { - if ($1->isArray()) { - if (index >= $1->getType().getArraySize()) { - std::stringstream extraInfoStream; - extraInfoStream << "array index out of range '" << index << "'"; - std::string extraInfo = extraInfoStream.str(); - context->error(@2, "", "[", extraInfo.c_str()); - context->recover(); - index = $1->getType().getArraySize() - 1; - } - } else if (($1->isVector() || $1->isMatrix()) && $1->getType().getNominalSize() <= index) { - std::stringstream extraInfoStream; - extraInfoStream << "field selection out of range '" << index << "'"; - std::string extraInfo = extraInfoStream.str(); - context->error(@2, "", "[", extraInfo.c_str()); - context->recover(); - index = $1->getType().getNominalSize() - 1; - } - $3->getAsConstantUnion()->getUnionArrayPointer()->setIConst(index); - $$ = context->intermediate.addIndex(EOpIndexDirect, $1, $3, @2); - } - } else { - $$ = context->intermediate.addIndex(EOpIndexIndirect, $1, $3, @2); - } - if ($$ == 0) { - ConstantUnion *unionArray = new ConstantUnion[1]; - unionArray->setFConst(0.0f); - $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst), @2); - } else if ($1->isArray()) { - if ($1->getType().getStruct()) - $$->setType(TType($1->getType().getStruct())); - else - $$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqTemporary, $1->getNominalSize(), $1->isMatrix())); - - if ($1->getType().getQualifier() == EvqConst) - $$->getTypePointer()->setQualifier(EvqConst); - } else if ($1->isMatrix()) { - TQualifier qualifier = $1->getType().getQualifier() == EvqConst ? EvqConst : EvqTemporary; - $$->setType(TType($1->getBasicType(), $1->getPrecision(), qualifier, $1->getNominalSize())); - } else if ($1->isVector()) { - TQualifier qualifier = $1->getType().getQualifier() == EvqConst ? EvqConst : EvqTemporary; - $$->setType(TType($1->getBasicType(), $1->getPrecision(), qualifier)); - } else { - $$->setType($1->getType()); - } + $$ = context->addIndexExpression($1, @2, $3); } | function_call { $$ = $1; diff --git a/src/compiler/glslang_tab.cpp b/src/compiler/glslang_tab.cpp index 21117ee7..111198a8 100644 --- a/src/compiler/glslang_tab.cpp +++ b/src/compiler/glslang_tab.cpp @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 2.7. */ +/* A Bison parser, made by GNU Bison 2.7.12-4996. */ /* Bison implementation for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -44,7 +44,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "2.7" +#define YYBISON_VERSION "2.7.12-4996" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -400,6 +400,14 @@ typedef short int yytype_int16; # endif #endif +#ifndef __attribute__ +/* This feature is available in gcc versions 2.5 and later. */ +# if (! defined __GNUC__ || __GNUC__ < 2 \ + || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)) +# define __attribute__(Spec) /* empty */ +# endif +#endif + /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(E) ((void) (E)) @@ -407,6 +415,7 @@ typedef short int yytype_int16; # define YYUSE(E) /* empty */ #endif + /* Identity function, used to suppress warnings about constant conditions. */ #ifndef lint # define YYID(N) (N) @@ -714,26 +723,26 @@ static const yytype_int16 yyrhs[] = static const yytype_uint16 yyrline[] = { 0, 179, 179, 180, 183, 226, 229, 242, 247, 252, - 258, 261, 336, 339, 434, 444, 457, 465, 565, 568, - 576, 579, 585, 589, 596, 602, 611, 619, 674, 684, - 687, 697, 707, 728, 729, 730, 735, 736, 744, 755, - 756, 764, 775, 779, 780, 790, 800, 810, 823, 824, - 834, 847, 851, 855, 859, 860, 873, 874, 887, 888, - 901, 902, 919, 920, 933, 934, 935, 936, 937, 941, - 944, 955, 963, 990, 995, 1009, 1046, 1049, 1056, 1064, - 1085, 1106, 1116, 1144, 1149, 1159, 1164, 1174, 1177, 1180, - 1183, 1189, 1196, 1199, 1221, 1239, 1263, 1286, 1290, 1308, - 1316, 1348, 1368, 1389, 1398, 1421, 1424, 1430, 1438, 1446, - 1454, 1464, 1471, 1474, 1477, 1483, 1486, 1501, 1505, 1509, - 1513, 1517, 1522, 1527, 1532, 1537, 1542, 1547, 1552, 1557, - 1562, 1567, 1572, 1577, 1581, 1585, 1593, 1601, 1605, 1618, - 1618, 1632, 1632, 1641, 1644, 1660, 1693, 1697, 1703, 1710, - 1725, 1729, 1733, 1734, 1740, 1741, 1742, 1743, 1744, 1748, - 1749, 1749, 1749, 1759, 1760, 1764, 1764, 1765, 1765, 1770, - 1773, 1783, 1786, 1792, 1793, 1797, 1805, 1809, 1819, 1824, - 1841, 1841, 1846, 1846, 1853, 1853, 1861, 1864, 1870, 1873, - 1879, 1883, 1890, 1897, 1904, 1911, 1922, 1931, 1935, 1942, - 1945, 1951, 1951 + 258, 261, 264, 267, 362, 372, 385, 393, 493, 496, + 504, 507, 513, 517, 524, 530, 539, 547, 602, 612, + 615, 625, 635, 656, 657, 658, 663, 664, 672, 683, + 684, 692, 703, 707, 708, 718, 728, 738, 751, 752, + 762, 775, 779, 783, 787, 788, 801, 802, 815, 816, + 829, 830, 847, 848, 861, 862, 863, 864, 865, 869, + 872, 883, 891, 918, 923, 937, 974, 977, 984, 992, + 1013, 1034, 1044, 1072, 1077, 1087, 1092, 1102, 1105, 1108, + 1111, 1117, 1124, 1127, 1149, 1167, 1191, 1214, 1218, 1236, + 1244, 1276, 1296, 1317, 1326, 1349, 1352, 1358, 1366, 1374, + 1382, 1392, 1399, 1402, 1405, 1411, 1414, 1429, 1433, 1437, + 1441, 1445, 1450, 1455, 1460, 1465, 1470, 1475, 1480, 1485, + 1490, 1495, 1500, 1505, 1509, 1513, 1521, 1529, 1533, 1546, + 1546, 1560, 1560, 1569, 1572, 1588, 1621, 1625, 1631, 1638, + 1653, 1657, 1661, 1662, 1668, 1669, 1670, 1671, 1672, 1676, + 1677, 1677, 1677, 1687, 1688, 1692, 1692, 1693, 1693, 1698, + 1701, 1711, 1714, 1720, 1721, 1725, 1733, 1737, 1747, 1752, + 1769, 1769, 1774, 1774, 1781, 1781, 1789, 1792, 1798, 1801, + 1807, 1811, 1818, 1825, 1832, 1839, 1850, 1859, 1863, 1870, + 1873, 1879, 1879 }; #endif @@ -1511,11 +1520,7 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, context) # else YYUSE (yyoutput); # endif - switch (yytype) - { - default: - break; - } + YYUSE (yytype); } @@ -1915,12 +1920,7 @@ yydestruct (yymsg, yytype, yyvaluep, yylocationp, context) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - switch (yytype) - { - - default: - break; - } + YYUSE (yytype); } @@ -2346,79 +2346,7 @@ yyreduce: case 11: { - if (!(yyvsp[(1) - (4)].interm.intermTypedNode)->isArray() && !(yyvsp[(1) - (4)].interm.intermTypedNode)->isMatrix() && !(yyvsp[(1) - (4)].interm.intermTypedNode)->isVector()) { - if ((yyvsp[(1) - (4)].interm.intermTypedNode)->getAsSymbolNode()) - context->error((yylsp[(2) - (4)]), " left of '[' is not of type array, matrix, or vector ", (yyvsp[(1) - (4)].interm.intermTypedNode)->getAsSymbolNode()->getSymbol().c_str()); - else - context->error((yylsp[(2) - (4)]), " left of '[' is not of type array, matrix, or vector ", "expression"); - context->recover(); - } - if ((yyvsp[(3) - (4)].interm.intermTypedNode)->getQualifier() == EvqConst) { - int index = (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getIConst(0); - if (index < 0) { - std::stringstream infoStream; - infoStream << index; - std::string info = infoStream.str(); - context->error((yylsp[(3) - (4)]), "negative index", info.c_str()); - context->recover(); - index = 0; - } - if ((yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getQualifier() == EvqConst) { - if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isArray()) { // constant folding for arrays - (yyval.interm.intermTypedNode) = context->addConstArrayNode(index, (yyvsp[(1) - (4)].interm.intermTypedNode), (yylsp[(2) - (4)])); - } else if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isVector()) { // constant folding for vectors - TVectorFields fields; - fields.num = 1; - fields.offsets[0] = index; // need to do it this way because v.xy sends fields integer array - (yyval.interm.intermTypedNode) = context->addConstVectorNode(fields, (yyvsp[(1) - (4)].interm.intermTypedNode), (yylsp[(2) - (4)])); - } else if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isMatrix()) { // constant folding for matrices - (yyval.interm.intermTypedNode) = context->addConstMatrixNode(index, (yyvsp[(1) - (4)].interm.intermTypedNode), (yylsp[(2) - (4)])); - } - } else { - if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isArray()) { - if (index >= (yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getArraySize()) { - std::stringstream extraInfoStream; - extraInfoStream << "array index out of range '" << index << "'"; - std::string extraInfo = extraInfoStream.str(); - context->error((yylsp[(2) - (4)]), "", "[", extraInfo.c_str()); - context->recover(); - index = (yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getArraySize() - 1; - } - } else if (((yyvsp[(1) - (4)].interm.intermTypedNode)->isVector() || (yyvsp[(1) - (4)].interm.intermTypedNode)->isMatrix()) && (yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getNominalSize() <= index) { - std::stringstream extraInfoStream; - extraInfoStream << "field selection out of range '" << index << "'"; - std::string extraInfo = extraInfoStream.str(); - context->error((yylsp[(2) - (4)]), "", "[", extraInfo.c_str()); - context->recover(); - index = (yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getNominalSize() - 1; - } - (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getUnionArrayPointer()->setIConst(index); - (yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpIndexDirect, (yyvsp[(1) - (4)].interm.intermTypedNode), (yyvsp[(3) - (4)].interm.intermTypedNode), (yylsp[(2) - (4)])); - } - } else { - (yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpIndexIndirect, (yyvsp[(1) - (4)].interm.intermTypedNode), (yyvsp[(3) - (4)].interm.intermTypedNode), (yylsp[(2) - (4)])); - } - if ((yyval.interm.intermTypedNode) == 0) { - ConstantUnion *unionArray = new ConstantUnion[1]; - unionArray->setFConst(0.0f); - (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst), (yylsp[(2) - (4)])); - } else if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isArray()) { - if ((yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getStruct()) - (yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getStruct())); - else - (yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (4)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (4)].interm.intermTypedNode)->getPrecision(), EvqTemporary, (yyvsp[(1) - (4)].interm.intermTypedNode)->getNominalSize(), (yyvsp[(1) - (4)].interm.intermTypedNode)->isMatrix())); - - if ((yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getQualifier() == EvqConst) - (yyval.interm.intermTypedNode)->getTypePointer()->setQualifier(EvqConst); - } else if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isMatrix()) { - TQualifier qualifier = (yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getQualifier() == EvqConst ? EvqConst : EvqTemporary; - (yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (4)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (4)].interm.intermTypedNode)->getPrecision(), qualifier, (yyvsp[(1) - (4)].interm.intermTypedNode)->getNominalSize())); - } else if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isVector()) { - TQualifier qualifier = (yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getQualifier() == EvqConst ? EvqConst : EvqTemporary; - (yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (4)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (4)].interm.intermTypedNode)->getPrecision(), qualifier)); - } else { - (yyval.interm.intermTypedNode)->setType((yyvsp[(1) - (4)].interm.intermTypedNode)->getType()); - } + (yyval.interm.intermTypedNode) = context->addIndexExpression((yyvsp[(1) - (4)].interm.intermTypedNode), (yylsp[(2) - (4)]), (yyvsp[(3) - (4)].interm.intermTypedNode)); } break; diff --git a/src/compiler/glslang_tab.h b/src/compiler/glslang_tab.h index 2f0f1106..ed3eda57 100644 --- a/src/compiler/glslang_tab.h +++ b/src/compiler/glslang_tab.h @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 2.7. */ +/* A Bison parser, made by GNU Bison 2.7.12-4996. */ /* Bison interface for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -- cgit v1.2.3