Merge pull request #538 from steve-lunarg/iomap-binding-range-err
Check for out-of-range bindings during IO mapping.
This commit is contained in:
commit
e4ad1bb68a
7 changed files with 72 additions and 13 deletions
|
|
@ -1724,7 +1724,7 @@ bool TProgram::mapIO()
|
|||
|
||||
for (int s = 0; s < EShLangCount; ++s) {
|
||||
if (intermediate[s]) {
|
||||
if (! ioMapper->addStage((EShLanguage)s, *intermediate[s]))
|
||||
if (! ioMapper->addStage((EShLanguage)s, *intermediate[s], *infoSink))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
//
|
||||
|
||||
#include "../Include/Common.h"
|
||||
#include "../Include/InfoSink.h"
|
||||
#include "iomapper.h"
|
||||
#include "LiveTraverser.h"
|
||||
#include "localintermediate.h"
|
||||
|
|
@ -150,11 +151,30 @@ protected:
|
|||
class TIoMappingTraverser : public TBindingTraverser {
|
||||
public:
|
||||
TIoMappingTraverser(TIntermediate& i, TBindingMap& bindingMap, TUsedBindings& usedBindings,
|
||||
bool traverseDeadCode) :
|
||||
TBindingTraverser(i, bindingMap, usedBindings, traverseDeadCode)
|
||||
TInfoSink& infoSink, bool traverseDeadCode) :
|
||||
TBindingTraverser(i, bindingMap, usedBindings, traverseDeadCode),
|
||||
infoSink(infoSink),
|
||||
assignError(false)
|
||||
{ }
|
||||
|
||||
bool success() const { return !assignError; }
|
||||
|
||||
protected:
|
||||
unsigned checkBindingRange(const TIntermSymbol& base, unsigned binding)
|
||||
{
|
||||
if (binding >= TQualifier::layoutBindingEnd) {
|
||||
TString err = "mapped binding out of range: ";
|
||||
err += base.getName();
|
||||
|
||||
infoSink.info.message(EPrefixInternalError, err.c_str());
|
||||
assignError = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return binding;
|
||||
}
|
||||
|
||||
void addUniform(TIntermSymbol& base) override
|
||||
{
|
||||
// Skip things we don't intend to bind.
|
||||
|
|
@ -165,7 +185,7 @@ protected:
|
|||
|
||||
// Apply existing binding, if we were given one or already made one up.
|
||||
if (existingBinding != -1) {
|
||||
base.getWritableType().getQualifier().layoutBinding = existingBinding;
|
||||
base.getWritableType().getQualifier().layoutBinding = checkBindingRange(base, existingBinding);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -174,7 +194,7 @@ protected:
|
|||
const int freeBinding = getFreeBinding(base.getType(), getBindingBase(base.getType()));
|
||||
|
||||
markBinding(base, freeBinding);
|
||||
base.getWritableType().getQualifier().layoutBinding = freeBinding;
|
||||
base.getWritableType().getQualifier().layoutBinding = checkBindingRange(base, freeBinding);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -195,13 +215,17 @@ protected:
|
|||
|
||||
return nextBinding;
|
||||
}
|
||||
|
||||
private:
|
||||
bool assignError; // true if there was an error assigning the bindings
|
||||
TInfoSink& infoSink;
|
||||
};
|
||||
|
||||
// Map I/O variables to provided offsets, and make bindings for
|
||||
// unbound but live variables.
|
||||
//
|
||||
// Returns false if the input is too malformed to do this.
|
||||
bool TIoMapper::addStage(EShLanguage, TIntermediate& intermediate)
|
||||
bool TIoMapper::addStage(EShLanguage, TIntermediate& intermediate, TInfoSink& infoSink)
|
||||
{
|
||||
// Trivial return if there is nothing to do.
|
||||
if (intermediate.getShiftSamplerBinding() == 0 &&
|
||||
|
|
@ -223,7 +247,7 @@ bool TIoMapper::addStage(EShLanguage, TIntermediate& intermediate)
|
|||
|
||||
TBindingTraverser it_binding_all(intermediate, bindingMap, usedBindings, true);
|
||||
TBindingTraverser it_binding_live(intermediate, bindingMap, usedBindings, false);
|
||||
TIoMappingTraverser it_iomap(intermediate, bindingMap, usedBindings, true);
|
||||
TIoMappingTraverser it_iomap(intermediate, bindingMap, usedBindings, infoSink, true);
|
||||
|
||||
// Traverse all (live+dead) code to find explicit bindings, so we can avoid those.
|
||||
root->traverse(&it_binding_all);
|
||||
|
|
@ -240,7 +264,7 @@ bool TIoMapper::addStage(EShLanguage, TIntermediate& intermediate)
|
|||
// Bind everything that needs a binding and doesn't have one.
|
||||
root->traverse(&it_iomap);
|
||||
|
||||
return true;
|
||||
return it_iomap.success();
|
||||
}
|
||||
|
||||
} // end namespace glslang
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@
|
|||
// A reflection database and its interface, consistent with the OpenGL API reflection queries.
|
||||
//
|
||||
|
||||
class TInfoSink;
|
||||
|
||||
namespace glslang {
|
||||
|
||||
class TIntermediate;
|
||||
|
|
@ -53,7 +55,7 @@ public:
|
|||
virtual ~TIoMapper() {}
|
||||
|
||||
// grow the reflection stage by stage
|
||||
bool addStage(EShLanguage, TIntermediate&);
|
||||
bool addStage(EShLanguage, TIntermediate&, TInfoSink&);
|
||||
};
|
||||
|
||||
} // end namespace glslang
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue