Skip to content

Conversation

klausler
Copy link
Contributor

@klausler klausler commented Sep 8, 2025

In expression semantics, don't completely delete the unary plus operator, but instead translate it into parentheses. The distinction matters in contexts where the bounds of x are significant or when x must not be misinterpreted as a variable.

Fixes #157379.

In expression semantics, don't completely delete the unary plus
operator, but instead translate it into parentheses.  The distinction
matters in contexts where the bounds of x are significant or when
x must not be misinterpreted as a variable.

Fixes llvm#157379.
@llvmbot llvmbot added flang Flang issues not falling into any other category flang:semantics labels Sep 8, 2025
@llvmbot
Copy link
Member

llvmbot commented Sep 8, 2025

@llvm/pr-subscribers-flang-semantics

Author: Peter Klausler (klausler)

Changes

In expression semantics, don't completely delete the unary plus operator, but instead translate it into parentheses. The distinction matters in contexts where the bounds of x are significant or when x must not be misinterpreted as a variable.

Fixes #157379.


Full diff: https://github.com/llvm/llvm-project/pull/157513.diff

2 Files Affected:

  • (modified) flang/lib/Semantics/expression.cpp (+4-1)
  • (added) flang/test/Evaluate/bug157379.f90 (+13)
diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index ccccf60adae5d..3f048ab6f7a4d 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -3700,7 +3700,10 @@ static MaybeExpr NumericUnaryHelper(ExpressionAnalyzer &context,
       analyzer.CheckForNullPointer();
       analyzer.CheckForAssumedRank();
       if (opr == NumericOperator::Add) {
-        return analyzer.MoveExpr(0);
+        // +x -> (x), not a bare x, because the bounds of the argument must
+        // not be exposed to allocatable assignments or structure constructor
+        // components.
+        return Parenthesize(analyzer.MoveExpr(0));
       } else {
         return Negation(context.GetContextualMessages(), analyzer.MoveExpr(0));
       }
diff --git a/flang/test/Evaluate/bug157379.f90 b/flang/test/Evaluate/bug157379.f90
new file mode 100644
index 0000000000000..53aac4c29d3e4
--- /dev/null
+++ b/flang/test/Evaluate/bug157379.f90
@@ -0,0 +1,13 @@
+! RUN: %flang_fc1 -fdebug-unparse %s 2>&1 | FileCheck %s
+program main
+  type t
+    integer, allocatable :: ia(:)
+  end type
+  type(t) x
+  integer, allocatable :: ja(:)
+  allocate(ja(2:2))
+  ja(2) = 2
+  !CHECK: x=t(ia=(ja))
+  x = t(+ja)            ! must be t(ia=(ja)), not t(ia=ja)
+  print *, lbound(x%ia) ! must be 1, not 2
+end

@klausler klausler enabled auto-merge (squash) September 10, 2025 20:16
@klausler klausler merged commit 35b141f into llvm:main Sep 10, 2025
9 checks passed
@klausler klausler deleted the bug157379 branch September 10, 2025 20:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:semantics flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Flang] Incorrect execution result of expression in structure constructor
3 participants