Hash :
d193d51b
Author :
Date :
2024-06-17T22:46:08
Replace issue ids post migration to new issue tracker This change replaces anglebug.com/NNNN links. Bug: None Change-Id: I8ac3aec8d2a8a844b3d7b99fc0a6b2be8da31761 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5637912 Reviewed-by: Geoff Lang <geofflang@chromium.org> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
//
// Copyright 2020 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// ValidateBarrierFunctionCalls:
// Runs compilation checks related to the "barrier built-in function.
#include "compiler/translator/ValidateBarrierFunctionCall.h"
#include "compiler/translator/Diagnostics.h"
#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/tree_util/IntermTraverse.h"
namespace sh
{
namespace
{
class Traverser : public TIntermTraverser
{
public:
Traverser(TDiagnostics *diagnostics)
: TIntermTraverser(true, false, true), mDiagnostics(diagnostics)
{}
bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override
{
if (!node->getFunction()->isMain())
{
return false;
}
mInMain = visit == PreVisit;
return true;
}
bool visitBranch(Visit visit, TIntermBranch *branch) override
{
if (branch->getFlowOp() == EOpReturn)
{
mSeenReturn = true;
}
return true;
}
bool visitAggregate(Visit visit, TIntermAggregate *node) override
{
if (node->getOp() != EOpBarrierTCS)
{
return true;
}
if (mSeenReturn)
{
mDiagnostics->error(node->getLine(),
"barrier() may not be called at any point after a return statement "
"in the function main().",
"barrier");
mValid = false;
return false;
}
// TODO(anglebug.com/42264094): Determine if we should check loops as well.
if (mBranchCount > 0)
{
mDiagnostics->error(
node->getLine(),
"barrier() may not be called in potentially divergent flow control.", "barrier");
mValid = false;
return false;
}
return true;
}
bool visitIfElse(Visit visit, TIntermIfElse *node) override
{
mBranchCount += ((visit == PreVisit) ? 1 : -1);
return true;
}
bool valid() const { return mValid; }
private:
TDiagnostics *mDiagnostics = nullptr;
bool mInMain = false;
bool mSeenReturn = false;
bool mValid = true;
uint32_t mBranchCount = 0;
};
} // anonymous namespace
bool ValidateBarrierFunctionCall(TIntermBlock *root, TDiagnostics *diagnostics)
{
Traverser traverser(diagnostics);
root->traverse(&traverser);
return traverser.valid();
}
} // namespace sh