From 9b6b31be5b38c588bde28d5f215d78cfc62620da Mon Sep 17 00:00:00 2001 From: Jay Kwak <82421531+jkwak-work@users.noreply.github.com> Date: Tue, 4 Jun 2024 10:26:12 -0700 Subject: Print warning when operator<< shifting too much (#4255) * Print warning when operator<< shifting too much Closes #3944 For the given type of the left side operand to `operator<<` is not big enough for the right side operand, print a warning that the result will be always zero. --- source/slang/slang-ir-operator-shift-overflow.cpp | 70 +++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 source/slang/slang-ir-operator-shift-overflow.cpp (limited to 'source/slang/slang-ir-operator-shift-overflow.cpp') diff --git a/source/slang/slang-ir-operator-shift-overflow.cpp b/source/slang/slang-ir-operator-shift-overflow.cpp new file mode 100644 index 000000000..33ee53262 --- /dev/null +++ b/source/slang/slang-ir-operator-shift-overflow.cpp @@ -0,0 +1,70 @@ +// slang-ir-operator-shift-overflow.cpp +#include "slang-ir-operator-shift-overflow.h" + +#include "../../slang.h" +#include "slang-ir.h" +#include "slang-ir-insts.h" +#include "slang-ir-layout.h" + +namespace Slang { + + class DiagnosticSink; + struct IRModule; + + void checkForOperatorShiftOverflowRecursive( + IRInst* inst, + CompilerOptionSet& optionSet, + DiagnosticSink* sink) + { + if (auto code = as(inst)) + { + for (auto block : code->getBlocks()) + { + for (auto opInst : block->getChildren()) + { + switch (opInst->getOp()) + { + case kIROp_Lsh: + { + SLANG_ASSERT(opInst->getOperandCount() == 2); + + IRInst* rhs = opInst->getOperand(1); + auto rhsLit = as(rhs); + if (!rhsLit) + continue; + + IRInst* lhs = opInst->getOperand(0); + IRType* lhsType = lhs->getDataType(); + + IRSizeAndAlignment sizeAlignment; + if (SLANG_FAILED(getNaturalSizeAndAlignment(optionSet, lhsType, &sizeAlignment))) + continue; + + IRIntegerValue shiftAmount = rhsLit->getValue(); + if (sizeAlignment.size * 8 <= shiftAmount) + { + sink->diagnose(opInst, Diagnostics::operatorShiftLeftOverflow, lhsType, shiftAmount); + } + break; + } + } + } + } + } + + for (auto childInst : inst->getChildren()) + { + checkForOperatorShiftOverflowRecursive(childInst, optionSet, sink); + } + } + + void checkForOperatorShiftOverflow( + IRModule* module, + CompilerOptionSet& optionSet, + DiagnosticSink* sink) + { + // Look for `operator<<` instructions + checkForOperatorShiftOverflowRecursive(module->getModuleInst(), optionSet, sink); + } + +} -- cgit v1.2.3