From bb79abccb3ad043c5e5a4c6dd58e83d0d392750b Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Sat, 7 Oct 2017 13:23:09 -0600 Subject: [PATCH] HLSL: Validate implicit initializer assignment to opaque members. Fixes #1091. --- hlsl/hlslGrammar.cpp | 9 ++++++--- hlsl/hlslParseHelper.cpp | 12 +++++++++++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp index 88eacd9c..515922e0 100755 --- a/hlsl/hlslGrammar.cpp +++ b/hlsl/hlslGrammar.cpp @@ -2426,6 +2426,9 @@ bool HlslGrammar::acceptDefaultParameterDeclaration(const TType& type, TIntermTy node = parseContext.handleFunctionCall(token.loc, constructor, node); } + if (node == nullptr) + return false; + // If this is simply a constant, we can use it directly. if (node->getAsConstantUnion()) return true; @@ -2862,7 +2865,7 @@ bool HlslGrammar::acceptUnaryExpression(TIntermTyped*& node) parseContext.handleFunctionArgument(constructorFunction, arguments, node); node = parseContext.handleFunctionCall(loc, constructorFunction, arguments); - return true; + return node != nullptr; } else { // This could be a parenthesized constructor, ala (int(3)), and we just accepted // the '(int' part. We must back up twice. @@ -3072,7 +3075,7 @@ bool HlslGrammar::acceptConstructor(TIntermTyped*& node) // hook it up node = parseContext.handleFunctionCall(arguments->getLoc(), constructorFunction, arguments); - return true; + return node != nullptr; } return false; @@ -3120,7 +3123,7 @@ bool HlslGrammar::acceptFunctionCall(const TSourceLoc& loc, TString& name, TInte // call node = parseContext.handleFunctionCall(loc, function, arguments); - return true; + return node != nullptr; } // arguments diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp index a336bd70..706173d2 100755 --- a/hlsl/hlslParseHelper.cpp +++ b/hlsl/hlslParseHelper.cpp @@ -4981,8 +4981,10 @@ TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunct // It's a constructor, of type 'type'. // result = handleConstructor(loc, arguments, type); - if (result == nullptr) + if (result == nullptr) { error(loc, "cannot construct with these arguments", type.getCompleteString().c_str(), ""); + return nullptr; + } } } else { // @@ -7736,6 +7738,14 @@ TIntermTyped* HlslParseContext::convertInitializerList(const TSourceLoc& loc, co return addConstructor(loc, initList, arrayType); } else if (type.isStruct()) { + // do we have implicit assignments to opaques? + for (size_t i = initList->getSequence().size(); i < type.getStruct()->size(); ++i) { + if ((*type.getStruct())[i].type->containsOpaque()) { + error(loc, "cannot implicitly initialize opaque members", "initializer list", ""); + return nullptr; + } + } + // lengthen list to be long enough lengthenList(loc, initList->getSequence(), static_cast(type.getStruct()->size()), scalarInit);