Fix #1759: Check for specialization constants when literals required.

This commit is contained in:
John Kessenich 2019-05-03 08:40:35 -06:00
parent 86c72c9486
commit 5cb2fa2ad2
7 changed files with 93 additions and 5 deletions

View File

@ -17,6 +17,7 @@ ERROR: 0:47: 'gl_ClipDistance array size' : must be less than or equal to gl_Max
ERROR: 0:51: 'start' : undeclared identifier
ERROR: 0:51: '' : constant expression required
ERROR: 0:51: 'layout-id value' : scalar integer expression required
ERROR: 0:51: 'location' : needs a literal integer
ERROR: 0:53: 'input block' : not supported in this stage: vertex
ERROR: 0:54: 'location on block member' : not supported for this version or the enabled extensions
ERROR: 0:57: 'input block' : not supported in this stage: vertex
@ -63,7 +64,7 @@ ERROR: 0:221: 'textureQueryLevels' : no matching overloaded function found
ERROR: 0:221: 'assign' : cannot convert from ' const float' to ' temp int'
ERROR: 0:222: 'textureQueryLevels' : no matching overloaded function found
ERROR: 0:222: 'assign' : cannot convert from ' const float' to ' temp int'
ERROR: 64 compilation errors. No code generated.
ERROR: 65 compilation errors. No code generated.
Shader version: 430

View File

@ -34,7 +34,26 @@ ERROR: 0:54: '[]' : only outermost dimension of an array of arrays can be a spec
ERROR: 0:54: 'location' : SPIR-V requires location for user input/output
ERROR: 0:58: 'location' : SPIR-V requires location for user input/output
ERROR: 0:65: 'location' : overlapping use of location 10
ERROR: 35 compilation errors. No code generated.
ERROR: 0:68: 'location' : needs a literal integer
ERROR: 0:68: 'component' : needs a literal integer
ERROR: 0:69: 'binding' : needs a literal integer
ERROR: 0:69: 'set' : needs a literal integer
ERROR: 0:70: 'offset' : needs a literal integer
ERROR: 0:71: 'align' : must be a power of 2
ERROR: 0:71: 'align' : needs a literal integer
ERROR: 0:72: 'xfb_offset' : needs a literal integer
ERROR: 0:73: 'xfb_buffer' : needs a literal integer
ERROR: 0:74: 'xfb_stride' : needs a literal integer
ERROR: 0:73: 'xfb_buffer' : member cannot contradict block (or what block inherited from global)
ERROR: 0:72: 'xfb layout qualifier' : can only be used on an output
ERROR: 0:73: 'xfb layout qualifier' : can only be used on an output
ERROR: 0:74: 'xfb layout qualifier' : can only be used on an output
ERROR: 0:76: 'input_attachment_index' : needs a literal integer
ERROR: 0:76: 'input_attachment_index' : can only be used with a subpass
ERROR: 0:77: 'constant_id' : needs a literal integer
ERROR: 0:77: 'constant_id' : can only be applied to 'const'-qualified scalar
ERROR: 0:77: 'constant_id' : can only be applied to a scalar
ERROR: 54 compilation errors. No code generated.
SPIR-V is not generated for failed compile or link

View File

@ -63,3 +63,15 @@ layout(binding = 3000) uniform sampler2D s3000;
layout(binding = 3001) uniform b3001 { int a; };
layout(location = 10) in vec4 in1;
layout(location = 10) in vec4 in2; // ERROR, no location aliasing
layout(constant_id = 400) const int nonLit = 1;
layout(location = nonLit, component = nonLit) in vec4 nonLit1; // ERROR, non literal
layout(binding = nonLit, set = nonLit) uniform nonLitBN { // ERROR, non literal
layout(offset = nonLit) vec4 nonLit1; // ERROR, non literal
layout(align = nonLit) vec4 nonLit3; // ERROR, non literal
layout(xfb_offset = nonLit) vec4 nonLit4; // ERROR, non literal
layout(xfb_buffer = nonLit) vec4 nonLit5; // ERROR, non literal
layout(xfb_stride = nonLit) vec4 nonLit6; // ERROR, non literal
} nonLitBI;
layout(input_attachment_index = nonLit) vec4 nonLit3; // ERROR, non literal
layout(constant_id = nonLit) vec4 nonLit4; // ERROR, non literal

View File

@ -1,3 +1,3 @@
// This header is generated by the make-revision script.
#define GLSLANG_PATCH_LEVEL 3204
#define GLSLANG_PATCH_LEVEL 3205

View File

@ -5003,6 +5003,7 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
integerCheck(node, feature);
const TIntermConstantUnion* constUnion = node->getAsConstantUnion();
int value;
bool nonLiteral = false;
if (constUnion) {
value = constUnion->getConstArray()[0].getIConst();
if (! constUnion->isLiteral()) {
@ -5012,6 +5013,7 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
} else {
// grammar should have give out the error message
value = 0;
nonLiteral = true;
}
if (value < 0) {
@ -5033,6 +5035,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
profileRequires(loc, EEsProfile, 310, nullptr, feature);
}
publicType.qualifier.layoutOffset = value;
if (nonLiteral)
error(loc, "needs a literal integer", "offset", "");
return;
} else if (id == "align") {
const char* feature = "uniform buffer-member align";
@ -5045,6 +5049,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
error(loc, "must be a power of 2", "align", "");
else
publicType.qualifier.layoutAlign = value;
if (nonLiteral)
error(loc, "needs a literal integer", "align", "");
return;
} else if (id == "location") {
profileRequires(loc, EEsProfile, 300, nullptr, "location");
@ -5054,6 +5060,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
error(loc, "location is too large", id.c_str(), "");
else
publicType.qualifier.layoutLocation = value;
if (nonLiteral)
error(loc, "needs a literal integer", "location", "");
return;
} else if (id == "set") {
if ((unsigned int)value >= TQualifier::layoutSetEnd)
@ -5062,6 +5070,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
publicType.qualifier.layoutSet = value;
if (value != 0)
requireVulkan(loc, "descriptor set");
if (nonLiteral)
error(loc, "needs a literal integer", "set", "");
return;
} else if (id == "binding") {
profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, "binding");
@ -5070,6 +5080,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
error(loc, "binding is too large", id.c_str(), "");
else
publicType.qualifier.layoutBinding = value;
if (nonLiteral)
error(loc, "needs a literal integer", "binding", "");
return;
} else if (id == "component") {
requireProfile(loc, ECoreProfile | ECompatibilityProfile, "component");
@ -5078,6 +5090,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
error(loc, "component is too large", id.c_str(), "");
else
publicType.qualifier.layoutComponent = value;
if (nonLiteral)
error(loc, "needs a literal integer", "component", "");
return;
} else if (id.compare(0, 4, "xfb_") == 0) {
// "Any shader making any static use (after preprocessing) of any of these
@ -5098,12 +5112,16 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
error(loc, "buffer is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbBufferEnd-1);
else
publicType.qualifier.layoutXfbBuffer = value;
if (nonLiteral)
error(loc, "needs a literal integer", "xfb_buffer", "");
return;
} else if (id == "xfb_offset") {
if (value >= (int)TQualifier::layoutXfbOffsetEnd)
error(loc, "offset is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbOffsetEnd-1);
else
publicType.qualifier.layoutXfbOffset = value;
if (nonLiteral)
error(loc, "needs a literal integer", "xfb_offset", "");
return;
} else if (id == "xfb_stride") {
// "The resulting stride (implicit or explicit), when divided by 4, must be less than or equal to the
@ -5116,6 +5134,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
error(loc, "stride is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbStrideEnd-1);
else
publicType.qualifier.layoutXfbStride = value;
if (nonLiteral)
error(loc, "needs a literal integer", "xfb_stride", "");
return;
}
}
@ -5126,6 +5146,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
error(loc, "attachment index is too large", id.c_str(), "");
else
publicType.qualifier.layoutAttachment = value;
if (nonLiteral)
error(loc, "needs a literal integer", "input_attachment_index", "");
return;
}
if (id == "constant_id") {
@ -5138,11 +5160,15 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
if (! intermediate.addUsedConstantId(value))
error(loc, "specialization-constant id already used", id.c_str(), "");
}
if (nonLiteral)
error(loc, "needs a literal integer", "constant_id", "");
return;
}
if (id == "num_views") {
requireExtensions(loc, Num_OVR_multiview_EXTs, OVR_multiview_EXTs, "num_views");
publicType.shaderQualifiers.numViews = value;
if (nonLiteral)
error(loc, "needs a literal integer", "num_views", "");
return;
}
@ -5154,6 +5180,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
if (id == "secondary_view_offset") {
requireExtensions(loc, 1, &E_GL_NV_stereo_view_rendering, "stereo view rendering");
publicType.qualifier.layoutSecondaryViewportRelativeOffset = value;
if (nonLiteral)
error(loc, "needs a literal integer", "secondary_view_offset", "");
return;
}
}
@ -5165,6 +5193,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
error(loc, "must be a power of 2", "buffer_reference_align", "");
else
publicType.qualifier.layoutBufferReferenceAlign = (unsigned int)std::log2(value);
if (nonLiteral)
error(loc, "needs a literal integer", "buffer_reference_align", "");
return;
}
@ -5178,6 +5208,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
error(loc, "must be greater than 0", "vertices", "");
else
publicType.shaderQualifiers.vertices = value;
if (nonLiteral)
error(loc, "needs a literal integer", "vertices", "");
return;
}
break;
@ -5192,12 +5224,16 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
error(loc, "must be at least 1", "invocations", "");
else
publicType.shaderQualifiers.invocations = value;
if (nonLiteral)
error(loc, "needs a literal integer", "invocations", "");
return;
}
if (id == "max_vertices") {
publicType.shaderQualifiers.vertices = value;
if (value > resources.maxGeometryOutputVertices)
error(loc, "too large, must be less than gl_MaxGeometryOutputVertices", "max_vertices", "");
if (nonLiteral)
error(loc, "needs a literal integer", "max_vertices", "");
return;
}
if (id == "stream") {
@ -5205,6 +5241,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
publicType.qualifier.layoutStream = value;
if (value > 0)
intermediate.setMultiStream();
if (nonLiteral)
error(loc, "needs a literal integer", "stream", "");
return;
}
break;
@ -5222,6 +5260,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
}
publicType.qualifier.layoutIndex = value;
if (nonLiteral)
error(loc, "needs a literal integer", "index", "");
return;
}
break;
@ -5233,6 +5273,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
publicType.shaderQualifiers.vertices = value;
if (value > resources.maxMeshOutputVerticesNV)
error(loc, "too large, must be less than gl_MaxMeshOutputVerticesNV", "max_vertices", "");
if (nonLiteral)
error(loc, "needs a literal integer", "max_vertices", "");
return;
}
if (id == "max_primitives") {
@ -5240,6 +5282,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
publicType.shaderQualifiers.primitives = value;
if (value > resources.maxMeshOutputPrimitivesNV)
error(loc, "too large, must be less than gl_MaxMeshOutputPrimitivesNV", "max_primitives", "");
if (nonLiteral)
error(loc, "needs a literal integer", "max_primitives", "");
return;
}
// Fall through
@ -5259,6 +5303,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
profileRequires(loc, EEsProfile, 310, 0, "gl_WorkGroupSize");
profileRequires(loc, ~EEsProfile, 430, E_GL_ARB_compute_shader, "gl_WorkGroupSize");
}
if (nonLiteral)
error(loc, "needs a literal integer", "local_size", "");
if (id.size() == 12 && value == 0) {
error(loc, "must be at least 1", id.c_str(), "");
return;

View File

@ -85,6 +85,9 @@ const TConstUnion* TAttributeArgs::getConstUnion(TBasicType basicType, int argNu
if (argNum >= (int)args->getSequence().size())
return nullptr;
if (args->getSequence()[argNum]->getAsConstantUnion() == nullptr)
return nullptr;
const TConstUnion* constVal = &args->getSequence()[argNum]->getAsConstantUnion()->getConstArray()[0];
if (constVal == nullptr || constVal->getType() != basicType)
return nullptr;

View File

@ -1899,13 +1899,16 @@ void HlslParseContext::transferTypeAttributes(const TSourceLoc& loc, const TAttr
// location
if (it->getInt(value))
type.getQualifier().layoutLocation = value;
else
error(loc, "needs a literal integer", "location", "");
break;
case EatBinding:
// binding
if (it->getInt(value)) {
type.getQualifier().layoutBinding = value;
type.getQualifier().layoutSet = 0;
}
} else
error(loc, "needs a literal integer", "binding", "");
// set
if (it->getInt(value, 1))
type.getQualifier().layoutSet = value;
@ -1914,7 +1917,9 @@ void HlslParseContext::transferTypeAttributes(const TSourceLoc& loc, const TAttr
// global cbuffer binding
if (it->getInt(value))
globalUniformBinding = value;
// global cbuffer binding
else
error(loc, "needs a literal integer", "global binding", "");
// global cbuffer set
if (it->getInt(value, 1))
globalUniformSet = value;
break;
@ -1922,6 +1927,8 @@ void HlslParseContext::transferTypeAttributes(const TSourceLoc& loc, const TAttr
// input attachment
if (it->getInt(value))
type.getQualifier().layoutAttachment = value;
else
error(loc, "needs a literal integer", "input attachment", "");
break;
case EatBuiltIn:
// PointSize built-in