summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorAnders Leino <aleino@nvidia.com>2025-01-16 19:23:35 +0200
committerGitHub <noreply@github.com>2025-01-16 09:23:35 -0800
commite771f1945ed692168a2634d66a0907acc9c68858 (patch)
treee8d6de4ad801b5dc68cd07638f27efa2e5664426 /source
parentad7d13a8a934a56db87a4ece4b1afb0f1db1c9d9 (diff)
C-like emitter: Add parenthesis when combining relational and bitwise… (#6070)
* C-like emitter: Add redundant parentheses in several cases This is required since the Dawn WGSL compiler requires parentheses even though precedence rules could resolve order of operations. This closes #6005. * Fix tests/metal/byte-address-buffer The output now includes parentheses around shift expressions appearing as operands in bitwise expressions, so update the test accordingly. * format code --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com> Co-authored-by: Yong He <yonghe@outlook.com>
Diffstat (limited to 'source')
-rw-r--r--source/slang/slang-emit-c-like.cpp178
1 files changed, 34 insertions, 144 deletions
diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp
index d3a9359ff..eaf7ef028 100644
--- a/source/slang/slang-emit-c-like.cpp
+++ b/source/slang/slang-emit-c-like.cpp
@@ -706,6 +706,35 @@ void CLikeSourceEmitter::emitLivenessImpl(IRInst* inst)
// Expressions
//
+static bool isBitLogicalOrRelationalOrEquality(EPrecedence prec)
+{
+ switch (prec)
+ {
+ case EPrecedence::kEPrecedence_And_Left:
+ case EPrecedence::kEPrecedence_And_Right:
+ case EPrecedence::kEPrecedence_BitAnd_Left:
+ case EPrecedence::kEPrecedence_BitAnd_Right:
+ case EPrecedence::kEPrecedence_BitOr_Left:
+ case EPrecedence::kEPrecedence_BitOr_Right:
+ case EPrecedence::kEPrecedence_BitXor_Left:
+ case EPrecedence::kEPrecedence_BitXor_Right:
+ case EPrecedence::kEPrecedence_Or_Left:
+ case EPrecedence::kEPrecedence_Or_Right:
+ case EPrecedence::kEPrecedence_Relational_Left:
+ case EPrecedence::kEPrecedence_Relational_Right:
+ case EPrecedence::kEPrecedence_Shift_Left:
+ case EPrecedence::kEPrecedence_Shift_Right:
+ case EPrecedence::kEPrecedence_Equality_Left:
+ case EPrecedence::kEPrecedence_Equality_Right:
+ return true;
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
bool CLikeSourceEmitter::maybeEmitParens(EmitOpInfo& outerPrec, const EmitOpInfo& prec)
{
bool needParens = (prec.leftPrecedence <= outerPrec.leftPrecedence) ||
@@ -715,152 +744,13 @@ bool CLikeSourceEmitter::maybeEmitParens(EmitOpInfo& outerPrec, const EmitOpInfo
// for common mistakes when parentheses are not used with certain combinations
// of the operations. We emit parentheses to avoid the warnings.
//
- // a | b & c => a | (b & c)
- if (prec.leftPrecedence == EPrecedence::kEPrecedence_BitAnd_Left &&
- outerPrec.leftPrecedence == EPrecedence::kEPrecedence_BitOr_Right)
- {
- needParens = true;
- }
- // a & b | c => (a & b) | c
- else if (
- prec.rightPrecedence == EPrecedence::kEPrecedence_BitAnd_Right &&
- outerPrec.rightPrecedence == EPrecedence::kEPrecedence_BitOr_Left)
- {
- needParens = true;
- }
- // a << b + c => a << (b + c)
- else if (
- prec.leftPrecedence == EPrecedence::kEPrecedence_Additive_Left &&
- outerPrec.leftPrecedence == EPrecedence::kEPrecedence_Shift_Right)
- {
- needParens = true;
- }
- // a + b << c => (a + b) << c
- else if (
- prec.rightPrecedence == EPrecedence::kEPrecedence_Additive_Right &&
- outerPrec.rightPrecedence == EPrecedence::kEPrecedence_Shift_Left)
- {
- needParens = true;
- }
- // a + b & c => (a + b) & c
- else if (
- prec.rightPrecedence == EPrecedence::kEPrecedence_Additive_Right &&
- outerPrec.rightPrecedence == EPrecedence::kEPrecedence_BitAnd_Left)
- {
- needParens = true;
- }
- // a ^ b * c => (a ^ b) * c
- else if (
- prec.rightPrecedence == EPrecedence::kEPrecedence_BitXor_Right &&
- outerPrec.rightPrecedence == EPrecedence::kEPrecedence_Multiplicative_Left)
- {
- needParens = true;
- }
- // a ^ b + c => a ^ (b + c)
- else if (
- prec.leftPrecedence == EPrecedence::kEPrecedence_Additive_Left &&
- outerPrec.leftPrecedence == EPrecedence::kEPrecedence_BitXor_Right)
- {
- needParens = true;
- }
- // a + b ^ c => (a + b) ^ c
- else if (
- prec.rightPrecedence == EPrecedence::kEPrecedence_Additive_Right &&
- outerPrec.rightPrecedence == EPrecedence::kEPrecedence_BitXor_Left)
- {
- needParens = true;
- }
- // a | b + c => a | (b + c)
- else if (
- prec.leftPrecedence == EPrecedence::kEPrecedence_Additive_Left &&
- outerPrec.leftPrecedence == EPrecedence::kEPrecedence_BitOr_Right)
- {
- needParens = true;
- }
- // a + b | c => (a + b) | c
- else if (
- prec.rightPrecedence == EPrecedence::kEPrecedence_Additive_Right &&
- outerPrec.rightPrecedence == EPrecedence::kEPrecedence_BitOr_Left)
- {
- needParens = true;
- }
- // a ^ b * c => a ^ (b * c)
- else if (
- prec.leftPrecedence == EPrecedence::kEPrecedence_Multiplicative_Left &&
- outerPrec.leftPrecedence == EPrecedence::kEPrecedence_BitXor_Right)
- {
- needParens = true;
- }
- // a * b ^ c => (a * b) ^ c
- else if (
- prec.rightPrecedence == EPrecedence::kEPrecedence_Multiplicative_Right &&
- outerPrec.rightPrecedence == EPrecedence::kEPrecedence_BitXor_Left)
- {
- needParens = true;
- }
- // a | b * c => a | (b * c)
- else if (
- prec.leftPrecedence == EPrecedence::kEPrecedence_Multiplicative_Left &&
- outerPrec.leftPrecedence == EPrecedence::kEPrecedence_BitOr_Right)
- {
- needParens = true;
- }
- // a * b | c => (a * b) | c
- else if (
- prec.rightPrecedence == EPrecedence::kEPrecedence_Multiplicative_Right &&
- outerPrec.rightPrecedence == EPrecedence::kEPrecedence_BitOr_Left)
- {
- needParens = true;
- }
- // a & b * c => a & (b * c)
- else if (
- prec.leftPrecedence == EPrecedence::kEPrecedence_Multiplicative_Left &&
- outerPrec.leftPrecedence == EPrecedence::kEPrecedence_BitAnd_Right)
- {
- needParens = true;
- }
- // a * b & c => (a * b) & c
- else if (
- prec.rightPrecedence == EPrecedence::kEPrecedence_Multiplicative_Right &&
- outerPrec.rightPrecedence == EPrecedence::kEPrecedence_BitAnd_Left)
- {
- needParens = true;
- }
- // a << b * c => a << (b * c)
- else if (
- prec.leftPrecedence == EPrecedence::kEPrecedence_Multiplicative_Left &&
- outerPrec.leftPrecedence == EPrecedence::kEPrecedence_Shift_Right)
- {
- needParens = true;
- }
- // a * b << c => (a * b) << c
- else if (
- prec.rightPrecedence == EPrecedence::kEPrecedence_Multiplicative_Right &&
- outerPrec.rightPrecedence == EPrecedence::kEPrecedence_Shift_Left)
- {
- needParens = true;
- }
- // a != b == c => (a != b) == c
- else if (
- prec.rightPrecedence == EPrecedence::kEPrecedence_Equality_Right &&
- outerPrec.rightPrecedence == EPrecedence::kEPrecedence_Equality_Left)
- {
- needParens = true;
- }
- // a == b < c => a == (b < c)
- else if (
- prec.leftPrecedence == EPrecedence::kEPrecedence_Relational_Left &&
- outerPrec.leftPrecedence == EPrecedence::kEPrecedence_Equality_Right)
- {
+
+ if (isBitLogicalOrRelationalOrEquality(prec.leftPrecedence) &&
+ (outerPrec.leftPrecedence > kEPrecedence_Assign_Left))
needParens = true;
- }
- // a < b == c => (a < b) == c
- else if (
- prec.rightPrecedence == EPrecedence::kEPrecedence_Relational_Right &&
- outerPrec.rightPrecedence == EPrecedence::kEPrecedence_Equality_Left)
- {
+ if (isBitLogicalOrRelationalOrEquality(outerPrec.leftPrecedence) ||
+ isBitLogicalOrRelationalOrEquality(outerPrec.rightPrecedence))
needParens = true;
- }
if (needParens)
{