Fix segfault with atomic arg check

Makes sure that we have an l-value before checking the storage type of
the mem argument passed to an atomic memory operation.

Fixes #3332.
This commit is contained in:
Nathaniel Cesario 2023-09-15 12:14:19 -06:00 committed by arcady-lunarg
parent 323836e46b
commit efc33d1ee5
5 changed files with 30 additions and 6 deletions

View File

@ -1,5 +1,5 @@
atomicAdd.comp
ERROR: 0:18: 'atomicAdd' : Atomic memory function can only be used for shader storage block member or shared variable.
ERROR: 0:18: 'atomicAdd' : Only l-values corresponding to shader block storage or shared variables can be used with atomic memory functions.
ERROR: 1 compilation errors. No code generated.

View File

@ -0,0 +1,9 @@
spv.atomicRvalue.error.vert
ERROR: 0:5: 'assign' : l-value required
ERROR: 0:5: 'out' : Non-L-value cannot be passed for 'out' or 'inout' parameters.
ERROR: 0:5: 'atomicAdd' : Only l-values corresponding to shader block storage or shared variables can be used with atomic memory functions.
ERROR: 0:6: 'atomicAdd' : Only l-values corresponding to shader block storage or shared variables can be used with atomic memory functions.
ERROR: 4 compilation errors. No code generated.
SPIR-V is not generated for failed compile or link

View File

@ -0,0 +1,7 @@
#version 440
void main() {
uint a = 5;
atomicAdd(a * 2, 0);
atomicAdd(a, 0);
}

View File

@ -2514,11 +2514,18 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
}
const TIntermTyped* base = TIntermediate::findLValueBase(arg0, true , true);
const TType* refType = (base->getType().isReference()) ? base->getType().getReferentType() : nullptr;
const TQualifier& qualifier = (refType != nullptr) ? refType->getQualifier() : base->getType().getQualifier();
if (qualifier.storage != EvqShared && qualifier.storage != EvqBuffer && qualifier.storage != EvqtaskPayloadSharedEXT)
error(loc,"Atomic memory function can only be used for shader storage block member or shared variable.",
fnCandidate.getName().c_str(), "");
const char* errMsg = "Only l-values corresponding to shader block storage or shared variables can be used with "
"atomic memory functions.";
if (base) {
const TType* refType = (base->getType().isReference()) ? base->getType().getReferentType() : nullptr;
const TQualifier& qualifier =
(refType != nullptr) ? refType->getQualifier() : base->getType().getQualifier();
if (qualifier.storage != EvqShared && qualifier.storage != EvqBuffer &&
qualifier.storage != EvqtaskPayloadSharedEXT)
error(loc, errMsg, fnCandidate.getName().c_str(), "");
} else {
error(loc, errMsg, fnCandidate.getName().c_str(), "");
}
break;
}

View File

@ -529,6 +529,7 @@ INSTANTIATE_TEST_SUITE_P(
"spv.ext.texture_shadow_lod.frag",
"spv.ext.texture_shadow_lod.error.frag",
"spv.floatFetch.frag",
"spv.atomicRvalue.error.vert",
})),
FileNameAsCustomTestSuffix
);