From 03c1de734c79aff99dc935ab93316077541dbd43 Mon Sep 17 00:00:00 2001 From: Srikanth Sankaran <131454720+srikanth-sankaran@users.noreply.github.com> Date: Wed, 2 Oct 2024 15:53:59 +0530 Subject: [PATCH] EmptyStackException when invoking a static method on a null literal in a ternary operator (#3043) * Fixes https://github.com/eclipse-jdt/eclipse.jdt.core/issues/3042 --- .../compiler/ast/ConditionalExpression.java | 10 ++- .../regression/ConditionalExpressionTest.java | 88 +++++++++++++++++++ 2 files changed, 94 insertions(+), 4 deletions(-) diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java index 8c8af44f64b..2b3eda3b6b4 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java @@ -331,10 +331,12 @@ public void generateCode( // End of if statement endifLabel.place(); } - if (this.valueIfFalse.resolvedType == TypeBinding.NULL) { - if (!this.resolvedType.isBaseType()) { - codeStream.operandStack.pop(TypeBinding.NULL); - codeStream.operandStack.push(this.resolvedType); + if (valueRequired) { + if (this.valueIfFalse.resolvedType == TypeBinding.NULL) { + if (!this.resolvedType.isBaseType()) { + codeStream.operandStack.pop(TypeBinding.NULL); + codeStream.operandStack.push(this.resolvedType); + } } } } diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ConditionalExpressionTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ConditionalExpressionTest.java index b125a7809e9..1d08e83b5fa 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ConditionalExpressionTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ConditionalExpressionTest.java @@ -657,4 +657,92 @@ public void testIssue2677_2() { }, "42"); } + + // https://github.com/eclipse-jdt/eclipse.jdt.core/issues/3042 + // java.util.EmptyStackException: null when invoking a static method on a null string literal in a ternary operator + public void testIssue3042() { + if (this.complianceLevel < ClassFileConstants.JDK14) + return; + this.runConformTest( + new String[] { + "X.java", + """ + public class X { + + static void parseFailure(X o) { + (o != null ? o : null).bar(); + } + + static void bar() { + System.out.println("Bar!"); + } + + public static void main(String[] args) { + parseFailure(new X()); + parseFailure(null); + } + } + """ + }, + "Bar!\nBar!"); + } + + public void testIssue3042_2() { + if (this.complianceLevel < ClassFileConstants.JDK14) + return; + this.runConformTest( + new String[] { + "X.java", + """ + public class X { + + void parseFailure(X o) { + (o != null ? o : null).bar(); + } + + void bar() { + System.out.println("Bar!"); + } + + public static void main(String[] args) { + new X().parseFailure(new X()); + try { + new X().parseFailure(null); + } catch (NullPointerException npe) { + System.out.println("NPE!"); + } + } + } + """ + }, + "Bar!\nNPE!"); + } + + public void testIssue3042_3() { + if (this.complianceLevel < ClassFileConstants.JDK14) + return; + this.runConformTest( + new String[] { + "X.java", + """ + public class X { + + void parseSuccess(X o) { + (o == null ? null : o).bar(); + ((X) null).bar(); + } + + static void bar() { + System.out.println("Bar!"); + } + + public static void main(String[] args) { + new X().parseSuccess(new X()); + new X().parseSuccess(null); + } + } + """ + }, + "Bar!\nBar!\nBar!\nBar!"); + } }