diff options
| author | Anders Leino <aleino@nvidia.com> | 2025-01-16 19:23:35 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-01-16 09:23:35 -0800 |
| commit | e771f1945ed692168a2634d66a0907acc9c68858 (patch) | |
| tree | e8d6de4ad801b5dc68cd07638f27efa2e5664426 /source | |
| parent | ad7d13a8a934a56db87a4ece4b1afb0f1db1c9d9 (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.cpp | 178 |
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) { |
