Commit 1176530b by John Kessenich

SPV: Prevent issue #415 with better semantic checking.

parent 11e1a073
...@@ -2860,7 +2860,7 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg ...@@ -2860,7 +2860,7 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg
builder.clearAccessChain(); builder.clearAccessChain();
glslangArgs[a]->traverse(this); glslangArgs[a]->traverse(this);
argTypes.push_back(&paramType); argTypes.push_back(&paramType);
// keep outputs as and opaque objects l-values, evaluate input-only as r-values // keep outputs and opaque objects as l-values, evaluate input-only as r-values
if (qualifiers[a] != glslang::EvqConstReadOnly || paramType.isOpaque()) { if (qualifiers[a] != glslang::EvqConstReadOnly || paramType.isOpaque()) {
// save l-value // save l-value
lValues.push_back(builder.getAccessChain()); lValues.push_back(builder.getAccessChain());
......
...@@ -33,7 +33,12 @@ ERROR: 0:67: 'uniform' : no qualifiers allowed for function return ...@@ -33,7 +33,12 @@ ERROR: 0:67: 'uniform' : no qualifiers allowed for function return
ERROR: 0:69: 'non-opaque uniforms outside a block' : not allowed when using GLSL for Vulkan ERROR: 0:69: 'non-opaque uniforms outside a block' : not allowed when using GLSL for Vulkan
ERROR: 0:73: 'texture' : no matching overloaded function found ERROR: 0:73: 'texture' : no matching overloaded function found
ERROR: 0:74: 'imageStore' : no matching overloaded function found ERROR: 0:74: 'imageStore' : no matching overloaded function found
ERROR: 33 compilation errors. No code generated. ERROR: 0:91: 'call argument' : sampler constructor must appear at point of use
ERROR: 0:92: 'call argument' : sampler constructor must appear at point of use
ERROR: 0:93: ',' : sampler constructor must appear at point of use
ERROR: 0:94: ':' : wrong operand types: no operation ':' exists that takes a left-hand operand of type 'temp sampler2D' and a right operand of type 'temp sampler2D' (or there is no acceptable conversion)
ERROR: 0:94: 'call argument' : sampler constructor must appear at point of use
ERROR: 38 compilation errors. No code generated.
......
...@@ -72,4 +72,24 @@ void fooTex() ...@@ -72,4 +72,24 @@ void fooTex()
{ {
texture(t2d, vec2(1.0)); // ERROR, need a sampler, not a pure texture texture(t2d, vec2(1.0)); // ERROR, need a sampler, not a pure texture
imageStore(t2d, ivec2(4, 5), vec4(1.2)); // ERROR, need an image, not a pure texture imageStore(t2d, ivec2(4, 5), vec4(1.2)); // ERROR, need an image, not a pure texture
} }
\ No newline at end of file
precision highp float;
layout(location=0) in vec2 vTexCoord;
layout(location=0) out vec4 FragColor;
vec4 userTexture(mediump sampler2D samp, vec2 coord)
{
return texture(samp, coord);
}
bool cond;
void callUserTexture()
{
userTexture(sampler2D(t2d,s), vTexCoord); // ERROR, not point of use
userTexture((sampler2D(t2d,s)), vTexCoord); // ERROR, not point of use
userTexture((sampler2D(t2d,s), sampler2D(t2d,s)), vTexCoord); // ERROR, not point of use
userTexture(cond ? sampler2D(t2d,s) : sampler2D(t2d,s), vTexCoord); // ERROR, no ?:, not point of use
}
...@@ -2,5 +2,5 @@ ...@@ -2,5 +2,5 @@
// For the version, it uses the latest git tag followed by the number of commits. // For the version, it uses the latest git tag followed by the number of commits.
// For the date, it uses the current date (when then script is run). // For the date, it uses the current date (when then script is run).
#define GLSLANG_REVISION "SPIRV99.1374" #define GLSLANG_REVISION "SPIRV99.1375"
#define GLSLANG_DATE "30-Jul-2016" #define GLSLANG_DATE "31-Jul-2016"
...@@ -1181,6 +1181,8 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction ...@@ -1181,6 +1181,8 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction
if (builtIn) if (builtIn)
nonOpBuiltInCheck(loc, *fnCandidate, *call); nonOpBuiltInCheck(loc, *fnCandidate, *call);
else
userFunctionCallCheck(loc, *call);
} }
// Convert 'out' arguments. If it was a constant folded built-in, it won't be an aggregate anymore. // Convert 'out' arguments. If it was a constant folded built-in, it won't be an aggregate anymore.
...@@ -1724,6 +1726,26 @@ void TParseContext::nonOpBuiltInCheck(const TSourceLoc& loc, const TFunction& fn ...@@ -1724,6 +1726,26 @@ void TParseContext::nonOpBuiltInCheck(const TSourceLoc& loc, const TFunction& fn
} }
// //
// Do any extra checking for a user function call.
//
void TParseContext::userFunctionCallCheck(const TSourceLoc& loc, TIntermAggregate& callNode)
{
TIntermSequence& arguments = callNode.getSequence();
for (int i = 0; i < (int)arguments.size(); ++i)
samplerConstructorLocationCheck(loc, "call argument", arguments[i]);
}
//
// Emit an error if this is a sampler constructor
//
void TParseContext::samplerConstructorLocationCheck(const TSourceLoc& loc, const char* token, TIntermNode* node)
{
if (node->getAsOperator() && node->getAsOperator()->getOp() == EOpConstructTextureSampler)
error(loc, "sampler constructor must appear at point of use", token, "");
}
//
// Handle seeing a built-in constructor in a grammar production. // Handle seeing a built-in constructor in a grammar production.
// //
TFunction* TParseContext::handleConstructorCall(const TSourceLoc& loc, const TPublicType& publicType) TFunction* TParseContext::handleConstructorCall(const TSourceLoc& loc, const TPublicType& publicType)
......
...@@ -204,6 +204,8 @@ public: ...@@ -204,6 +204,8 @@ public:
TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermAggregate&) const; TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermAggregate&) const;
void builtInOpCheck(const TSourceLoc&, const TFunction&, TIntermOperator&); void builtInOpCheck(const TSourceLoc&, const TFunction&, TIntermOperator&);
void nonOpBuiltInCheck(const TSourceLoc&, const TFunction&, TIntermAggregate&); void nonOpBuiltInCheck(const TSourceLoc&, const TFunction&, TIntermAggregate&);
void userFunctionCallCheck(const TSourceLoc&, TIntermAggregate&);
void samplerConstructorLocationCheck(const TSourceLoc&, const char* token, TIntermNode*);
TFunction* handleConstructorCall(const TSourceLoc&, const TPublicType&); TFunction* handleConstructorCall(const TSourceLoc&, const TPublicType&);
bool parseVectorFields(const TSourceLoc&, const TString&, int vecSize, TVectorFields&); bool parseVectorFields(const TSourceLoc&, const TString&, int vecSize, TVectorFields&);
......
...@@ -691,6 +691,7 @@ expression ...@@ -691,6 +691,7 @@ expression
$$ = $1; $$ = $1;
} }
| expression COMMA assignment_expression { | expression COMMA assignment_expression {
parseContext.samplerConstructorLocationCheck($2.loc, ",", $3);
$$ = parseContext.intermediate.addComma($1, $3, $2.loc); $$ = parseContext.intermediate.addComma($1, $3, $2.loc);
if ($$ == 0) { if ($$ == 0) {
parseContext.binaryOpError($2.loc, ",", $1->getCompleteString(), $3->getCompleteString()); parseContext.binaryOpError($2.loc, ",", $1->getCompleteString(), $3->getCompleteString());
......
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment