summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-ir-operator-shift-overflow.cpp
diff options
context:
space:
mode:
authorJay Kwak <82421531+jkwak-work@users.noreply.github.com>2024-06-04 10:26:12 -0700
committerGitHub <noreply@github.com>2024-06-04 10:26:12 -0700
commit9b6b31be5b38c588bde28d5f215d78cfc62620da (patch)
tree03330e5f920c7f7c45375ddbac8ff449cbbcbe01 /source/slang/slang-ir-operator-shift-overflow.cpp
parent89c1fd0dd1581221f583653a9dfa6d1cf990577c (diff)
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.
Diffstat (limited to 'source/slang/slang-ir-operator-shift-overflow.cpp')
-rw-r--r--source/slang/slang-ir-operator-shift-overflow.cpp70
1 files changed, 70 insertions, 0 deletions
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<IRGlobalValueWithCode>(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<IRIntLit>(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);
+ }
+
+}