Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Index Checker crashes on pattern matching variable #5013

Closed
tmarback opened this issue Jan 18, 2022 · 1 comment · Fixed by #5015
Closed

Index Checker crashes on pattern matching variable #5013

tmarback opened this issue Jan 18, 2022 · 1 comment · Fixed by #5015

Comments

@tmarback
Copy link

The Index Checker crashes upon encountering a BINDING_VARIABLE (pattern matching variable). The following code:

public class Foo {
    public static int bar( Object o ) {
        if ( o instanceof String s ) {
            return s.length();
        } else {
            return 0;
        }
    }
}

Using javac 17.0.1 and checker-framework 3.21.1 throws this exception during compilation (javac -processor org.checkerframework.checker.index.IndexChecker Foo.java):

error: Error in AnnotatedTypeMirror.fromExpression(UpperBoundAnnotatedTypeFactory, s.length()): Unexpected kind of VariableTree: kind: BINDING_VARIABLE element: s
  ; The Checker Framework crashed.  Please report the crash.
  Compilation unit: Foo.java
  Last visited tree at line 1 column 1:
  public class Foo {
  Exception: org.checkerframework.javacutil.BugInCF: Unexpected kind of VariableTree: kind: BINDING_VARIABLE element: s; org.checkerframework.javacutil.BugInCF: Unexpected kind of VariableTree: kind: BINDING_VARIABLE element: s
        at org.checkerframework.dataflow.expression.JavaExpression.fromVariableElement(JavaExpression.java:526)
        at org.checkerframework.dataflow.expression.JavaExpression.fromTree(JavaExpression.java:440)
        at org.checkerframework.dataflow.expression.JavaExpression.getReceiver(JavaExpression.java:610)
        at org.checkerframework.dataflow.expression.JavaExpression.atMethodInvocation(JavaExpression.java:703)
        at org.checkerframework.framework.util.StringToJavaExpression.atMethodInvocation(StringToJavaExpression.java:195)
        at org.checkerframework.framework.util.dependenttypes.DependentTypesHelper.lambda$atInvocation$1(DependentTypesHelper.java:315)
        at org.checkerframework.framework.util.dependenttypes.DependentTypesHelper.convertAnnotationMirror(DependentTypesHelper.java:711)
        at org.checkerframework.framework.util.dependenttypes.DependentTypesHelper.lambda$convertAnnotatedTypeMirror$12(DependentTypesHelper.java:663)
        at org.checkerframework.framework.util.dependenttypes.DependentTypesHelper$AnnotatedTypeReplacer.scan(DependentTypesHelper.java:869)
        at org.checkerframework.framework.util.dependenttypes.DependentTypesHelper$AnnotatedTypeReplacer.scan(DependentTypesHelper.java:836)
        at org.checkerframework.framework.type.visitor.AnnotatedTypeScanner.visitExecutable(AnnotatedTypeScanner.java:313)
        at org.checkerframework.framework.type.AnnotatedTypeMirror$AnnotatedExecutableType.accept(AnnotatedTypeMirror.java:1149)
        at org.checkerframework.framework.type.visitor.AnnotatedTypeScanner.scan(AnnotatedTypeScanner.java:206)
        at org.checkerframework.framework.util.dependenttypes.DependentTypesHelper$AnnotatedTypeReplacer.scan(DependentTypesHelper.java:881)
        at org.checkerframework.framework.util.dependenttypes.DependentTypesHelper$AnnotatedTypeReplacer.scan(DependentTypesHelper.java:836)
        at org.checkerframework.framework.type.visitor.AnnotatedTypeScanner.visit(AnnotatedTypeScanner.java:194)
        at org.checkerframework.framework.util.dependenttypes.DependentTypesHelper.convertAnnotatedTypeMirror(DependentTypesHelper.java:663)
        at org.checkerframework.framework.util.dependenttypes.DependentTypesHelper.atInvocation(DependentTypesHelper.java:335)
        at org.checkerframework.framework.util.dependenttypes.DependentTypesHelper.atMethodInvocation(DependentTypesHelper.java:254)
        at org.checkerframework.framework.type.GenericAnnotatedTypeFactory.methodFromUse(GenericAnnotatedTypeFactory.java:2023)
        at org.checkerframework.framework.type.TypeFromExpressionVisitor.visitMethodInvocation(TypeFromExpressionVisitor.java:357)
        at org.checkerframework.framework.type.TypeFromExpressionVisitor.visitMethodInvocation(TypeFromExpressionVisitor.java:72)
        at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCMethodInvocation.accept(JCTree.java:1813)
        at jdk.compiler/com.sun.source.util.SimpleTreeVisitor.visit(SimpleTreeVisitor.java:81)
        at org.checkerframework.framework.type.TypeFromTree.fromExpression(TypeFromTree.java:40)
        at org.checkerframework.framework.type.AnnotatedTypeFactory.fromExpression(AnnotatedTypeFactory.java:1555)
        at org.checkerframework.framework.type.AnnotatedTypeFactory.getAnnotatedType(AnnotatedTypeFactory.java:1245)
        at org.checkerframework.framework.flow.CFAbstractTransfer.getValueFromFactory(CFAbstractTransfer.java:203)
        at org.checkerframework.checker.index.upperbound.UpperBoundTransfer.getUBQualifier(UpperBoundTransfer.java:795)
        at org.checkerframework.checker.index.upperbound.UpperBoundTransfer.visitLengthAccess(UpperBoundTransfer.java:681)
        at org.checkerframework.checker.index.upperbound.UpperBoundTransfer.visitMethodInvocation(UpperBoundTransfer.java:723)
        at org.checkerframework.checker.index.upperbound.UpperBoundTransfer.visitMethodInvocation(UpperBoundTransfer.java:107)
        at org.checkerframework.dataflow.cfg.node.MethodInvocationNode.accept(MethodInvocationNode.java:119)
        at org.checkerframework.dataflow.analysis.AbstractAnalysis.callTransferFunction(AbstractAnalysis.java:334)
        at org.checkerframework.dataflow.analysis.ForwardAnalysisImpl.callTransferFunction(ForwardAnalysisImpl.java:372)
        at org.checkerframework.dataflow.analysis.ForwardAnalysisImpl.performAnalysisBlock(ForwardAnalysisImpl.java:151)
        at org.checkerframework.dataflow.analysis.ForwardAnalysisImpl.performAnalysis(ForwardAnalysisImpl.java:105)
        at org.checkerframework.framework.flow.CFAbstractAnalysis.performAnalysis(CFAbstractAnalysis.java:146)
        at org.checkerframework.framework.type.GenericAnnotatedTypeFactory.analyze(GenericAnnotatedTypeFactory.java:1497)
        at org.checkerframework.framework.type.GenericAnnotatedTypeFactory.performFlowAnalysis(GenericAnnotatedTypeFactory.java:1394)
        at org.checkerframework.framework.type.GenericAnnotatedTypeFactory.checkAndPerformFlowAnalysis(GenericAnnotatedTypeFactory.java:1828)
        at org.checkerframework.framework.type.GenericAnnotatedTypeFactory.preProcessClassTree(GenericAnnotatedTypeFactory.java:414)
        at org.checkerframework.common.basetype.BaseTypeVisitor.visitClass(BaseTypeVisitor.java:476)
        at org.checkerframework.common.basetype.BaseTypeVisitor.visitClass(BaseTypeVisitor.java:181)
        at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCClassDecl.accept(JCTree.java:860)
        at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:60)
        at org.checkerframework.framework.source.SourceVisitor.visit(SourceVisitor.java:82)
        at org.checkerframework.framework.source.SourceChecker.typeProcess(SourceChecker.java:987)
        at org.checkerframework.common.basetype.BaseTypeChecker.typeProcess(BaseTypeChecker.java:542)
        at org.checkerframework.javacutil.AbstractTypeProcessor$AttributionTaskListener.finished(AbstractTypeProcessor.java:188)
        at jdk.compiler/com.sun.tools.javac.api.ClientCodeWrapper$WrappedTaskListener.finished(ClientCodeWrapper.java:854)
        at jdk.compiler/com.sun.tools.javac.api.MultiTaskListener.finished(MultiTaskListener.java:132)
        at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1394)
        at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1351)
        at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:946)
        at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:317)
        at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:176)
        at jdk.compiler/com.sun.tools.javac.Main.compile(Main.java:64)
        at jdk.compiler/com.sun.tools.javac.Main.main(Main.java:50)
  Caused by: java.lang.Throwable
        at org.checkerframework.javacutil.BugInCF.<init>(BugInCF.java:34)
        ... 59 more

  Underlying Exception: java.lang.Throwable; java.lang.Throwable
        at org.checkerframework.javacutil.BugInCF.<init>(BugInCF.java:34)
        at org.checkerframework.dataflow.expression.JavaExpression.fromVariableElement(JavaExpression.java:526)
        at org.checkerframework.dataflow.expression.JavaExpression.fromTree(JavaExpression.java:440)
        at org.checkerframework.dataflow.expression.JavaExpression.getReceiver(JavaExpression.java:610)
        at org.checkerframework.dataflow.expression.JavaExpression.atMethodInvocation(JavaExpression.java:703)
        at org.checkerframework.framework.util.StringToJavaExpression.atMethodInvocation(StringToJavaExpression.java:195)
        at org.checkerframework.framework.util.dependenttypes.DependentTypesHelper.lambda$atInvocation$1(DependentTypesHelper.java:315)
        at org.checkerframework.framework.util.dependenttypes.DependentTypesHelper.convertAnnotationMirror(DependentTypesHelper.java:711)
        at org.checkerframework.framework.util.dependenttypes.DependentTypesHelper.lambda$convertAnnotatedTypeMirror$12(DependentTypesHelper.java:663)
        at org.checkerframework.framework.util.dependenttypes.DependentTypesHelper$AnnotatedTypeReplacer.scan(DependentTypesHelper.java:869)
        at org.checkerframework.framework.util.dependenttypes.DependentTypesHelper$AnnotatedTypeReplacer.scan(DependentTypesHelper.java:836)
        at org.checkerframework.framework.type.visitor.AnnotatedTypeScanner.visitExecutable(AnnotatedTypeScanner.java:313)
        at org.checkerframework.framework.type.AnnotatedTypeMirror$AnnotatedExecutableType.accept(AnnotatedTypeMirror.java:1149)
        at org.checkerframework.framework.type.visitor.AnnotatedTypeScanner.scan(AnnotatedTypeScanner.java:206)
        at org.checkerframework.framework.util.dependenttypes.DependentTypesHelper$AnnotatedTypeReplacer.scan(DependentTypesHelper.java:881)
        at org.checkerframework.framework.util.dependenttypes.DependentTypesHelper$AnnotatedTypeReplacer.scan(DependentTypesHelper.java:836)
        at org.checkerframework.framework.type.visitor.AnnotatedTypeScanner.visit(AnnotatedTypeScanner.java:194)
        at org.checkerframework.framework.util.dependenttypes.DependentTypesHelper.convertAnnotatedTypeMirror(DependentTypesHelper.java:663)
        at org.checkerframework.framework.util.dependenttypes.DependentTypesHelper.atInvocation(DependentTypesHelper.java:335)
        at org.checkerframework.framework.util.dependenttypes.DependentTypesHelper.atMethodInvocation(DependentTypesHelper.java:254)
        at org.checkerframework.framework.type.GenericAnnotatedTypeFactory.methodFromUse(GenericAnnotatedTypeFactory.java:2023)
        at org.checkerframework.framework.type.TypeFromExpressionVisitor.visitMethodInvocation(TypeFromExpressionVisitor.java:357)
        at org.checkerframework.framework.type.TypeFromExpressionVisitor.visitMethodInvocation(TypeFromExpressionVisitor.java:72)
        at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCMethodInvocation.accept(JCTree.java:1813)
        at jdk.compiler/com.sun.source.util.SimpleTreeVisitor.visit(SimpleTreeVisitor.java:81)
        at org.checkerframework.framework.type.TypeFromTree.fromExpression(TypeFromTree.java:40)
        at org.checkerframework.framework.type.AnnotatedTypeFactory.fromExpression(AnnotatedTypeFactory.java:1555)
        at org.checkerframework.framework.type.AnnotatedTypeFactory.getAnnotatedType(AnnotatedTypeFactory.java:1245)
        at org.checkerframework.framework.flow.CFAbstractTransfer.getValueFromFactory(CFAbstractTransfer.java:203)
        at org.checkerframework.checker.index.upperbound.UpperBoundTransfer.getUBQualifier(UpperBoundTransfer.java:795)
        at org.checkerframework.checker.index.upperbound.UpperBoundTransfer.visitLengthAccess(UpperBoundTransfer.java:681)
        at org.checkerframework.checker.index.upperbound.UpperBoundTransfer.visitMethodInvocation(UpperBoundTransfer.java:723)
        at org.checkerframework.checker.index.upperbound.UpperBoundTransfer.visitMethodInvocation(UpperBoundTransfer.java:107)
        at org.checkerframework.dataflow.cfg.node.MethodInvocationNode.accept(MethodInvocationNode.java:119)
        at org.checkerframework.dataflow.analysis.AbstractAnalysis.callTransferFunction(AbstractAnalysis.java:334)
        at org.checkerframework.dataflow.analysis.ForwardAnalysisImpl.callTransferFunction(ForwardAnalysisImpl.java:372)
        at org.checkerframework.dataflow.analysis.ForwardAnalysisImpl.performAnalysisBlock(ForwardAnalysisImpl.java:151)
        at org.checkerframework.dataflow.analysis.ForwardAnalysisImpl.performAnalysis(ForwardAnalysisImpl.java:105)
        at org.checkerframework.framework.flow.CFAbstractAnalysis.performAnalysis(CFAbstractAnalysis.java:146)
        at org.checkerframework.framework.type.GenericAnnotatedTypeFactory.analyze(GenericAnnotatedTypeFactory.java:1497)
        at org.checkerframework.framework.type.GenericAnnotatedTypeFactory.performFlowAnalysis(GenericAnnotatedTypeFactory.java:1394)
        at org.checkerframework.framework.type.GenericAnnotatedTypeFactory.checkAndPerformFlowAnalysis(GenericAnnotatedTypeFactory.java:1828)
        at org.checkerframework.framework.type.GenericAnnotatedTypeFactory.preProcessClassTree(GenericAnnotatedTypeFactory.java:414)
        at org.checkerframework.common.basetype.BaseTypeVisitor.visitClass(BaseTypeVisitor.java:476)
        at org.checkerframework.common.basetype.BaseTypeVisitor.visitClass(BaseTypeVisitor.java:181)
        at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCClassDecl.accept(JCTree.java:860)
        at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:60)
        at org.checkerframework.framework.source.SourceVisitor.visit(SourceVisitor.java:82)
        at org.checkerframework.framework.source.SourceChecker.typeProcess(SourceChecker.java:987)
        at org.checkerframework.common.basetype.BaseTypeChecker.typeProcess(BaseTypeChecker.java:542)
        at org.checkerframework.javacutil.AbstractTypeProcessor$AttributionTaskListener.finished(AbstractTypeProcessor.java:188)
        at jdk.compiler/com.sun.tools.javac.api.ClientCodeWrapper$WrappedTaskListener.finished(ClientCodeWrapper.java:854)
        at jdk.compiler/com.sun.tools.javac.api.MultiTaskListener.finished(MultiTaskListener.java:132)
        at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1394)
        at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1351)
        at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:946)
        at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:317)
        at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:176)
        at jdk.compiler/com.sun.tools.javac.Main.compile(Main.java:64)
        at jdk.compiler/com.sun.tools.javac.Main.main(Main.java:50)
1 error

Other checkers do not seem to have this issue and compile fine when pattern matching is present.

@kelloggm
Copy link
Contributor

Thanks for reporting this issue, and sorry you encountered it! I've written a fix that works when I test it on the command-line, but causes an (unrelated?) problem in the Index Checker test suite. If this is blocking you, hopefully that will unblock you in the short-term; we'll work on getting that other issue fixed and the patch landed in the mean time.

Other checkers do not seem to have this issue and compile fine when pattern matching is present.

The reason for this is that most checkers don't use strings (i.e. variable names) to look up JavaExpressions, which the Index Checker uses to match the argument of e.g. an @IndexFor annotation to the corresponding in-scope array. The bug was in that code's handling of variable declarations, which didn't account for binding variables.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants