From dc8ee8eb42ca9b9b2e41bc183bd0a036030c439f Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Wed, 2 Aug 2023 01:40:47 -0400 Subject: [PATCH 01/39] fix typo --- .../checker/initialization/InitializationTransfer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checker/src/main/java/org/checkerframework/checker/initialization/InitializationTransfer.java b/checker/src/main/java/org/checkerframework/checker/initialization/InitializationTransfer.java index f3fd93b79b3..f46ef5eba09 100644 --- a/checker/src/main/java/org/checkerframework/checker/initialization/InitializationTransfer.java +++ b/checker/src/main/java/org/checkerframework/checker/initialization/InitializationTransfer.java @@ -168,7 +168,7 @@ public TransferResult visitAssignment(AssignmentNode n, TransferInput Date: Wed, 2 Aug 2023 03:02:28 -0400 Subject: [PATCH 02/39] fix typo --- .../org/checkerframework/framework/flow/CFAbstractTransfer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/src/main/java/org/checkerframework/framework/flow/CFAbstractTransfer.java b/framework/src/main/java/org/checkerframework/framework/flow/CFAbstractTransfer.java index 99ccb3645f7..13833b8ab0e 100644 --- a/framework/src/main/java/org/checkerframework/framework/flow/CFAbstractTransfer.java +++ b/framework/src/main/java/org/checkerframework/framework/flow/CFAbstractTransfer.java @@ -589,7 +589,7 @@ protected TransferResult createTransferResult(@Nullable V value, TransferI * * @param value the value; possibly null * @param in the TransferResult to copy - * @return the input informatio + * @return the input information */ @SideEffectFree protected TransferResult recreateTransferResult( From c5f519aecda52b1c2371fc34b0a7610ed835e717 Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Wed, 2 Aug 2023 14:49:53 -0400 Subject: [PATCH 03/39] fix typo --- .../org/checkerframework/dataflow/cfg/node/FieldAccessNode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/FieldAccessNode.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/FieldAccessNode.java index 3051ed91755..a56d986e586 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/FieldAccessNode.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/FieldAccessNode.java @@ -36,7 +36,7 @@ public class FieldAccessNode extends Node { * Creates a new FieldAccessNode. * * @param tree the tree from which to create a FieldAccessNode - * @param receiver the receiver for the resuling FieldAccessNode + * @param receiver the receiver for the resulting FieldAccessNode */ public FieldAccessNode(Tree tree, Node receiver) { super(TreeUtils.typeOf(tree)); From a6980cac800cfa4f00b0772a9bceba569b96d68c Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Wed, 2 Aug 2023 18:19:13 -0400 Subject: [PATCH 04/39] fix typo --- .../org/checkerframework/checker/optional/OptionalChecker.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checker/src/main/java/org/checkerframework/checker/optional/OptionalChecker.java b/checker/src/main/java/org/checkerframework/checker/optional/OptionalChecker.java index f804f943d73..fca4c4b4273 100644 --- a/checker/src/main/java/org/checkerframework/checker/optional/OptionalChecker.java +++ b/checker/src/main/java/org/checkerframework/checker/optional/OptionalChecker.java @@ -10,7 +10,7 @@ * * @checker_framework.manual #optional-checker Optional Checker */ -// TODO: For a call to ofNullable, if the argument has type @NonNull, make the return type have type +// TODO: For a call to of Nullable, if the argument has type @NonNull, make the return type have type // @Present. Make Optional Checker a subchecker of the Nullness Checker. @RelevantJavaTypes(Optional.class) public class OptionalChecker extends BaseTypeChecker {} From b9d3d643538ceb4ce2089eec4fde48b9ca8f8926 Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Thu, 3 Aug 2023 21:07:51 -0400 Subject: [PATCH 05/39] test changes --- .../EISOPissue548/ConservativeClassLiteral.java | 15 +++++++++++++++ checker/jtreg/nullness/EISOPissue548/MyEnum.java | 3 +++ .../checker/nullness/NullnessTransfer.java | 9 +++++++++ .../common/basetype/BaseTypeVisitor.java | 14 ++++++++------ 4 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 checker/jtreg/nullness/EISOPissue548/ConservativeClassLiteral.java create mode 100644 checker/jtreg/nullness/EISOPissue548/MyEnum.java diff --git a/checker/jtreg/nullness/EISOPissue548/ConservativeClassLiteral.java b/checker/jtreg/nullness/EISOPissue548/ConservativeClassLiteral.java new file mode 100644 index 00000000000..246648a4e53 --- /dev/null +++ b/checker/jtreg/nullness/EISOPissue548/ConservativeClassLiteral.java @@ -0,0 +1,15 @@ +/* + * @test + * @summary Test class literals in CFGs and their type with conservative nullness. + * + * @compile MyEnum.java + * @compile -processor org.checkerframework.checker.nullness.NullnessChecker -AuseConservativeDefaultsForUncheckedCode=bytecode,-source ConservativeClassLiteral.java + */ + +import java.util.EnumSet; + +class ConservativeClassLiteral { + EnumSet none() { + return EnumSet.noneOf(MyEnum.class); + } +} diff --git a/checker/jtreg/nullness/EISOPissue548/MyEnum.java b/checker/jtreg/nullness/EISOPissue548/MyEnum.java new file mode 100644 index 00000000000..c4b60a93a39 --- /dev/null +++ b/checker/jtreg/nullness/EISOPissue548/MyEnum.java @@ -0,0 +1,3 @@ +enum MyEnum { + VALUE; +} diff --git a/checker/src/main/java/org/checkerframework/checker/nullness/NullnessTransfer.java b/checker/src/main/java/org/checkerframework/checker/nullness/NullnessTransfer.java index 5e594dc0cc9..cf292d85a71 100644 --- a/checker/src/main/java/org/checkerframework/checker/nullness/NullnessTransfer.java +++ b/checker/src/main/java/org/checkerframework/checker/nullness/NullnessTransfer.java @@ -10,6 +10,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.common.basetype.BaseTypeChecker; import org.checkerframework.dataflow.analysis.ConditionalTransferResult; +import org.checkerframework.dataflow.analysis.RegularTransferResult; import org.checkerframework.dataflow.analysis.TransferInput; import org.checkerframework.dataflow.analysis.TransferResult; import org.checkerframework.dataflow.cfg.node.ArrayAccessNode; @@ -351,6 +352,14 @@ public TransferResult visitMethodAccess( @Override public TransferResult visitFieldAccess( FieldAccessNode n, TransferInput p) { + if (n.getFieldName().equals("class")) { + NullnessStore store = p.getRegularStore(); + NullnessValue storeValue = store.getValue(n); + TransferResult result = + new RegularTransferResult(storeValue, store); + makeNonNull(result, n.getReceiver()); + return result; + } TransferResult result = super.visitFieldAccess(n, p); makeNonNull(result, n.getReceiver()); return result; diff --git a/framework/src/main/java/org/checkerframework/common/basetype/BaseTypeVisitor.java b/framework/src/main/java/org/checkerframework/common/basetype/BaseTypeVisitor.java index 0b1be9798d2..8e8f546776c 100644 --- a/framework/src/main/java/org/checkerframework/common/basetype/BaseTypeVisitor.java +++ b/framework/src/main/java/org/checkerframework/common/basetype/BaseTypeVisitor.java @@ -3103,12 +3103,14 @@ protected void commonAssignmentCheck( Tree valueExpTree, @CompilerMessageKey String errorKey, Object... extraArgs) { - - commonAssignmentCheckStartDiagnostic(varType, valueType, valueExpTree); - - AnnotatedTypeMirror widenedValueType = atypeFactory.getWidenedType(valueType, varType); - boolean success = atypeFactory.getTypeHierarchy().isSubtype(widenedValueType, varType); - + boolean success; + if (valueExpTree.toString().endsWith(".class")) { + success = true; + } else { + commonAssignmentCheckStartDiagnostic(varType, valueType, valueExpTree); + AnnotatedTypeMirror widenedValueType = atypeFactory.getWidenedType(valueType, varType); + success = atypeFactory.getTypeHierarchy().isSubtype(widenedValueType, varType); + } // TODO: integrate with subtype test. if (success) { for (Class mono : From 4b73445c6d0ea38dda4b09c16d4d56af5982da5e Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Fri, 4 Aug 2023 03:02:37 -0400 Subject: [PATCH 06/39] apply spotless --- .../org/checkerframework/common/basetype/BaseTypeVisitor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/src/main/java/org/checkerframework/common/basetype/BaseTypeVisitor.java b/framework/src/main/java/org/checkerframework/common/basetype/BaseTypeVisitor.java index 8e8f546776c..b0d72136aae 100644 --- a/framework/src/main/java/org/checkerframework/common/basetype/BaseTypeVisitor.java +++ b/framework/src/main/java/org/checkerframework/common/basetype/BaseTypeVisitor.java @@ -3109,7 +3109,7 @@ protected void commonAssignmentCheck( } else { commonAssignmentCheckStartDiagnostic(varType, valueType, valueExpTree); AnnotatedTypeMirror widenedValueType = atypeFactory.getWidenedType(valueType, varType); - success = atypeFactory.getTypeHierarchy().isSubtype(widenedValueType, varType); + success = atypeFactory.getTypeHierarchy().isSubtype(widenedValueType, varType); } // TODO: integrate with subtype test. if (success) { From 92248dc6bbf986ddd9351aaee157cd7e22cc1834 Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Fri, 4 Aug 2023 19:13:29 -0400 Subject: [PATCH 07/39] apply spotless --- .../checkerframework/checker/optional/OptionalChecker.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/checker/src/main/java/org/checkerframework/checker/optional/OptionalChecker.java b/checker/src/main/java/org/checkerframework/checker/optional/OptionalChecker.java index fca4c4b4273..aa78b92148f 100644 --- a/checker/src/main/java/org/checkerframework/checker/optional/OptionalChecker.java +++ b/checker/src/main/java/org/checkerframework/checker/optional/OptionalChecker.java @@ -10,7 +10,7 @@ * * @checker_framework.manual #optional-checker Optional Checker */ -// TODO: For a call to of Nullable, if the argument has type @NonNull, make the return type have type -// @Present. Make Optional Checker a subchecker of the Nullness Checker. +// TODO: For a call to of Nullable, if the argument has type @NonNull, make the return type have +// type @Present. Make Optional Checker a subchecker of the Nullness Checker. @RelevantJavaTypes(Optional.class) public class OptionalChecker extends BaseTypeChecker {} From 00a3855e84a03483fcad4f856a6977a51beda0dc Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Mon, 7 Aug 2023 23:02:26 -0400 Subject: [PATCH 08/39] test pipelines --- checker/tests/nullness/Issue3020.java | 1 + 1 file changed, 1 insertion(+) diff --git a/checker/tests/nullness/Issue3020.java b/checker/tests/nullness/Issue3020.java index b8d735d9eba..e98d5a723fc 100644 --- a/checker/tests/nullness/Issue3020.java +++ b/checker/tests/nullness/Issue3020.java @@ -4,6 +4,7 @@ enum Issue3020 { void retrieveConstant() { Class theClass = Issue3020.class; // :: error: (accessing.nullable) + // :: error: (dereference.of.nullable) Object unused = passThrough(theClass.getEnumConstants())[0]; } From 17e79e3234df196cd30187ad4fc92b12d80d7a58 Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Mon, 16 Oct 2023 01:18:26 -0400 Subject: [PATCH 09/39] initial commit --- .../InitializationParentAnnotatedTypeFactory.java | 4 ++++ .../checker/nullness/NullnessNoInitAnnotatedTypeFactory.java | 3 +++ checker/tests/nullness/Issue3020.java | 1 - .../dataflow/cfg/builder/CFGTranslationPhaseOne.java | 2 +- .../org/checkerframework/dataflow/cfg/node/ClassNameNode.java | 4 +++- .../main/java/org/checkerframework/javacutil/TreeUtils.java | 2 +- 6 files changed, 12 insertions(+), 4 deletions(-) diff --git a/checker/src/main/java/org/checkerframework/checker/initialization/InitializationParentAnnotatedTypeFactory.java b/checker/src/main/java/org/checkerframework/checker/initialization/InitializationParentAnnotatedTypeFactory.java index 39b13e367bd..775ec0f9bdb 100644 --- a/checker/src/main/java/org/checkerframework/checker/initialization/InitializationParentAnnotatedTypeFactory.java +++ b/checker/src/main/java/org/checkerframework/checker/initialization/InitializationParentAnnotatedTypeFactory.java @@ -779,6 +779,10 @@ public Void visitNewArray(NewArrayTree tree, AnnotatedTypeMirror type) { @Override public Void visitMemberSelect( MemberSelectTree tree, AnnotatedTypeMirror annotatedTypeMirror) { + Element elt = TreeUtils.elementFromUse(tree); + if (elt.toString().equals("class")) { + annotatedTypeMirror.replaceAnnotation(INITIALIZED); + } if (TreeUtils.isArrayLengthAccess(tree)) { annotatedTypeMirror.replaceAnnotation(INITIALIZED); } diff --git a/checker/src/main/java/org/checkerframework/checker/nullness/NullnessNoInitAnnotatedTypeFactory.java b/checker/src/main/java/org/checkerframework/checker/nullness/NullnessNoInitAnnotatedTypeFactory.java index 9d55f343a6a..5ef1f66e8aa 100644 --- a/checker/src/main/java/org/checkerframework/checker/nullness/NullnessNoInitAnnotatedTypeFactory.java +++ b/checker/src/main/java/org/checkerframework/checker/nullness/NullnessNoInitAnnotatedTypeFactory.java @@ -670,6 +670,9 @@ public Void visitMemberSelect(MemberSelectTree tree, AnnotatedTypeMirror type) { type.replaceAnnotation(NONNULL); } + if (elt.toString().equals("class")) { + type.replaceAnnotation(NONNULL); + } return null; } diff --git a/checker/tests/nullness/Issue3020.java b/checker/tests/nullness/Issue3020.java index e98d5a723fc..b8d735d9eba 100644 --- a/checker/tests/nullness/Issue3020.java +++ b/checker/tests/nullness/Issue3020.java @@ -4,7 +4,6 @@ enum Issue3020 { void retrieveConstant() { Class theClass = Issue3020.class; // :: error: (accessing.nullable) - // :: error: (dereference.of.nullable) Object unused = passThrough(theClass.getEnumConstants())[0]; } diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/CFGTranslationPhaseOne.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/CFGTranslationPhaseOne.java index 9dc97a5cbfe..a1aa7b5b1da 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/CFGTranslationPhaseOne.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/CFGTranslationPhaseOne.java @@ -3585,7 +3585,7 @@ public Node visitMemberSelect(MemberSelectTree tree, Void p) { if (!TreeUtils.isFieldAccess(tree)) { // Could be a selector of a class or package Element element = TreeUtils.elementFromUse(tree); - if (ElementUtils.isTypeElement(element)) { + if (ElementUtils.isTypeElement(element) || element.toString().equals("class")) { ClassNameNode result = new ClassNameNode(tree, expr); extendWithClassNameNode(result); return result; diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/ClassNameNode.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/ClassNameNode.java index b34299862fc..7f5f0db1c23 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/ClassNameNode.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/ClassNameNode.java @@ -63,7 +63,9 @@ public ClassNameNode(MemberSelectTree tree, Node parent) { this.tree = tree; assert TreeUtils.isUseOfElement(tree) : "@AssumeAssertion(nullness): tree kind"; Element element = TreeUtils.elementFromUse(tree); - assert element instanceof TypeElement || element instanceof TypeParameterElement + assert element instanceof TypeElement + || element instanceof TypeParameterElement + || element.toString().equals("class") : "@AssumeAssertion(nullness)"; this.element = element; this.parent = parent; diff --git a/javacutil/src/main/java/org/checkerframework/javacutil/TreeUtils.java b/javacutil/src/main/java/org/checkerframework/javacutil/TreeUtils.java index 850770dc6ba..c455a0216aa 100644 --- a/javacutil/src/main/java/org/checkerframework/javacutil/TreeUtils.java +++ b/javacutil/src/main/java/org/checkerframework/javacutil/TreeUtils.java @@ -1570,7 +1570,7 @@ public static boolean isFieldAccess(Tree tree) { MemberSelectTree memberSelect = (MemberSelectTree) tree; assert isUseOfElement(memberSelect) : "@AssumeAssertion(nullness): tree kind"; Element el = TreeUtils.elementFromUse(memberSelect); - if (el.getKind().isField()) { + if (el.getKind().isField() && !el.toString().equals("class")) { return (VariableElement) el; } } else if (tree.getKind() == Tree.Kind.IDENTIFIER) { From ec79fa27f37ea7133f12696c0ce3fb13ccf804b7 Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Sun, 15 Dec 2024 03:43:48 -0500 Subject: [PATCH 10/39] Add new Class literalNode and remove hardcode fix --- ...tializationParentAnnotatedTypeFactory.java | 6 +-- .../NullnessNoInitAnnotatedTypeFactory.java | 5 ++- .../cfg/builder/CFGTranslationPhaseOne.java | 5 +++ .../cfg/node/AbstractNodeVisitor.java | 5 +++ .../dataflow/cfg/node/ClassLiteralNode.java | 41 +++++++++++++++++++ .../dataflow/cfg/node/NodeVisitor.java | 2 + .../dataflow/expression/JavaExpression.java | 2 +- .../checkerframework/javacutil/TreeUtils.java | 8 ++-- 8 files changed, 61 insertions(+), 13 deletions(-) create mode 100644 dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/ClassLiteralNode.java diff --git a/checker/src/main/java/org/checkerframework/checker/initialization/InitializationParentAnnotatedTypeFactory.java b/checker/src/main/java/org/checkerframework/checker/initialization/InitializationParentAnnotatedTypeFactory.java index 2596c473962..209c0247726 100644 --- a/checker/src/main/java/org/checkerframework/checker/initialization/InitializationParentAnnotatedTypeFactory.java +++ b/checker/src/main/java/org/checkerframework/checker/initialization/InitializationParentAnnotatedTypeFactory.java @@ -793,11 +793,7 @@ public Void visitNewArray(NewArrayTree tree, AnnotatedTypeMirror type) { @Override public Void visitMemberSelect( MemberSelectTree tree, AnnotatedTypeMirror annotatedTypeMirror) { - Element elt = TreeUtils.elementFromUse(tree); - if (elt.toString().equals("class")) { - annotatedTypeMirror.replaceAnnotation(INITIALIZED); - } - if (TreeUtils.isArrayLengthAccess(tree)) { + if (TreeUtils.isArrayLengthAccess(tree) || TreeUtils.isClassLiteral(tree)) { annotatedTypeMirror.replaceAnnotation(INITIALIZED); } return super.visitMemberSelect(tree, annotatedTypeMirror); diff --git a/checker/src/main/java/org/checkerframework/checker/nullness/NullnessNoInitAnnotatedTypeFactory.java b/checker/src/main/java/org/checkerframework/checker/nullness/NullnessNoInitAnnotatedTypeFactory.java index 0bbc11cd317..2cb37fcd2b3 100644 --- a/checker/src/main/java/org/checkerframework/checker/nullness/NullnessNoInitAnnotatedTypeFactory.java +++ b/checker/src/main/java/org/checkerframework/checker/nullness/NullnessNoInitAnnotatedTypeFactory.java @@ -667,9 +667,10 @@ public Void visitMemberSelect(MemberSelectTree tree, AnnotatedTypeMirror type) { Element elt = TreeUtils.elementFromUse(tree); assert elt != null; - // Make primitive variable @NonNull in case the Initialization Checker + // Make primitive variable and class literal @NonNull in case the Initialization Checker // considers it uninitialized. - if (TypesUtils.isPrimitive(type.getUnderlyingType())) { + if (TypesUtils.isPrimitive(type.getUnderlyingType()) + || TreeUtils.isClassLiteral(tree)) { type.replaceAnnotation(NONNULL); } diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/CFGTranslationPhaseOne.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/CFGTranslationPhaseOne.java index 17ea2d8cb8b..9015244507c 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/CFGTranslationPhaseOne.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/CFGTranslationPhaseOne.java @@ -77,6 +77,7 @@ import org.checkerframework.dataflow.cfg.node.CatchMarkerNode; import org.checkerframework.dataflow.cfg.node.CharacterLiteralNode; import org.checkerframework.dataflow.cfg.node.ClassDeclarationNode; +import org.checkerframework.dataflow.cfg.node.ClassLiteralNode; import org.checkerframework.dataflow.cfg.node.ClassNameNode; import org.checkerframework.dataflow.cfg.node.ConditionalAndNode; import org.checkerframework.dataflow.cfg.node.ConditionalNotNode; @@ -3671,6 +3672,10 @@ public Node visitMemberSelect(MemberSelectTree tree, Void p) { Node result = new PackageNameNode(tree, (PackageNameNode) expr); extendWithNode(result); return result; + } else if (element.getKind() == ElementKind.FIELD) { + Node result = new ClassLiteralNode(tree); + extendWithNode((ClassLiteralNode) result); + return result; } else { throw new BugInCF("Unexpected element kind: " + element.getKind()); } diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/AbstractNodeVisitor.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/AbstractNodeVisitor.java index 4f04678f1a4..0982c82dbc8 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/AbstractNodeVisitor.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/AbstractNodeVisitor.java @@ -66,6 +66,11 @@ public R visitNullLiteral(NullLiteralNode n, P p) { return visitValueLiteral(n, p); } + @Override + public R visitClassLiteral(ClassLiteralNode n, P p) { + return visitNode(n, p); + } + // Unary operations @Override public R visitNumericalMinus(NumericalMinusNode n, P p) { diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/ClassLiteralNode.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/ClassLiteralNode.java new file mode 100644 index 00000000000..ea2687aadb6 --- /dev/null +++ b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/ClassLiteralNode.java @@ -0,0 +1,41 @@ +package org.checkerframework.dataflow.cfg.node; + +import com.sun.source.tree.MemberSelectTree; +import com.sun.source.tree.Tree; + +import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.javacutil.TreeUtils; + +import java.util.Collection; +import java.util.Collections; + +/** A node for a class literal. For example: {@code String.class}. */ +public class ClassLiteralNode extends Node { + /** The tree for the class literal. */ + protected final Tree tree; + + /** + * Create a new ClassLiteralNode. + * + * @param tree the class literal + */ + public ClassLiteralNode(MemberSelectTree tree) { + super(TreeUtils.typeOf(tree)); + this.tree = tree; + } + + @Override + public @Nullable Tree getTree() { + return tree; + } + + @Override + public R accept(NodeVisitor visitor, P p) { + return visitor.visitClassLiteral(this, p); + } + + @Override + public Collection getOperands() { + return Collections.emptyList(); + } +} diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/NodeVisitor.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/NodeVisitor.java index 20211a9619b..9562ee6cb74 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/NodeVisitor.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/NodeVisitor.java @@ -28,6 +28,8 @@ public interface NodeVisitor { R visitNullLiteral(NullLiteralNode n, P p); + R visitClassLiteral(ClassLiteralNode n, P p); + // Unary operations R visitNumericalMinus(NumericalMinusNode n, P p); diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/expression/JavaExpression.java b/dataflow/src/main/java/org/checkerframework/dataflow/expression/JavaExpression.java index d55fd6eefb2..dc4404998d0 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/expression/JavaExpression.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/expression/JavaExpression.java @@ -243,7 +243,7 @@ public static JavaExpression fromNodeFieldAccess(FieldAccessNode node) { // access. return new ThisReference(receiverNode.getType()); } else if (fieldName.equals("class")) { - // The CFG represents "className.class" as a FieldAccessNode; bit it is a class literal. + // The CFG represents "className.class" as a FieldAccessNode; but it is a class literal. return new ClassName(receiverNode.getType()); } JavaExpression receiver; diff --git a/javacutil/src/main/java/org/checkerframework/javacutil/TreeUtils.java b/javacutil/src/main/java/org/checkerframework/javacutil/TreeUtils.java index 0fc453a1e29..44f7ae13721 100644 --- a/javacutil/src/main/java/org/checkerframework/javacutil/TreeUtils.java +++ b/javacutil/src/main/java/org/checkerframework/javacutil/TreeUtils.java @@ -1437,8 +1437,6 @@ public static boolean isClassLiteral(Tree tree) { * obj . f * * - * This method currently also returns true for class literals and qualified this. - * * @param tree a tree that might be a field access * @return true iff if tree is a field access expression (implicit or explicit) */ @@ -1454,17 +1452,17 @@ public static boolean isFieldAccess(Tree tree) { * obj . f * * - * This method currently also returns a non-null value for class literals and qualified this. - * * @param tree a tree that might be a field access * @return the element if tree is a field access expression (implicit or explicit); null * otherwise */ - // TODO: fix value for class literals and qualified this, which are not field accesses. public static @Nullable VariableElement asFieldAccess(Tree tree) { if (tree.getKind() == Tree.Kind.MEMBER_SELECT) { // explicit member access (or a class literal or a qualified this) MemberSelectTree memberSelect = (MemberSelectTree) tree; + if (isClassLiteral(memberSelect) || isExplicitThisDereference(memberSelect)) { + return null; + } assert isUseOfElement(memberSelect) : "@AssumeAssertion(nullness): tree kind"; Element el = TreeUtils.elementFromUse(memberSelect); if (el.getKind().isField() && !el.toString().equals("class")) { From d896862c9666841c609a6e5f148f4110bad86e09 Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Sun, 15 Dec 2024 03:46:23 -0500 Subject: [PATCH 11/39] Clean up old hardcoding --- .../checker/nullness/NullnessNoInitAnnotatedTypeFactory.java | 3 --- .../dataflow/cfg/builder/CFGTranslationPhaseOne.java | 2 +- .../org/checkerframework/dataflow/cfg/node/ClassNameNode.java | 4 +--- .../main/java/org/checkerframework/javacutil/TreeUtils.java | 2 +- 4 files changed, 3 insertions(+), 8 deletions(-) diff --git a/checker/src/main/java/org/checkerframework/checker/nullness/NullnessNoInitAnnotatedTypeFactory.java b/checker/src/main/java/org/checkerframework/checker/nullness/NullnessNoInitAnnotatedTypeFactory.java index 2cb37fcd2b3..9fd622fd1e4 100644 --- a/checker/src/main/java/org/checkerframework/checker/nullness/NullnessNoInitAnnotatedTypeFactory.java +++ b/checker/src/main/java/org/checkerframework/checker/nullness/NullnessNoInitAnnotatedTypeFactory.java @@ -674,9 +674,6 @@ public Void visitMemberSelect(MemberSelectTree tree, AnnotatedTypeMirror type) { type.replaceAnnotation(NONNULL); } - if (elt.toString().equals("class")) { - type.replaceAnnotation(NONNULL); - } return null; } diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/CFGTranslationPhaseOne.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/CFGTranslationPhaseOne.java index 9015244507c..5e1e46cfd58 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/CFGTranslationPhaseOne.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/CFGTranslationPhaseOne.java @@ -3664,7 +3664,7 @@ public Node visitMemberSelect(MemberSelectTree tree, Void p) { if (!TreeUtils.isFieldAccess(tree)) { // Could be a selector of a class or package Element element = TreeUtils.elementFromUse(tree); - if (ElementUtils.isTypeElement(element) || element.toString().equals("class")) { + if (ElementUtils.isTypeElement(element)) { ClassNameNode result = new ClassNameNode(tree, expr); extendWithClassNameNode(result); return result; diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/ClassNameNode.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/ClassNameNode.java index 7f5f0db1c23..b34299862fc 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/ClassNameNode.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/ClassNameNode.java @@ -63,9 +63,7 @@ public ClassNameNode(MemberSelectTree tree, Node parent) { this.tree = tree; assert TreeUtils.isUseOfElement(tree) : "@AssumeAssertion(nullness): tree kind"; Element element = TreeUtils.elementFromUse(tree); - assert element instanceof TypeElement - || element instanceof TypeParameterElement - || element.toString().equals("class") + assert element instanceof TypeElement || element instanceof TypeParameterElement : "@AssumeAssertion(nullness)"; this.element = element; this.parent = parent; diff --git a/javacutil/src/main/java/org/checkerframework/javacutil/TreeUtils.java b/javacutil/src/main/java/org/checkerframework/javacutil/TreeUtils.java index 44f7ae13721..40c86f4905d 100644 --- a/javacutil/src/main/java/org/checkerframework/javacutil/TreeUtils.java +++ b/javacutil/src/main/java/org/checkerframework/javacutil/TreeUtils.java @@ -1465,7 +1465,7 @@ public static boolean isFieldAccess(Tree tree) { } assert isUseOfElement(memberSelect) : "@AssumeAssertion(nullness): tree kind"; Element el = TreeUtils.elementFromUse(memberSelect); - if (el.getKind().isField() && !el.toString().equals("class")) { + if (el.getKind().isField()) { return (VariableElement) el; } } else if (tree.getKind() == Tree.Kind.IDENTIFIER) { From 4990cc9806483b7555a79d010bc1e07ab72ef0ba Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Sun, 15 Dec 2024 04:07:33 -0500 Subject: [PATCH 12/39] Override toString to use correct name for class literal --- .../checkerframework/dataflow/cfg/node/ClassLiteralNode.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/ClassLiteralNode.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/ClassLiteralNode.java index ea2687aadb6..4bc8603eea6 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/ClassLiteralNode.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/ClassLiteralNode.java @@ -34,6 +34,11 @@ public R accept(NodeVisitor visitor, P p) { return visitor.visitClassLiteral(this, p); } + @Override + public String toString() { + return tree.toString(); + } + @Override public Collection getOperands() { return Collections.emptyList(); From 2d1aea1f62d62d539c6a439301c854569e58da01 Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Sun, 15 Dec 2024 04:17:34 -0500 Subject: [PATCH 13/39] Update expected CFG --- .../nullness-extra/issue5174/Issue5174.out | 473 +++++++++--------- 1 file changed, 228 insertions(+), 245 deletions(-) diff --git a/checker/tests/nullness-extra/issue5174/Issue5174.out b/checker/tests/nullness-extra/issue5174/Issue5174.out index d4144a111ab..5dc7ec12a11 100644 --- a/checker/tests/nullness-extra/issue5174/Issue5174.out +++ b/checker/tests/nullness-extra/issue5174/Issue5174.out @@ -639,20 +639,19 @@ Before: InitializationStore#164( 76 -> 77 77 -> 78 -78 -> 80 +78 -> 79 78 -> 75 78 -> 75 78 -> 75 78 -> 75 -80 -> 82 +79 -> 80 +80 -> 81 80 -> 75 +81 -> 82 82 -> 83 82 -> 75 -83 -> 84 -84 -> 85 -84 -> 75 -84 -> 75 -85 -> 74 +82 -> 75 +83 -> 74 76: Before: InitializationStore#171( @@ -675,12 +674,12 @@ Before: InitializationStore#172( ~~~~~~~~~ Issue5174Sub [ ClassName ] > CFAV{@Initialized, Issue5174Sub} -80: +79: Before: InitializationStore#173( in > CFAV{, T} initialized fields = []) ~~~~~~~~~ -Issue5174Sub.this [ FieldAccess ] > CFAV{@Initialized, Issue5174Sub} +Issue5174Sub.this [ ClassLiteral ] > CFAV{@Initialized, Issue5174Sub} 75: Before: InitializationStore#174( @@ -689,52 +688,52 @@ Before: InitializationStore#174( ~~~~~~~~~ -82: +80: Before: InitializationStore#181( in > CFAV{, T} initialized fields = []) ~~~~~~~~~ Issue5174Sub.this.methodInner [ MethodAccess ] -83: -Before: InitializationStore#184( +81: +Before: InitializationStore#182( in > CFAV{, T} initialized fields = []) ~~~~~~~~~ in [ LocalVariable ] > CFAV{, T} -84: -Before: InitializationStore#187( +82: +Before: InitializationStore#185( in > CFAV{, T} initialized fields = []) ~~~~~~~~~ Issue5174Sub.this.methodInner(in) [ MethodInvocation ] > CFAV{, T} -85: -Before: InitializationStore#188( +83: +Before: InitializationStore#186( in > CFAV{, T} initialized fields = []) ~~~~~~~~~ o = Issue5174Sub.this.methodInner(in) [ Assignment ] > CFAV{, T} 74: -Before: InitializationStore#193( +Before: InitializationStore#191( in > CFAV{, T} o > CFAV{, T} initialized fields = []) ~~~~~~~~~ -89 -> 90 -90 -> 87 +87 -> 88 +88 -> 85 -89: -Before: InitializationStore#204( +87: +Before: InitializationStore#202( initialized fields = []) ~~~~~~~~~ -90: -Before: InitializationStore#204( +88: +Before: InitializationStore#202( initialized fields = []) ~~~~~~~~~ o [ VariableDeclaration ] @@ -742,115 +741,114 @@ o [ VariableDeclaration ] (this).f [ FieldAccess ] > CFAV{, T} o = (this).f [ Assignment ] > CFAV{, T} -87: -Before: InitializationStore#205( +85: +Before: InitializationStore#203( o > CFAV{, T} initialized fields = []) ~~~~~~~~~ +92 -> 93 +93 -> 94 94 -> 95 +94 -> 91 +94 -> 91 +94 -> 91 +94 -> 91 95 -> 96 -96 -> 98 -96 -> 93 -96 -> 93 -96 -> 93 -96 -> 93 -98 -> 100 -98 -> 93 -100 -> 101 -100 -> 93 -101 -> 92 +96 -> 97 +96 -> 91 +97 -> 90 -94: -Before: InitializationStore#209( +92: +Before: InitializationStore#207( initialized fields = []) ~~~~~~~~~ -95: -Before: InitializationStore#209( +93: +Before: InitializationStore#207( initialized fields = []) ~~~~~~~~~ o [ VariableDeclaration ] -96: -Before: InitializationStore#210( +94: +Before: InitializationStore#208( initialized fields = []) ~~~~~~~~~ Issue5174Sub [ ClassName ] > CFAV{@Initialized, Issue5174Sub} -98: -Before: InitializationStore#211( +95: +Before: InitializationStore#209( initialized fields = []) ~~~~~~~~~ -Issue5174Sub.this [ FieldAccess ] > CFAV{@Initialized, Issue5174Sub} +Issue5174Sub.this [ ClassLiteral ] > CFAV{@Initialized, Issue5174Sub} -93: -Before: InitializationStore#212( +91: +Before: InitializationStore#210( initialized fields = []) ~~~~~~~~~ -100: -Before: InitializationStore#219( +96: +Before: InitializationStore#217( initialized fields = []) ~~~~~~~~~ Issue5174Sub.this.f [ FieldAccess ] > CFAV{, T} -101: -Before: InitializationStore#222( +97: +Before: InitializationStore#218( initialized fields = []) ~~~~~~~~~ o = Issue5174Sub.this.f [ Assignment ] > CFAV{, T} -92: -Before: InitializationStore#225( +90: +Before: InitializationStore#221( o > CFAV{, T} initialized fields = []) ~~~~~~~~~ +101 -> 102 +102 -> 103 +103 -> 104 +103 -> 100 +103 -> 100 +103 -> 100 +103 -> 100 +104 -> 105 105 -> 106 +105 -> 100 +105 -> 100 +105 -> 100 +105 -> 100 106 -> 107 107 -> 108 -107 -> 104 -107 -> 104 -107 -> 104 -107 -> 104 -108 -> 109 -109 -> 110 -109 -> 104 -109 -> 104 -109 -> 104 -109 -> 104 -110 -> 111 -111 -> 112 -111 -> 104 -111 -> 104 -111 -> 104 -111 -> 104 -112 -> 103 +107 -> 100 +107 -> 100 +107 -> 100 +107 -> 100 +108 -> 99 -105: -Before: InitializationStore#234( +101: +Before: InitializationStore#230( initialized fields = []) ~~~~~~~~~ -106: -Before: InitializationStore#234( +102: +Before: InitializationStore#230( initialized fields = []) ~~~~~~~~~ o [ VariableDeclaration ] o [ LocalVariable ] -107: -Before: InitializationStore#235( +103: +Before: InitializationStore#231( initialized fields = []) ~~~~~~~~~ Issue5174Super [ ClassName ] -108: -Before: InitializationStore#236( +104: +Before: InitializationStore#232( initialized fields = []) ~~~~~~~~~ Issue5174Super.sf [ FieldAccess ] > CFAV{@Initialized, Object} @@ -858,21 +856,21 @@ o = Issue5174Super.sf [ Assignment ] > CFAV{@Initialized, Object} expression statement o = sf [ ExpressionStatement ] o [ LocalVariable ] -104: -Before: InitializationStore#237( +100: +Before: InitializationStore#233( initialized fields = []) ~~~~~~~~~ -109: -Before: InitializationStore#244( +105: +Before: InitializationStore#240( o > CFAV{@Initialized, Object} initialized fields = []) ~~~~~~~~~ Issue5174Sub [ ClassName ] > CFAV{@Initialized, Issue5174Sub} -110: -Before: InitializationStore#245( +106: +Before: InitializationStore#241( o > CFAV{@Initialized, Object} initialized fields = []) ~~~~~~~~~ @@ -881,15 +879,15 @@ o = Issue5174Sub.sf [ Assignment ] > CFAV{@Initialized, Object} expression statement o = Issue5174Sub.sf [ ExpressionStatement ] o [ LocalVariable ] -111: -Before: InitializationStore#254( +107: +Before: InitializationStore#250( o > CFAV{@Initialized, Object} initialized fields = []) ~~~~~~~~~ Issue5174Super [ ClassName ] > CFAV{@Initialized, Issue5174Super} -112: -Before: InitializationStore#255( +108: +Before: InitializationStore#251( o > CFAV{@Initialized, Object} initialized fields = []) ~~~~~~~~~ @@ -897,8 +895,8 @@ Issue5174Super.sf [ FieldAccess ] > CFAV{@Initialized, Object} o = Issue5174Super.sf [ Assignment ] > CFAV{@Initialized, Object} expression statement o = Issue5174Super.sf [ ExpressionStatement ] -103: -Before: InitializationStore#264( +99: +Before: InitializationStore#260( o > CFAV{@Initialized, Object} initialized fields = []) ~~~~~~~~~ @@ -911,7 +909,7 @@ Before: InitializationStore#264( 23 -> 18 20: -Before: NullnessNoInitStore#275( +Before: NullnessNoInitStore#271( f > NV{, T, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -919,7 +917,7 @@ Before: NullnessNoInitStore#275( 21: -Before: NullnessNoInitStore#275( +Before: NullnessNoInitStore#271( f > NV{, T, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -929,7 +927,7 @@ Before: NullnessNoInitStore#275( f [ LocalVariable ] > NV{, T, poly nn/n=f/f} 22: -Before: NullnessNoInitStore#276( +Before: NullnessNoInitStore#272( f > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false @@ -938,7 +936,7 @@ Before: NullnessNoInitStore#276( (this).(f) [ MethodInvocation ] > NV{@NonNull, Issue5174Super, poly nn/n=f/f} 23: -Before: NullnessNoInitStore#277( +Before: NullnessNoInitStore#273( f > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false @@ -947,7 +945,7 @@ Before: NullnessNoInitStore#277( expression statement super(f) [ ExpressionStatement ] 19: -Before: NullnessNoInitStore#278( +Before: NullnessNoInitStore#274( f > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false @@ -956,7 +954,7 @@ Before: NullnessNoInitStore#278( 18: -Before: NullnessNoInitStore#281( +Before: NullnessNoInitStore#277( f > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false @@ -971,7 +969,7 @@ Before: NullnessNoInitStore#281( 30 -> 25 27: -Before: NullnessNoInitStore#288( +Before: NullnessNoInitStore#284( in > NV{, T, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -979,7 +977,7 @@ Before: NullnessNoInitStore#288( 28: -Before: NullnessNoInitStore#288( +Before: NullnessNoInitStore#284( in > NV{, T, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -990,7 +988,7 @@ o [ VariableDeclaration ] in [ LocalVariable ] > NV{, T, poly nn/n=f/f} 29: -Before: NullnessNoInitStore#289( +Before: NullnessNoInitStore#285( in > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false @@ -999,7 +997,7 @@ Before: NullnessNoInitStore#289( (this).methodInner(in) [ MethodInvocation ] > NV{, T, poly nn/n=f/f} 30: -Before: NullnessNoInitStore#290( +Before: NullnessNoInitStore#286( in > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false @@ -1008,7 +1006,7 @@ Before: NullnessNoInitStore#290( o = (this).methodInner(in) [ Assignment ] > NV{, T, poly nn/n=f/f} 26: -Before: NullnessNoInitStore#291( +Before: NullnessNoInitStore#287( in > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false @@ -1017,7 +1015,7 @@ Before: NullnessNoInitStore#291( 25: -Before: NullnessNoInitStore#294( +Before: NullnessNoInitStore#290( in > NV{, T, poly nn/n=f/f} o > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} @@ -1033,7 +1031,7 @@ Before: NullnessNoInitStore#294( 37 -> 32 34: -Before: NullnessNoInitStore#301( +Before: NullnessNoInitStore#297( in > NV{, T, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -1041,7 +1039,7 @@ Before: NullnessNoInitStore#301( 35: -Before: NullnessNoInitStore#301( +Before: NullnessNoInitStore#297( in > NV{, T, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -1052,7 +1050,7 @@ this.methodInner [ MethodAccess ] in [ LocalVariable ] > NV{, T, poly nn/n=f/f} 36: -Before: NullnessNoInitStore#302( +Before: NullnessNoInitStore#298( in > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false @@ -1061,7 +1059,7 @@ Before: NullnessNoInitStore#302( this.methodInner(in) [ MethodInvocation ] > NV{, T, poly nn/n=f/f} 37: -Before: NullnessNoInitStore#303( +Before: NullnessNoInitStore#299( in > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false @@ -1070,7 +1068,7 @@ Before: NullnessNoInitStore#303( o = this.methodInner(in) [ Assignment ] > NV{, T, poly nn/n=f/f} 33: -Before: NullnessNoInitStore#304( +Before: NullnessNoInitStore#300( in > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false @@ -1079,7 +1077,7 @@ Before: NullnessNoInitStore#304( 32: -Before: NullnessNoInitStore#307( +Before: NullnessNoInitStore#303( in > NV{, T, poly nn/n=f/f} o > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} @@ -1091,7 +1089,7 @@ Before: NullnessNoInitStore#307( 42 -> 39 41: -Before: NullnessNoInitStore#314( +Before: NullnessNoInitStore#310( isPolyNullNonNull = false isPolyNullNull = false) @@ -1099,7 +1097,7 @@ Before: NullnessNoInitStore#314( 42: -Before: NullnessNoInitStore#314( +Before: NullnessNoInitStore#310( isPolyNullNonNull = false isPolyNullNull = false) @@ -1110,7 +1108,7 @@ o [ VariableDeclaration ] o = (this).f [ Assignment ] > NV{, T, poly nn/n=f/f} 39: -Before: NullnessNoInitStore#315( +Before: NullnessNoInitStore#311( o > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false @@ -1121,7 +1119,7 @@ Before: NullnessNoInitStore#315( 47 -> 44 46: -Before: NullnessNoInitStore#319( +Before: NullnessNoInitStore#315( isPolyNullNonNull = false isPolyNullNull = false) @@ -1129,7 +1127,7 @@ Before: NullnessNoInitStore#319( 47: -Before: NullnessNoInitStore#319( +Before: NullnessNoInitStore#315( isPolyNullNonNull = false isPolyNullNull = false) @@ -1140,7 +1138,7 @@ this.f [ FieldAccess ] > NV{, T, poly nn/n=f/f} o = this.f [ Assignment ] > NV{, T, poly nn/n=f/f} 44: -Before: NullnessNoInitStore#320( +Before: NullnessNoInitStore#316( o > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false @@ -1169,7 +1167,7 @@ Before: NullnessNoInitStore#320( 58 -> 49 51: -Before: NullnessNoInitStore#324( +Before: NullnessNoInitStore#320( isPolyNullNonNull = false isPolyNullNull = false) @@ -1177,7 +1175,7 @@ Before: NullnessNoInitStore#324( 52: -Before: NullnessNoInitStore#324( +Before: NullnessNoInitStore#320( isPolyNullNonNull = false isPolyNullNull = false) @@ -1186,7 +1184,7 @@ o [ VariableDeclaration ] o [ LocalVariable ] 53: -Before: NullnessNoInitStore#325( +Before: NullnessNoInitStore#321( isPolyNullNonNull = false isPolyNullNull = false) @@ -1194,7 +1192,7 @@ Before: NullnessNoInitStore#325( Issue5174Super [ ClassName ] 54: -Before: NullnessNoInitStore#326( +Before: NullnessNoInitStore#322( isPolyNullNonNull = false isPolyNullNull = false) @@ -1205,7 +1203,7 @@ expression statement o = sf [ ExpressionStatement ] o [ LocalVariable ] 50: -Before: NullnessNoInitStore#327( +Before: NullnessNoInitStore#323( isPolyNullNonNull = false isPolyNullNull = false) @@ -1213,7 +1211,7 @@ Before: NullnessNoInitStore#327( 55: -Before: NullnessNoInitStore#334( +Before: NullnessNoInitStore#330( o > NV{@NonNull, Object, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -1221,7 +1219,7 @@ Before: NullnessNoInitStore#334( Issue5174Sub [ ClassName ] > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} 56: -Before: NullnessNoInitStore#335( +Before: NullnessNoInitStore#331( o > NV{@NonNull, Object, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -1232,7 +1230,7 @@ expression statement o = Issue5174Sub.sf [ ExpressionStatement ] o [ LocalVariable ] 57: -Before: NullnessNoInitStore#344( +Before: NullnessNoInitStore#340( o > NV{@NonNull, Object, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -1240,7 +1238,7 @@ Before: NullnessNoInitStore#344( Issue5174Super [ ClassName ] > NV{@NonNull, Issue5174Super, poly nn/n=f/f} 58: -Before: NullnessNoInitStore#345( +Before: NullnessNoInitStore#341( o > NV{@NonNull, Object, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -1250,7 +1248,7 @@ o = Issue5174Super.sf [ Assignment ] > NV{@NonNull, Object, poly nn/n=f/f} expression statement o = Issue5174Super.sf [ ExpressionStatement ] 49: -Before: NullnessNoInitStore#354( +Before: NullnessNoInitStore#350( o > NV{@NonNull, Object, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -1264,7 +1262,7 @@ Before: NullnessNoInitStore#354( 65 -> 60 62: -Before: NullnessNoInitStore#365( +Before: NullnessNoInitStore#361( isPolyNullNonNull = false isPolyNullNull = false) @@ -1272,7 +1270,7 @@ Before: NullnessNoInitStore#365( 63: -Before: NullnessNoInitStore#365( +Before: NullnessNoInitStore#361( isPolyNullNonNull = false isPolyNullNull = false) @@ -1281,7 +1279,7 @@ Before: NullnessNoInitStore#365( (this). [ MethodAccess ] > NV{@NonNull, SubNested, poly nn/n=f/f} 64: -Before: NullnessNoInitStore#366( +Before: NullnessNoInitStore#362( this > NV{@NonNull, SubNested, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -1289,7 +1287,7 @@ Before: NullnessNoInitStore#366( (this).() [ MethodInvocation ] > NV{@NonNull, Object, poly nn/n=f/f} 65: -Before: NullnessNoInitStore#367( +Before: NullnessNoInitStore#363( this > NV{@NonNull, SubNested, poly nn/n=f/f} this.() > NV{@NonNull, Object, poly nn/n=f/f} isPolyNullNonNull = false @@ -1298,7 +1296,7 @@ Before: NullnessNoInitStore#367( expression statement super() [ ExpressionStatement ] 61: -Before: NullnessNoInitStore#368( +Before: NullnessNoInitStore#364( this > NV{@NonNull, SubNested, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -1306,7 +1304,7 @@ Before: NullnessNoInitStore#368( 60: -Before: NullnessNoInitStore#371( +Before: NullnessNoInitStore#367( this > NV{@NonNull, SubNested, poly nn/n=f/f} this.() > NV{@NonNull, Object, poly nn/n=f/f} isPolyNullNonNull = false @@ -1321,7 +1319,7 @@ Before: NullnessNoInitStore#371( 72 -> 67 69: -Before: NullnessNoInitStore#378( +Before: NullnessNoInitStore#374( in > NV{, T, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -1329,7 +1327,7 @@ Before: NullnessNoInitStore#378( 70: -Before: NullnessNoInitStore#378( +Before: NullnessNoInitStore#374( in > NV{, T, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -1340,7 +1338,7 @@ o [ VariableDeclaration ] in [ LocalVariable ] > NV{, T, poly nn/n=f/f} 71: -Before: NullnessNoInitStore#379( +Before: NullnessNoInitStore#375( in > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false @@ -1349,7 +1347,7 @@ Before: NullnessNoInitStore#379( (this).methodInner(in) [ MethodInvocation ] > NV{, T, poly nn/n=f/f} 72: -Before: NullnessNoInitStore#380( +Before: NullnessNoInitStore#376( in > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false @@ -1358,7 +1356,7 @@ Before: NullnessNoInitStore#380( o = (this).methodInner(in) [ Assignment ] > NV{, T, poly nn/n=f/f} 68: -Before: NullnessNoInitStore#381( +Before: NullnessNoInitStore#377( in > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false @@ -1367,7 +1365,7 @@ Before: NullnessNoInitStore#381( 67: -Before: NullnessNoInitStore#384( +Before: NullnessNoInitStore#380( in > NV{, T, poly nn/n=f/f} o > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} @@ -1377,23 +1375,22 @@ Before: NullnessNoInitStore#384( 76 -> 77 77 -> 78 -78 -> 80 +78 -> 79 78 -> 75 78 -> 75 78 -> 75 78 -> 75 -80 -> 82 +79 -> 80 +80 -> 81 80 -> 75 +81 -> 82 82 -> 83 82 -> 75 -83 -> 84 -84 -> 85 -84 -> 75 -84 -> 75 -85 -> 74 +82 -> 75 +83 -> 74 76: -Before: NullnessNoInitStore#391( +Before: NullnessNoInitStore#387( in > NV{, T, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -1401,7 +1398,7 @@ Before: NullnessNoInitStore#391( 77: -Before: NullnessNoInitStore#391( +Before: NullnessNoInitStore#387( in > NV{, T, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -1409,92 +1406,82 @@ Before: NullnessNoInitStore#391( o [ VariableDeclaration ] 78: -Before: NullnessNoInitStore#392( +Before: NullnessNoInitStore#388( in > NV{, T, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ Issue5174Sub [ ClassName ] > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} -80: -Before: NullnessNoInitStore#393( +79: +Before: NullnessNoInitStore#389( in > NV{, T, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ -Issue5174Sub.this [ FieldAccess ] > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} +Issue5174Sub.this [ ClassLiteral ] > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} 75: -Before: NullnessNoInitStore#410( +Before: NullnessNoInitStore#390( in > NV{, T, poly nn/n=f/f} - this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ -82: -Before: NullnessNoInitStore#401( +80: +Before: NullnessNoInitStore#397( in > NV{, T, poly nn/n=f/f} - Issue5174Sub.class > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ Issue5174Sub.this.methodInner [ MethodAccess ] -83: -Before: NullnessNoInitStore#404( +81: +Before: NullnessNoInitStore#398( in > NV{, T, poly nn/n=f/f} - this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} - Issue5174Sub.class > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ in [ LocalVariable ] > NV{, T, poly nn/n=f/f} -84: -Before: NullnessNoInitStore#407( +82: +Before: NullnessNoInitStore#401( in > NV{, T, poly nn/n=f/f} - this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} - Issue5174Sub.class > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ Issue5174Sub.this.methodInner(in) [ MethodInvocation ] > NV{, T, poly nn/n=f/f} -85: -Before: NullnessNoInitStore#408( +83: +Before: NullnessNoInitStore#402( in > NV{, T, poly nn/n=f/f} - this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} - Issue5174Sub.class > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ o = Issue5174Sub.this.methodInner(in) [ Assignment ] > NV{, T, poly nn/n=f/f} 74: -Before: NullnessNoInitStore#413( +Before: NullnessNoInitStore#407( in > NV{, T, poly nn/n=f/f} o > NV{, T, poly nn/n=f/f} - this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} - Issue5174Sub.class > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ -89 -> 90 -90 -> 87 +87 -> 88 +88 -> 85 -89: -Before: NullnessNoInitStore#424( +87: +Before: NullnessNoInitStore#418( isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ -90: -Before: NullnessNoInitStore#424( +88: +Before: NullnessNoInitStore#418( isPolyNullNonNull = false isPolyNullNull = false) @@ -1504,124 +1491,120 @@ o [ VariableDeclaration ] (this).f [ FieldAccess ] > NV{, T, poly nn/n=f/f} o = (this).f [ Assignment ] > NV{, T, poly nn/n=f/f} -87: -Before: NullnessNoInitStore#425( +85: +Before: NullnessNoInitStore#419( o > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ +92 -> 93 +93 -> 94 94 -> 95 +94 -> 91 +94 -> 91 +94 -> 91 +94 -> 91 95 -> 96 -96 -> 98 -96 -> 93 -96 -> 93 -96 -> 93 -96 -> 93 -98 -> 100 -98 -> 93 -100 -> 101 -100 -> 93 -101 -> 92 +96 -> 97 +96 -> 91 +97 -> 90 -94: -Before: NullnessNoInitStore#429( +92: +Before: NullnessNoInitStore#423( isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ -95: -Before: NullnessNoInitStore#429( +93: +Before: NullnessNoInitStore#423( isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ o [ VariableDeclaration ] -96: -Before: NullnessNoInitStore#430( +94: +Before: NullnessNoInitStore#424( isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ Issue5174Sub [ ClassName ] > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} -98: -Before: NullnessNoInitStore#431( +95: +Before: NullnessNoInitStore#425( isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ -Issue5174Sub.this [ FieldAccess ] > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} +Issue5174Sub.this [ ClassLiteral ] > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} -93: -Before: NullnessNoInitStore#432( +91: +Before: NullnessNoInitStore#426( isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ -100: -Before: NullnessNoInitStore#439( - Issue5174Sub.class > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} +96: +Before: NullnessNoInitStore#433( + isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ Issue5174Sub.this.f [ FieldAccess ] > NV{, T, poly nn/n=f/f} -101: -Before: NullnessNoInitStore#442( - this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} - Issue5174Sub.class > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} +97: +Before: NullnessNoInitStore#434( + isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ o = Issue5174Sub.this.f [ Assignment ] > NV{, T, poly nn/n=f/f} -92: -Before: NullnessNoInitStore#445( +90: +Before: NullnessNoInitStore#437( o > NV{, T, poly nn/n=f/f} - this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} - Issue5174Sub.class > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ +101 -> 102 +102 -> 103 +103 -> 104 +103 -> 100 +103 -> 100 +103 -> 100 +103 -> 100 +104 -> 105 105 -> 106 +105 -> 100 +105 -> 100 +105 -> 100 +105 -> 100 106 -> 107 107 -> 108 -107 -> 104 -107 -> 104 -107 -> 104 -107 -> 104 -108 -> 109 -109 -> 110 -109 -> 104 -109 -> 104 -109 -> 104 -109 -> 104 -110 -> 111 -111 -> 112 -111 -> 104 -111 -> 104 -111 -> 104 -111 -> 104 -112 -> 103 +107 -> 100 +107 -> 100 +107 -> 100 +107 -> 100 +108 -> 99 -105: -Before: NullnessNoInitStore#454( +101: +Before: NullnessNoInitStore#446( isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ -106: -Before: NullnessNoInitStore#454( +102: +Before: NullnessNoInitStore#446( isPolyNullNonNull = false isPolyNullNull = false) @@ -1629,16 +1612,16 @@ Before: NullnessNoInitStore#454( o [ VariableDeclaration ] o [ LocalVariable ] -107: -Before: NullnessNoInitStore#455( +103: +Before: NullnessNoInitStore#447( isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ Issue5174Super [ ClassName ] -108: -Before: NullnessNoInitStore#456( +104: +Before: NullnessNoInitStore#448( isPolyNullNonNull = false isPolyNullNull = false) @@ -1648,24 +1631,24 @@ o = Issue5174Super.sf [ Assignment ] > NV{@NonNull, Object, poly nn/n=f/f} expression statement o = sf [ ExpressionStatement ] o [ LocalVariable ] -104: -Before: NullnessNoInitStore#457( +100: +Before: NullnessNoInitStore#449( isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ -109: -Before: NullnessNoInitStore#464( +105: +Before: NullnessNoInitStore#456( o > NV{@NonNull, Object, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ Issue5174Sub [ ClassName ] > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} -110: -Before: NullnessNoInitStore#465( +106: +Before: NullnessNoInitStore#457( o > NV{@NonNull, Object, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -1675,16 +1658,16 @@ o = Issue5174Sub.sf [ Assignment ] > NV{@NonNull, Object, poly nn/n=f/f} expression statement o = Issue5174Sub.sf [ ExpressionStatement ] o [ LocalVariable ] -111: -Before: NullnessNoInitStore#474( +107: +Before: NullnessNoInitStore#466( o > NV{@NonNull, Object, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ Issue5174Super [ ClassName ] > NV{@NonNull, Issue5174Super, poly nn/n=f/f} -112: -Before: NullnessNoInitStore#475( +108: +Before: NullnessNoInitStore#467( o > NV{@NonNull, Object, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -1693,8 +1676,8 @@ Issue5174Super.sf [ FieldAccess ] > NV{@NonNull, Object, poly nn/n=f/f} o = Issue5174Super.sf [ Assignment ] > NV{@NonNull, Object, poly nn/n=f/f} expression statement o = Issue5174Super.sf [ ExpressionStatement ] -103: -Before: NullnessNoInitStore#484( +99: +Before: NullnessNoInitStore#476( o > NV{@NonNull, Object, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) From bc926434203dae2491547e322e27fd75f6f77787 Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Sun, 15 Dec 2024 04:46:39 -0500 Subject: [PATCH 14/39] Leave qualified this in another PR --- .../java/org/checkerframework/javacutil/TreeUtils.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/javacutil/src/main/java/org/checkerframework/javacutil/TreeUtils.java b/javacutil/src/main/java/org/checkerframework/javacutil/TreeUtils.java index 40c86f4905d..0d7451c973f 100644 --- a/javacutil/src/main/java/org/checkerframework/javacutil/TreeUtils.java +++ b/javacutil/src/main/java/org/checkerframework/javacutil/TreeUtils.java @@ -1437,6 +1437,8 @@ public static boolean isClassLiteral(Tree tree) { * obj . f * * + * This method currently also returns true for qualified this. + * * @param tree a tree that might be a field access * @return true iff if tree is a field access expression (implicit or explicit) */ @@ -1452,15 +1454,18 @@ public static boolean isFieldAccess(Tree tree) { * obj . f * * + * This method currently also returns a non-null value for qualified this. + * * @param tree a tree that might be a field access * @return the element if tree is a field access expression (implicit or explicit); null * otherwise */ + // TODO: fix value for qualified this, which is not field accesses. public static @Nullable VariableElement asFieldAccess(Tree tree) { if (tree.getKind() == Tree.Kind.MEMBER_SELECT) { // explicit member access (or a class literal or a qualified this) MemberSelectTree memberSelect = (MemberSelectTree) tree; - if (isClassLiteral(memberSelect) || isExplicitThisDereference(memberSelect)) { + if (isClassLiteral(memberSelect)) { return null; } assert isUseOfElement(memberSelect) : "@AssumeAssertion(nullness): tree kind"; From fcd6950e899f29e06a141ae7f8d9815228c0e672 Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Sun, 15 Dec 2024 04:49:01 -0500 Subject: [PATCH 15/39] Javadoc for NodeVisitor --- .../dataflow/cfg/node/NodeVisitor.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/NodeVisitor.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/NodeVisitor.java index 9562ee6cb74..0686d8e9ee1 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/NodeVisitor.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/NodeVisitor.java @@ -26,11 +26,32 @@ public interface NodeVisitor { R visitStringLiteral(StringLiteralNode n, P p); + /** + * Visits a null literal node. + * + * @param n the {@link NullLiteralNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitNullLiteral(NullLiteralNode n, P p); + /** + * Visits a class literal node. + * + * @param n the {@link ClassLiteralNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitClassLiteral(ClassLiteralNode n, P p); // Unary operations + /** + * Visits a unary minus node. + * + * @param n the {@link NumericalMinusNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitNumericalMinus(NumericalMinusNode n, P p); R visitNumericalPlus(NumericalPlusNode n, P p); From e6b61770e488b31f8eed6dc3877dc8c37d9f4662 Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Sun, 15 Dec 2024 05:05:45 -0500 Subject: [PATCH 16/39] Update expected CFG --- .../nullness-extra/issue5174/Issue5174.out | 473 +++++++++--------- 1 file changed, 245 insertions(+), 228 deletions(-) diff --git a/checker/tests/nullness-extra/issue5174/Issue5174.out b/checker/tests/nullness-extra/issue5174/Issue5174.out index 5dc7ec12a11..d4144a111ab 100644 --- a/checker/tests/nullness-extra/issue5174/Issue5174.out +++ b/checker/tests/nullness-extra/issue5174/Issue5174.out @@ -639,19 +639,20 @@ Before: InitializationStore#164( 76 -> 77 77 -> 78 -78 -> 79 +78 -> 80 78 -> 75 78 -> 75 78 -> 75 78 -> 75 -79 -> 80 -80 -> 81 +80 -> 82 80 -> 75 -81 -> 82 82 -> 83 82 -> 75 -82 -> 75 -83 -> 74 +83 -> 84 +84 -> 85 +84 -> 75 +84 -> 75 +85 -> 74 76: Before: InitializationStore#171( @@ -674,12 +675,12 @@ Before: InitializationStore#172( ~~~~~~~~~ Issue5174Sub [ ClassName ] > CFAV{@Initialized, Issue5174Sub} -79: +80: Before: InitializationStore#173( in > CFAV{, T} initialized fields = []) ~~~~~~~~~ -Issue5174Sub.this [ ClassLiteral ] > CFAV{@Initialized, Issue5174Sub} +Issue5174Sub.this [ FieldAccess ] > CFAV{@Initialized, Issue5174Sub} 75: Before: InitializationStore#174( @@ -688,52 +689,52 @@ Before: InitializationStore#174( ~~~~~~~~~ -80: +82: Before: InitializationStore#181( in > CFAV{, T} initialized fields = []) ~~~~~~~~~ Issue5174Sub.this.methodInner [ MethodAccess ] -81: -Before: InitializationStore#182( +83: +Before: InitializationStore#184( in > CFAV{, T} initialized fields = []) ~~~~~~~~~ in [ LocalVariable ] > CFAV{, T} -82: -Before: InitializationStore#185( +84: +Before: InitializationStore#187( in > CFAV{, T} initialized fields = []) ~~~~~~~~~ Issue5174Sub.this.methodInner(in) [ MethodInvocation ] > CFAV{, T} -83: -Before: InitializationStore#186( +85: +Before: InitializationStore#188( in > CFAV{, T} initialized fields = []) ~~~~~~~~~ o = Issue5174Sub.this.methodInner(in) [ Assignment ] > CFAV{, T} 74: -Before: InitializationStore#191( +Before: InitializationStore#193( in > CFAV{, T} o > CFAV{, T} initialized fields = []) ~~~~~~~~~ -87 -> 88 -88 -> 85 +89 -> 90 +90 -> 87 -87: -Before: InitializationStore#202( +89: +Before: InitializationStore#204( initialized fields = []) ~~~~~~~~~ -88: -Before: InitializationStore#202( +90: +Before: InitializationStore#204( initialized fields = []) ~~~~~~~~~ o [ VariableDeclaration ] @@ -741,114 +742,115 @@ o [ VariableDeclaration ] (this).f [ FieldAccess ] > CFAV{, T} o = (this).f [ Assignment ] > CFAV{, T} -85: -Before: InitializationStore#203( +87: +Before: InitializationStore#205( o > CFAV{, T} initialized fields = []) ~~~~~~~~~ -92 -> 93 -93 -> 94 94 -> 95 -94 -> 91 -94 -> 91 -94 -> 91 -94 -> 91 95 -> 96 -96 -> 97 -96 -> 91 -97 -> 90 +96 -> 98 +96 -> 93 +96 -> 93 +96 -> 93 +96 -> 93 +98 -> 100 +98 -> 93 +100 -> 101 +100 -> 93 +101 -> 92 -92: -Before: InitializationStore#207( +94: +Before: InitializationStore#209( initialized fields = []) ~~~~~~~~~ -93: -Before: InitializationStore#207( +95: +Before: InitializationStore#209( initialized fields = []) ~~~~~~~~~ o [ VariableDeclaration ] -94: -Before: InitializationStore#208( +96: +Before: InitializationStore#210( initialized fields = []) ~~~~~~~~~ Issue5174Sub [ ClassName ] > CFAV{@Initialized, Issue5174Sub} -95: -Before: InitializationStore#209( +98: +Before: InitializationStore#211( initialized fields = []) ~~~~~~~~~ -Issue5174Sub.this [ ClassLiteral ] > CFAV{@Initialized, Issue5174Sub} +Issue5174Sub.this [ FieldAccess ] > CFAV{@Initialized, Issue5174Sub} -91: -Before: InitializationStore#210( +93: +Before: InitializationStore#212( initialized fields = []) ~~~~~~~~~ -96: -Before: InitializationStore#217( +100: +Before: InitializationStore#219( initialized fields = []) ~~~~~~~~~ Issue5174Sub.this.f [ FieldAccess ] > CFAV{, T} -97: -Before: InitializationStore#218( +101: +Before: InitializationStore#222( initialized fields = []) ~~~~~~~~~ o = Issue5174Sub.this.f [ Assignment ] > CFAV{, T} -90: -Before: InitializationStore#221( +92: +Before: InitializationStore#225( o > CFAV{, T} initialized fields = []) ~~~~~~~~~ -101 -> 102 -102 -> 103 -103 -> 104 -103 -> 100 -103 -> 100 -103 -> 100 -103 -> 100 -104 -> 105 105 -> 106 -105 -> 100 -105 -> 100 -105 -> 100 -105 -> 100 106 -> 107 107 -> 108 -107 -> 100 -107 -> 100 -107 -> 100 -107 -> 100 -108 -> 99 +107 -> 104 +107 -> 104 +107 -> 104 +107 -> 104 +108 -> 109 +109 -> 110 +109 -> 104 +109 -> 104 +109 -> 104 +109 -> 104 +110 -> 111 +111 -> 112 +111 -> 104 +111 -> 104 +111 -> 104 +111 -> 104 +112 -> 103 -101: -Before: InitializationStore#230( +105: +Before: InitializationStore#234( initialized fields = []) ~~~~~~~~~ -102: -Before: InitializationStore#230( +106: +Before: InitializationStore#234( initialized fields = []) ~~~~~~~~~ o [ VariableDeclaration ] o [ LocalVariable ] -103: -Before: InitializationStore#231( +107: +Before: InitializationStore#235( initialized fields = []) ~~~~~~~~~ Issue5174Super [ ClassName ] -104: -Before: InitializationStore#232( +108: +Before: InitializationStore#236( initialized fields = []) ~~~~~~~~~ Issue5174Super.sf [ FieldAccess ] > CFAV{@Initialized, Object} @@ -856,21 +858,21 @@ o = Issue5174Super.sf [ Assignment ] > CFAV{@Initialized, Object} expression statement o = sf [ ExpressionStatement ] o [ LocalVariable ] -100: -Before: InitializationStore#233( +104: +Before: InitializationStore#237( initialized fields = []) ~~~~~~~~~ -105: -Before: InitializationStore#240( +109: +Before: InitializationStore#244( o > CFAV{@Initialized, Object} initialized fields = []) ~~~~~~~~~ Issue5174Sub [ ClassName ] > CFAV{@Initialized, Issue5174Sub} -106: -Before: InitializationStore#241( +110: +Before: InitializationStore#245( o > CFAV{@Initialized, Object} initialized fields = []) ~~~~~~~~~ @@ -879,15 +881,15 @@ o = Issue5174Sub.sf [ Assignment ] > CFAV{@Initialized, Object} expression statement o = Issue5174Sub.sf [ ExpressionStatement ] o [ LocalVariable ] -107: -Before: InitializationStore#250( +111: +Before: InitializationStore#254( o > CFAV{@Initialized, Object} initialized fields = []) ~~~~~~~~~ Issue5174Super [ ClassName ] > CFAV{@Initialized, Issue5174Super} -108: -Before: InitializationStore#251( +112: +Before: InitializationStore#255( o > CFAV{@Initialized, Object} initialized fields = []) ~~~~~~~~~ @@ -895,8 +897,8 @@ Issue5174Super.sf [ FieldAccess ] > CFAV{@Initialized, Object} o = Issue5174Super.sf [ Assignment ] > CFAV{@Initialized, Object} expression statement o = Issue5174Super.sf [ ExpressionStatement ] -99: -Before: InitializationStore#260( +103: +Before: InitializationStore#264( o > CFAV{@Initialized, Object} initialized fields = []) ~~~~~~~~~ @@ -909,7 +911,7 @@ Before: InitializationStore#260( 23 -> 18 20: -Before: NullnessNoInitStore#271( +Before: NullnessNoInitStore#275( f > NV{, T, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -917,7 +919,7 @@ Before: NullnessNoInitStore#271( 21: -Before: NullnessNoInitStore#271( +Before: NullnessNoInitStore#275( f > NV{, T, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -927,7 +929,7 @@ Before: NullnessNoInitStore#271( f [ LocalVariable ] > NV{, T, poly nn/n=f/f} 22: -Before: NullnessNoInitStore#272( +Before: NullnessNoInitStore#276( f > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false @@ -936,7 +938,7 @@ Before: NullnessNoInitStore#272( (this).(f) [ MethodInvocation ] > NV{@NonNull, Issue5174Super, poly nn/n=f/f} 23: -Before: NullnessNoInitStore#273( +Before: NullnessNoInitStore#277( f > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false @@ -945,7 +947,7 @@ Before: NullnessNoInitStore#273( expression statement super(f) [ ExpressionStatement ] 19: -Before: NullnessNoInitStore#274( +Before: NullnessNoInitStore#278( f > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false @@ -954,7 +956,7 @@ Before: NullnessNoInitStore#274( 18: -Before: NullnessNoInitStore#277( +Before: NullnessNoInitStore#281( f > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false @@ -969,7 +971,7 @@ Before: NullnessNoInitStore#277( 30 -> 25 27: -Before: NullnessNoInitStore#284( +Before: NullnessNoInitStore#288( in > NV{, T, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -977,7 +979,7 @@ Before: NullnessNoInitStore#284( 28: -Before: NullnessNoInitStore#284( +Before: NullnessNoInitStore#288( in > NV{, T, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -988,7 +990,7 @@ o [ VariableDeclaration ] in [ LocalVariable ] > NV{, T, poly nn/n=f/f} 29: -Before: NullnessNoInitStore#285( +Before: NullnessNoInitStore#289( in > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false @@ -997,7 +999,7 @@ Before: NullnessNoInitStore#285( (this).methodInner(in) [ MethodInvocation ] > NV{, T, poly nn/n=f/f} 30: -Before: NullnessNoInitStore#286( +Before: NullnessNoInitStore#290( in > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false @@ -1006,7 +1008,7 @@ Before: NullnessNoInitStore#286( o = (this).methodInner(in) [ Assignment ] > NV{, T, poly nn/n=f/f} 26: -Before: NullnessNoInitStore#287( +Before: NullnessNoInitStore#291( in > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false @@ -1015,7 +1017,7 @@ Before: NullnessNoInitStore#287( 25: -Before: NullnessNoInitStore#290( +Before: NullnessNoInitStore#294( in > NV{, T, poly nn/n=f/f} o > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} @@ -1031,7 +1033,7 @@ Before: NullnessNoInitStore#290( 37 -> 32 34: -Before: NullnessNoInitStore#297( +Before: NullnessNoInitStore#301( in > NV{, T, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -1039,7 +1041,7 @@ Before: NullnessNoInitStore#297( 35: -Before: NullnessNoInitStore#297( +Before: NullnessNoInitStore#301( in > NV{, T, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -1050,7 +1052,7 @@ this.methodInner [ MethodAccess ] in [ LocalVariable ] > NV{, T, poly nn/n=f/f} 36: -Before: NullnessNoInitStore#298( +Before: NullnessNoInitStore#302( in > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false @@ -1059,7 +1061,7 @@ Before: NullnessNoInitStore#298( this.methodInner(in) [ MethodInvocation ] > NV{, T, poly nn/n=f/f} 37: -Before: NullnessNoInitStore#299( +Before: NullnessNoInitStore#303( in > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false @@ -1068,7 +1070,7 @@ Before: NullnessNoInitStore#299( o = this.methodInner(in) [ Assignment ] > NV{, T, poly nn/n=f/f} 33: -Before: NullnessNoInitStore#300( +Before: NullnessNoInitStore#304( in > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false @@ -1077,7 +1079,7 @@ Before: NullnessNoInitStore#300( 32: -Before: NullnessNoInitStore#303( +Before: NullnessNoInitStore#307( in > NV{, T, poly nn/n=f/f} o > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} @@ -1089,7 +1091,7 @@ Before: NullnessNoInitStore#303( 42 -> 39 41: -Before: NullnessNoInitStore#310( +Before: NullnessNoInitStore#314( isPolyNullNonNull = false isPolyNullNull = false) @@ -1097,7 +1099,7 @@ Before: NullnessNoInitStore#310( 42: -Before: NullnessNoInitStore#310( +Before: NullnessNoInitStore#314( isPolyNullNonNull = false isPolyNullNull = false) @@ -1108,7 +1110,7 @@ o [ VariableDeclaration ] o = (this).f [ Assignment ] > NV{, T, poly nn/n=f/f} 39: -Before: NullnessNoInitStore#311( +Before: NullnessNoInitStore#315( o > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false @@ -1119,7 +1121,7 @@ Before: NullnessNoInitStore#311( 47 -> 44 46: -Before: NullnessNoInitStore#315( +Before: NullnessNoInitStore#319( isPolyNullNonNull = false isPolyNullNull = false) @@ -1127,7 +1129,7 @@ Before: NullnessNoInitStore#315( 47: -Before: NullnessNoInitStore#315( +Before: NullnessNoInitStore#319( isPolyNullNonNull = false isPolyNullNull = false) @@ -1138,7 +1140,7 @@ this.f [ FieldAccess ] > NV{, T, poly nn/n=f/f} o = this.f [ Assignment ] > NV{, T, poly nn/n=f/f} 44: -Before: NullnessNoInitStore#316( +Before: NullnessNoInitStore#320( o > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false @@ -1167,7 +1169,7 @@ Before: NullnessNoInitStore#316( 58 -> 49 51: -Before: NullnessNoInitStore#320( +Before: NullnessNoInitStore#324( isPolyNullNonNull = false isPolyNullNull = false) @@ -1175,7 +1177,7 @@ Before: NullnessNoInitStore#320( 52: -Before: NullnessNoInitStore#320( +Before: NullnessNoInitStore#324( isPolyNullNonNull = false isPolyNullNull = false) @@ -1184,7 +1186,7 @@ o [ VariableDeclaration ] o [ LocalVariable ] 53: -Before: NullnessNoInitStore#321( +Before: NullnessNoInitStore#325( isPolyNullNonNull = false isPolyNullNull = false) @@ -1192,7 +1194,7 @@ Before: NullnessNoInitStore#321( Issue5174Super [ ClassName ] 54: -Before: NullnessNoInitStore#322( +Before: NullnessNoInitStore#326( isPolyNullNonNull = false isPolyNullNull = false) @@ -1203,7 +1205,7 @@ expression statement o = sf [ ExpressionStatement ] o [ LocalVariable ] 50: -Before: NullnessNoInitStore#323( +Before: NullnessNoInitStore#327( isPolyNullNonNull = false isPolyNullNull = false) @@ -1211,7 +1213,7 @@ Before: NullnessNoInitStore#323( 55: -Before: NullnessNoInitStore#330( +Before: NullnessNoInitStore#334( o > NV{@NonNull, Object, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -1219,7 +1221,7 @@ Before: NullnessNoInitStore#330( Issue5174Sub [ ClassName ] > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} 56: -Before: NullnessNoInitStore#331( +Before: NullnessNoInitStore#335( o > NV{@NonNull, Object, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -1230,7 +1232,7 @@ expression statement o = Issue5174Sub.sf [ ExpressionStatement ] o [ LocalVariable ] 57: -Before: NullnessNoInitStore#340( +Before: NullnessNoInitStore#344( o > NV{@NonNull, Object, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -1238,7 +1240,7 @@ Before: NullnessNoInitStore#340( Issue5174Super [ ClassName ] > NV{@NonNull, Issue5174Super, poly nn/n=f/f} 58: -Before: NullnessNoInitStore#341( +Before: NullnessNoInitStore#345( o > NV{@NonNull, Object, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -1248,7 +1250,7 @@ o = Issue5174Super.sf [ Assignment ] > NV{@NonNull, Object, poly nn/n=f/f} expression statement o = Issue5174Super.sf [ ExpressionStatement ] 49: -Before: NullnessNoInitStore#350( +Before: NullnessNoInitStore#354( o > NV{@NonNull, Object, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -1262,7 +1264,7 @@ Before: NullnessNoInitStore#350( 65 -> 60 62: -Before: NullnessNoInitStore#361( +Before: NullnessNoInitStore#365( isPolyNullNonNull = false isPolyNullNull = false) @@ -1270,7 +1272,7 @@ Before: NullnessNoInitStore#361( 63: -Before: NullnessNoInitStore#361( +Before: NullnessNoInitStore#365( isPolyNullNonNull = false isPolyNullNull = false) @@ -1279,7 +1281,7 @@ Before: NullnessNoInitStore#361( (this). [ MethodAccess ] > NV{@NonNull, SubNested, poly nn/n=f/f} 64: -Before: NullnessNoInitStore#362( +Before: NullnessNoInitStore#366( this > NV{@NonNull, SubNested, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -1287,7 +1289,7 @@ Before: NullnessNoInitStore#362( (this).() [ MethodInvocation ] > NV{@NonNull, Object, poly nn/n=f/f} 65: -Before: NullnessNoInitStore#363( +Before: NullnessNoInitStore#367( this > NV{@NonNull, SubNested, poly nn/n=f/f} this.() > NV{@NonNull, Object, poly nn/n=f/f} isPolyNullNonNull = false @@ -1296,7 +1298,7 @@ Before: NullnessNoInitStore#363( expression statement super() [ ExpressionStatement ] 61: -Before: NullnessNoInitStore#364( +Before: NullnessNoInitStore#368( this > NV{@NonNull, SubNested, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -1304,7 +1306,7 @@ Before: NullnessNoInitStore#364( 60: -Before: NullnessNoInitStore#367( +Before: NullnessNoInitStore#371( this > NV{@NonNull, SubNested, poly nn/n=f/f} this.() > NV{@NonNull, Object, poly nn/n=f/f} isPolyNullNonNull = false @@ -1319,7 +1321,7 @@ Before: NullnessNoInitStore#367( 72 -> 67 69: -Before: NullnessNoInitStore#374( +Before: NullnessNoInitStore#378( in > NV{, T, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -1327,7 +1329,7 @@ Before: NullnessNoInitStore#374( 70: -Before: NullnessNoInitStore#374( +Before: NullnessNoInitStore#378( in > NV{, T, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -1338,7 +1340,7 @@ o [ VariableDeclaration ] in [ LocalVariable ] > NV{, T, poly nn/n=f/f} 71: -Before: NullnessNoInitStore#375( +Before: NullnessNoInitStore#379( in > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false @@ -1347,7 +1349,7 @@ Before: NullnessNoInitStore#375( (this).methodInner(in) [ MethodInvocation ] > NV{, T, poly nn/n=f/f} 72: -Before: NullnessNoInitStore#376( +Before: NullnessNoInitStore#380( in > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false @@ -1356,7 +1358,7 @@ Before: NullnessNoInitStore#376( o = (this).methodInner(in) [ Assignment ] > NV{, T, poly nn/n=f/f} 68: -Before: NullnessNoInitStore#377( +Before: NullnessNoInitStore#381( in > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false @@ -1365,7 +1367,7 @@ Before: NullnessNoInitStore#377( 67: -Before: NullnessNoInitStore#380( +Before: NullnessNoInitStore#384( in > NV{, T, poly nn/n=f/f} o > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} @@ -1375,22 +1377,23 @@ Before: NullnessNoInitStore#380( 76 -> 77 77 -> 78 -78 -> 79 +78 -> 80 78 -> 75 78 -> 75 78 -> 75 78 -> 75 -79 -> 80 -80 -> 81 +80 -> 82 80 -> 75 -81 -> 82 82 -> 83 82 -> 75 -82 -> 75 -83 -> 74 +83 -> 84 +84 -> 85 +84 -> 75 +84 -> 75 +85 -> 74 76: -Before: NullnessNoInitStore#387( +Before: NullnessNoInitStore#391( in > NV{, T, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -1398,7 +1401,7 @@ Before: NullnessNoInitStore#387( 77: -Before: NullnessNoInitStore#387( +Before: NullnessNoInitStore#391( in > NV{, T, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -1406,82 +1409,92 @@ Before: NullnessNoInitStore#387( o [ VariableDeclaration ] 78: -Before: NullnessNoInitStore#388( +Before: NullnessNoInitStore#392( in > NV{, T, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ Issue5174Sub [ ClassName ] > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} -79: -Before: NullnessNoInitStore#389( +80: +Before: NullnessNoInitStore#393( in > NV{, T, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ -Issue5174Sub.this [ ClassLiteral ] > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} +Issue5174Sub.this [ FieldAccess ] > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} 75: -Before: NullnessNoInitStore#390( +Before: NullnessNoInitStore#410( in > NV{, T, poly nn/n=f/f} + this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ -80: -Before: NullnessNoInitStore#397( +82: +Before: NullnessNoInitStore#401( in > NV{, T, poly nn/n=f/f} + Issue5174Sub.class > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ Issue5174Sub.this.methodInner [ MethodAccess ] -81: -Before: NullnessNoInitStore#398( +83: +Before: NullnessNoInitStore#404( in > NV{, T, poly nn/n=f/f} + this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} + Issue5174Sub.class > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ in [ LocalVariable ] > NV{, T, poly nn/n=f/f} -82: -Before: NullnessNoInitStore#401( +84: +Before: NullnessNoInitStore#407( in > NV{, T, poly nn/n=f/f} + this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} + Issue5174Sub.class > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ Issue5174Sub.this.methodInner(in) [ MethodInvocation ] > NV{, T, poly nn/n=f/f} -83: -Before: NullnessNoInitStore#402( +85: +Before: NullnessNoInitStore#408( in > NV{, T, poly nn/n=f/f} + this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} + Issue5174Sub.class > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ o = Issue5174Sub.this.methodInner(in) [ Assignment ] > NV{, T, poly nn/n=f/f} 74: -Before: NullnessNoInitStore#407( +Before: NullnessNoInitStore#413( in > NV{, T, poly nn/n=f/f} o > NV{, T, poly nn/n=f/f} + this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} + Issue5174Sub.class > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ -87 -> 88 -88 -> 85 +89 -> 90 +90 -> 87 -87: -Before: NullnessNoInitStore#418( +89: +Before: NullnessNoInitStore#424( isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ -88: -Before: NullnessNoInitStore#418( +90: +Before: NullnessNoInitStore#424( isPolyNullNonNull = false isPolyNullNull = false) @@ -1491,120 +1504,124 @@ o [ VariableDeclaration ] (this).f [ FieldAccess ] > NV{, T, poly nn/n=f/f} o = (this).f [ Assignment ] > NV{, T, poly nn/n=f/f} -85: -Before: NullnessNoInitStore#419( +87: +Before: NullnessNoInitStore#425( o > NV{, T, poly nn/n=f/f} this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ -92 -> 93 -93 -> 94 94 -> 95 -94 -> 91 -94 -> 91 -94 -> 91 -94 -> 91 95 -> 96 -96 -> 97 -96 -> 91 -97 -> 90 +96 -> 98 +96 -> 93 +96 -> 93 +96 -> 93 +96 -> 93 +98 -> 100 +98 -> 93 +100 -> 101 +100 -> 93 +101 -> 92 -92: -Before: NullnessNoInitStore#423( +94: +Before: NullnessNoInitStore#429( isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ -93: -Before: NullnessNoInitStore#423( +95: +Before: NullnessNoInitStore#429( isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ o [ VariableDeclaration ] -94: -Before: NullnessNoInitStore#424( +96: +Before: NullnessNoInitStore#430( isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ Issue5174Sub [ ClassName ] > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} -95: -Before: NullnessNoInitStore#425( +98: +Before: NullnessNoInitStore#431( isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ -Issue5174Sub.this [ ClassLiteral ] > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} +Issue5174Sub.this [ FieldAccess ] > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} -91: -Before: NullnessNoInitStore#426( +93: +Before: NullnessNoInitStore#432( isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ -96: -Before: NullnessNoInitStore#433( - +100: +Before: NullnessNoInitStore#439( + Issue5174Sub.class > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ Issue5174Sub.this.f [ FieldAccess ] > NV{, T, poly nn/n=f/f} -97: -Before: NullnessNoInitStore#434( - +101: +Before: NullnessNoInitStore#442( + this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} + Issue5174Sub.class > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ o = Issue5174Sub.this.f [ Assignment ] > NV{, T, poly nn/n=f/f} -90: -Before: NullnessNoInitStore#437( +92: +Before: NullnessNoInitStore#445( o > NV{, T, poly nn/n=f/f} + this > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} + Issue5174Sub.class > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ -101 -> 102 -102 -> 103 -103 -> 104 -103 -> 100 -103 -> 100 -103 -> 100 -103 -> 100 -104 -> 105 105 -> 106 -105 -> 100 -105 -> 100 -105 -> 100 -105 -> 100 106 -> 107 107 -> 108 -107 -> 100 -107 -> 100 -107 -> 100 -107 -> 100 -108 -> 99 +107 -> 104 +107 -> 104 +107 -> 104 +107 -> 104 +108 -> 109 +109 -> 110 +109 -> 104 +109 -> 104 +109 -> 104 +109 -> 104 +110 -> 111 +111 -> 112 +111 -> 104 +111 -> 104 +111 -> 104 +111 -> 104 +112 -> 103 -101: -Before: NullnessNoInitStore#446( +105: +Before: NullnessNoInitStore#454( isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ -102: -Before: NullnessNoInitStore#446( +106: +Before: NullnessNoInitStore#454( isPolyNullNonNull = false isPolyNullNull = false) @@ -1612,16 +1629,16 @@ Before: NullnessNoInitStore#446( o [ VariableDeclaration ] o [ LocalVariable ] -103: -Before: NullnessNoInitStore#447( +107: +Before: NullnessNoInitStore#455( isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ Issue5174Super [ ClassName ] -104: -Before: NullnessNoInitStore#448( +108: +Before: NullnessNoInitStore#456( isPolyNullNonNull = false isPolyNullNull = false) @@ -1631,24 +1648,24 @@ o = Issue5174Super.sf [ Assignment ] > NV{@NonNull, Object, poly nn/n=f/f} expression statement o = sf [ ExpressionStatement ] o [ LocalVariable ] -100: -Before: NullnessNoInitStore#449( +104: +Before: NullnessNoInitStore#457( isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ -105: -Before: NullnessNoInitStore#456( +109: +Before: NullnessNoInitStore#464( o > NV{@NonNull, Object, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ Issue5174Sub [ ClassName ] > NV{@NonNull, Issue5174Sub, poly nn/n=f/f} -106: -Before: NullnessNoInitStore#457( +110: +Before: NullnessNoInitStore#465( o > NV{@NonNull, Object, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -1658,16 +1675,16 @@ o = Issue5174Sub.sf [ Assignment ] > NV{@NonNull, Object, poly nn/n=f/f} expression statement o = Issue5174Sub.sf [ ExpressionStatement ] o [ LocalVariable ] -107: -Before: NullnessNoInitStore#466( +111: +Before: NullnessNoInitStore#474( o > NV{@NonNull, Object, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) ~~~~~~~~~ Issue5174Super [ ClassName ] > NV{@NonNull, Issue5174Super, poly nn/n=f/f} -108: -Before: NullnessNoInitStore#467( +112: +Before: NullnessNoInitStore#475( o > NV{@NonNull, Object, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) @@ -1676,8 +1693,8 @@ Issue5174Super.sf [ FieldAccess ] > NV{@NonNull, Object, poly nn/n=f/f} o = Issue5174Super.sf [ Assignment ] > NV{@NonNull, Object, poly nn/n=f/f} expression statement o = Issue5174Super.sf [ ExpressionStatement ] -99: -Before: NullnessNoInitStore#476( +103: +Before: NullnessNoInitStore#484( o > NV{@NonNull, Object, poly nn/n=f/f} isPolyNullNonNull = false isPolyNullNull = false) From c89b0173a2083529b690cd18edd5aa4e37790d81 Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Sun, 15 Dec 2024 05:18:52 -0500 Subject: [PATCH 17/39] A lot of Javadoc --- .../dataflow/cfg/node/NodeVisitor.java | 463 +++++++++++++++++- 1 file changed, 462 insertions(+), 1 deletion(-) diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/NodeVisitor.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/NodeVisitor.java index 0686d8e9ee1..06055f9a052 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/NodeVisitor.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/NodeVisitor.java @@ -10,20 +10,76 @@ */ public interface NodeVisitor { // Literals + /** + * Visits a short literal node. + * + * @param n the {@link ShortLiteralNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitShortLiteral(ShortLiteralNode n, P p); + /** + * Visits an integer literal node. + * + * @param n the {@link IntegerLiteralNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitIntegerLiteral(IntegerLiteralNode n, P p); + /** + * Visits a long literal node. + * + * @param n the {@link LongLiteralNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitLongLiteral(LongLiteralNode n, P p); + /** + * Visits a float literal node. + * + * @param n the {@link FloatLiteralNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitFloatLiteral(FloatLiteralNode n, P p); + /** + * Visits a double literal node. + * + * @param n the {@link DoubleLiteralNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitDoubleLiteral(DoubleLiteralNode n, P p); + /** + * Visits a boolean literal node. + * + * @param n the {@link BooleanLiteralNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitBooleanLiteral(BooleanLiteralNode n, P p); + /** + * Visits a character literal node. + * + * @param n the {@link CharacterLiteralNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitCharacterLiteral(CharacterLiteralNode n, P p); + /** + * Visits a string literal node. + * + * @param n the {@link StringLiteralNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitStringLiteral(StringLiteralNode n, P p); /** @@ -54,131 +110,536 @@ public interface NodeVisitor { */ R visitNumericalMinus(NumericalMinusNode n, P p); + /** + * Visits a unary plus node. + * + * @param n the {@link NumericalPlusNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitNumericalPlus(NumericalPlusNode n, P p); + /** + * Visits a bitwise complement node. + * + * @param n the {@link BitwiseComplementNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitBitwiseComplement(BitwiseComplementNode n, P p); + /** + * Visits a NullChk node. + * + * @param n the {@link NullChkNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitNullChk(NullChkNode n, P p); // Binary operations + /** + * Visits a string concatenation node. + * + * @param n the {@link StringConcatenateNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitStringConcatenate(StringConcatenateNode n, P p); + /** + * Visits a numerical addition node. + * + * @param n the {@link NumericalAdditionNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitNumericalAddition(NumericalAdditionNode n, P p); + /** + * Visits a numerical subtraction node. + * + * @param n the {@link NumericalSubtractionNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitNumericalSubtraction(NumericalSubtractionNode n, P p); + /** + * Visits a numerical multiplication node. + * + * @param n the {@link NumericalMultiplicationNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitNumericalMultiplication(NumericalMultiplicationNode n, P p); + /** + * Visits a integer division node. + * + * @param n the {@link IntegerDivisionNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitIntegerDivision(IntegerDivisionNode n, P p); + /** + * Visits a floating division node. + * + * @param n the {@link FloatingDivisionNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitFloatingDivision(FloatingDivisionNode n, P p); + /** + * Visits a integer remainder node. + * + * @param n the {@link IntegerRemainderNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitIntegerRemainder(IntegerRemainderNode n, P p); + /** + * Visits a floating remainder node. + * + * @param n the {@link FloatingRemainderNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitFloatingRemainder(FloatingRemainderNode n, P p); + /** + * Visits a left shift node. + * + * @param n the {@link LeftShiftNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitLeftShift(LeftShiftNode n, P p); + /** + * Visits a signed right shift node. + * + * @param n the {@link SignedRightShiftNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitSignedRightShift(SignedRightShiftNode n, P p); + /** + * Visits an unsigned right shift node. + * + * @param n the {@link UnsignedRightShiftNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitUnsignedRightShift(UnsignedRightShiftNode n, P p); + /** + * Visits a bitwise and node. + * + * @param n the {@link BitwiseAndNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitBitwiseAnd(BitwiseAndNode n, P p); + /** + * Visits a bitwise or node. + * + * @param n the {@link BitwiseOrNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitBitwiseOr(BitwiseOrNode n, P p); + /** + * Visits a bitwise xor node. + * + * @param n the {@link BitwiseXorNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitBitwiseXor(BitwiseXorNode n, P p); // Comparison operations + /** + * Visits a less than node. + * + * @param n the {@link LessThanNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitLessThan(LessThanNode n, P p); + /** + * Visits a less than or equal node. + * + * @param n the {@link LessThanOrEqualNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitLessThanOrEqual(LessThanOrEqualNode n, P p); + /** + * Visits a greater than node. + * + * @param n the {@link GreaterThanNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitGreaterThan(GreaterThanNode n, P p); + /** + * Visits a greater than or equal node. + * + * @param n the {@link GreaterThanOrEqualNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitGreaterThanOrEqual(GreaterThanOrEqualNode n, P p); + /** + * Visits an equal to node. + * + * @param n the {@link EqualToNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitEqualTo(EqualToNode n, P p); + /** + * Visits a not equal node. + * + * @param n the {@link NotEqualNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitNotEqual(NotEqualNode n, P p); // Conditional operations + /** + * Visits a conditional and node. + * + * @param n the {@link ConditionalAndNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitConditionalAnd(ConditionalAndNode n, P p); + /** + * Visits a conditional or node. + * + * @param n the {@link ConditionalOrNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitConditionalOr(ConditionalOrNode n, P p); + /** + * Visits a conditional not node. + * + * @param n the {@link ConditionalNotNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitConditionalNot(ConditionalNotNode n, P p); + /** + * Visits a ternary expression node. + * + * @param n the {@link TernaryExpressionNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitTernaryExpression(TernaryExpressionNode n, P p); + /** + * Visits a switch expression node. + * + * @param n the {@link SwitchExpressionNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitSwitchExpressionNode(SwitchExpressionNode n, P p); + /** + * Visits a switch expression node. + * + * @param n the {@link SwitchExpressionNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitAssignment(AssignmentNode n, P p); + /** + * Visits a local variable node. + * + * @param n the {@link LocalVariableNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitLocalVariable(LocalVariableNode n, P p); + /** + * Visits a variable declaration node. + * + * @param n the {@link VariableDeclarationNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitVariableDeclaration(VariableDeclarationNode n, P p); + /** + * Visits a field access node. + * + * @param n the {@link FieldAccessNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitFieldAccess(FieldAccessNode n, P p); + /** + * Visits a method access node. + * + * @param n the {@link MethodAccessNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitMethodAccess(MethodAccessNode n, P p); + /** + * Visits an array access node. + * + * @param n the {@link ArrayAccessNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitArrayAccess(ArrayAccessNode n, P p); + /** + * Visits an implicit this node. + * + * @param n the {@link ImplicitThisNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitImplicitThis(ImplicitThisNode n, P p); + /** + * Visits an explicit this node. + * + * @param n the {@link ExplicitThisNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitExplicitThis(ExplicitThisNode n, P p); + /** + * Visits a super node. + * + * @param n the {@link SuperNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitSuper(SuperNode n, P p); + /** + * Visits a return node. + * + * @param n the {@link ReturnNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitReturn(ReturnNode n, P p); + /** + * Visits a lambda result expression node. + * + * @param n the {@link LambdaResultExpressionNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitLambdaResultExpression(LambdaResultExpressionNode n, P p); + /** + * Visits a string conversion node. + * + * @param n the {@link StringConversionNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitStringConversion(StringConversionNode n, P p); + /** + * Visits a widening conversion node. + * + * @param n the {@link WideningConversionNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitWideningConversion(WideningConversionNode n, P p); + /** + * Visits a narrowing conversion node. + * + * @param n the {@link NarrowingConversionNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitNarrowingConversion(NarrowingConversionNode n, P p); + /** + * Visits an instance of node. + * + * @param n the {@link InstanceOfNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitInstanceOf(InstanceOfNode n, P p); + /** + * Visits a type cast node. + * + * @param n the {@link TypeCastNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitTypeCast(TypeCastNode n, P p); // Blocks - + /** + * Visits a synchronized node. + * + * @param n the {@link SynchronizedNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitSynchronized(SynchronizedNode n, P p); // Statements + /** + * Visits an assertion error node. + * + * @param n the {@link AssertionErrorNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitAssertionError(AssertionErrorNode n, P p); + /** + * Visits a throw node. + * + * @param n the {@link ThrowNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitThrow(ThrowNode n, P p); // Cases + /** + * Visits a case node. + * + * @param n the {@link CaseNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitCase(CaseNode n, P p); // Method and constructor invocations + /** + * Visits a method invocation node. + * + * @param n the {@link MethodInvocationNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitMethodInvocation(MethodInvocationNode n, P p); + /** + * Visits a object creation node. + * + * @param n the {@link ObjectCreationNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitObjectCreation(ObjectCreationNode n, P p); + /** + * Visits a Member Reference node. + * + * @param n the {@link FunctionalInterfaceNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitMemberReference(FunctionalInterfaceNode n, P p); + /** + * Visits an array creation node. + * + * @param n the {@link ArrayCreationNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitArrayCreation(ArrayCreationNode n, P p); // Type, package and class names + /** + * Visits an array type node. + * + * @param n the {@link ArrayTypeNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitArrayType(ArrayTypeNode n, P p); + /** + * Visits a primitive type node. + * + * @param n the {@link PrimitiveTypeNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitPrimitiveType(PrimitiveTypeNode n, P p); + /** + * Visits a class name node. + * + * @param n the {@link ClassNameNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitClassName(ClassNameNode n, P p); + /** + * Visits a package name node. + * + * @param n the {@link PackageNameNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitPackageName(PackageNameNode n, P p); // Parameterized types + /** + * Visits a parameterized type node. + * + * @param n the {@link ParameterizedTypeNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitParameterizedType(ParameterizedTypeNode n, P p); // Marker nodes + /** + * Visits a marker node. + * + * @param n the {@link MarkerNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ R visitMarker(MarkerNode n, P p); /** From 4d04987e4f1ed97ab5fa01a770e713df5132dfa7 Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Sun, 15 Dec 2024 09:53:12 -0500 Subject: [PATCH 18/39] Maybe this is the cause of daikon failure --- .../java/org/checkerframework/checker/lock/LockVisitor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checker/src/main/java/org/checkerframework/checker/lock/LockVisitor.java b/checker/src/main/java/org/checkerframework/checker/lock/LockVisitor.java index 6c8f71dcf9c..6f5dca9bb32 100644 --- a/checker/src/main/java/org/checkerframework/checker/lock/LockVisitor.java +++ b/checker/src/main/java/org/checkerframework/checker/lock/LockVisitor.java @@ -424,7 +424,7 @@ protected boolean commonAssignmentCheck( @Override public Void visitMemberSelect(MemberSelectTree tree, Void p) { - if (TreeUtils.isFieldAccess(tree)) { + if (!TreeUtils.isFieldAccess(tree)) { AnnotatedTypeMirror atmOfReceiver = atypeFactory.getAnnotatedType(tree.getExpression()); // The atmOfReceiver for "void.class" is TypeKind.VOID, which isn't annotated so avoid // it. From 9fee97ca008cdbe64602dbc3aa63dc4741e4195b Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Sun, 15 Dec 2024 10:03:42 -0500 Subject: [PATCH 19/39] Revert the change --- .../java/org/checkerframework/checker/lock/LockVisitor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checker/src/main/java/org/checkerframework/checker/lock/LockVisitor.java b/checker/src/main/java/org/checkerframework/checker/lock/LockVisitor.java index 6f5dca9bb32..6c8f71dcf9c 100644 --- a/checker/src/main/java/org/checkerframework/checker/lock/LockVisitor.java +++ b/checker/src/main/java/org/checkerframework/checker/lock/LockVisitor.java @@ -424,7 +424,7 @@ protected boolean commonAssignmentCheck( @Override public Void visitMemberSelect(MemberSelectTree tree, Void p) { - if (!TreeUtils.isFieldAccess(tree)) { + if (TreeUtils.isFieldAccess(tree)) { AnnotatedTypeMirror atmOfReceiver = atypeFactory.getAnnotatedType(tree.getExpression()); // The atmOfReceiver for "void.class" is TypeKind.VOID, which isn't annotated so avoid // it. From ea6b44eb9995634caa25fae47a0ef62cd54d672d Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Sun, 15 Dec 2024 14:46:33 -0500 Subject: [PATCH 20/39] Fix broken link --- .../dataflow/expression/JavaExpressionVisitor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/expression/JavaExpressionVisitor.java b/dataflow/src/main/java/org/checkerframework/dataflow/expression/JavaExpressionVisitor.java index 024ec632ce1..69612800962 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/expression/JavaExpressionVisitor.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/expression/JavaExpressionVisitor.java @@ -9,7 +9,7 @@ public abstract class JavaExpressionVisitor { /** - * Visits the given {@code javaExpr}. + * Visits the given {@link JavaExpression}. * * @param javaExpr the expression to visit * @param p the parameter to pass to the visit method From a59417e59abd3cee858efc08ef868e3f8a966b75 Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Sun, 15 Dec 2024 14:55:17 -0500 Subject: [PATCH 21/39] Don't check Daikon 2 to see if there is other failure --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6b5369f5524..d462e22b220 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: fail-fast: true matrix: # No need to run 'cftests-junit-jdk21' on JDK 21. - script: ['typecheck-part1', 'typecheck-part2', 'guava', 'plume-lib', 'daikon-part1', 'daikon-part2', 'jspecify-conformance', 'jspecify-reference-checker'] + script: ['typecheck-part1', 'typecheck-part2', 'guava', 'plume-lib', 'daikon-part1', 'jspecify-conformance', 'jspecify-reference-checker'] java_version: [21] env: JAVA_VERSION: ${{ matrix.java_version }} @@ -94,7 +94,7 @@ jobs: fail-fast: true matrix: # jspecify-conformance and jspecify-reference-checker only tested on JDK 21. - script: ['cftests-junit', 'cftests-nonjunit', 'cftests-junit-jdk21', 'typecheck-part1', 'typecheck-part2', 'guava', 'plume-lib', 'daikon-part1', 'daikon-part2'] + script: ['cftests-junit', 'cftests-nonjunit', 'cftests-junit-jdk21', 'typecheck-part1', 'typecheck-part2', 'guava', 'plume-lib', 'daikon-part1'] # JDK 21 used by sanity before java: [{version: '8', experimental: false}, {version: '11', experimental: false}, From 5a15cd4fa43e5a06864b9c31be9006ba5c8f205c Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Sun, 15 Dec 2024 13:35:07 -0800 Subject: [PATCH 22/39] Undo CI --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d462e22b220..3fd364840b4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: fail-fast: true matrix: # No need to run 'cftests-junit-jdk21' on JDK 21. - script: ['typecheck-part1', 'typecheck-part2', 'guava', 'plume-lib', 'daikon-part1', 'jspecify-conformance', 'jspecify-reference-checker'] + script: ['typecheck-part1', 'typecheck-part2', 'guava', 'plume-lib', 'daikon-part1', 'daikon-part2', 'jspecify-conformance', 'jspecify-reference-checker'] java_version: [21] env: JAVA_VERSION: ${{ matrix.java_version }} @@ -94,7 +94,7 @@ jobs: fail-fast: true matrix: # jspecify-conformance and jspecify-reference-checker only tested on JDK 21. - script: ['cftests-junit', 'cftests-nonjunit', 'cftests-junit-jdk21', 'typecheck-part1', 'typecheck-part2', 'guava', 'plume-lib', 'daikon-part1'] + script: ['cftests-junit', 'cftests-nonjunit', 'cftests-junit-jdk21', 'typecheck-part1', 'typecheck-part2', 'guava', 'plume-lib', 'daikon-part1', 'daikon-part2',] # JDK 21 used by sanity before java: [{version: '8', experimental: false}, {version: '11', experimental: false}, From 47b2f63a63eba7567c6137ff1286aa1f666bdcdc Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Sun, 15 Dec 2024 13:35:57 -0800 Subject: [PATCH 23/39] Use PrimitiveTypeNode to represent class literal --- .../cfg/builder/CFGTranslationPhaseOne.java | 5 +- .../cfg/node/AbstractNodeVisitor.java | 5 -- .../dataflow/cfg/node/ClassLiteralNode.java | 46 ------------------- .../dataflow/cfg/node/NodeVisitor.java | 9 ---- .../dataflow/cfg/node/PrimitiveTypeNode.java | 7 +++ 5 files changed, 9 insertions(+), 63 deletions(-) delete mode 100644 dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/ClassLiteralNode.java diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/CFGTranslationPhaseOne.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/CFGTranslationPhaseOne.java index 5e1e46cfd58..497ce47dec4 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/CFGTranslationPhaseOne.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/CFGTranslationPhaseOne.java @@ -77,7 +77,6 @@ import org.checkerframework.dataflow.cfg.node.CatchMarkerNode; import org.checkerframework.dataflow.cfg.node.CharacterLiteralNode; import org.checkerframework.dataflow.cfg.node.ClassDeclarationNode; -import org.checkerframework.dataflow.cfg.node.ClassLiteralNode; import org.checkerframework.dataflow.cfg.node.ClassNameNode; import org.checkerframework.dataflow.cfg.node.ConditionalAndNode; import org.checkerframework.dataflow.cfg.node.ConditionalNotNode; @@ -3673,8 +3672,8 @@ public Node visitMemberSelect(MemberSelectTree tree, Void p) { extendWithNode(result); return result; } else if (element.getKind() == ElementKind.FIELD) { - Node result = new ClassLiteralNode(tree); - extendWithNode((ClassLiteralNode) result); + Node result = new PrimitiveTypeNode(tree, types); + extendWithNode((PrimitiveTypeNode) result); return result; } else { throw new BugInCF("Unexpected element kind: " + element.getKind()); diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/AbstractNodeVisitor.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/AbstractNodeVisitor.java index 0982c82dbc8..4f04678f1a4 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/AbstractNodeVisitor.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/AbstractNodeVisitor.java @@ -66,11 +66,6 @@ public R visitNullLiteral(NullLiteralNode n, P p) { return visitValueLiteral(n, p); } - @Override - public R visitClassLiteral(ClassLiteralNode n, P p) { - return visitNode(n, p); - } - // Unary operations @Override public R visitNumericalMinus(NumericalMinusNode n, P p) { diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/ClassLiteralNode.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/ClassLiteralNode.java deleted file mode 100644 index 4bc8603eea6..00000000000 --- a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/ClassLiteralNode.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.checkerframework.dataflow.cfg.node; - -import com.sun.source.tree.MemberSelectTree; -import com.sun.source.tree.Tree; - -import org.checkerframework.checker.nullness.qual.Nullable; -import org.checkerframework.javacutil.TreeUtils; - -import java.util.Collection; -import java.util.Collections; - -/** A node for a class literal. For example: {@code String.class}. */ -public class ClassLiteralNode extends Node { - /** The tree for the class literal. */ - protected final Tree tree; - - /** - * Create a new ClassLiteralNode. - * - * @param tree the class literal - */ - public ClassLiteralNode(MemberSelectTree tree) { - super(TreeUtils.typeOf(tree)); - this.tree = tree; - } - - @Override - public @Nullable Tree getTree() { - return tree; - } - - @Override - public R accept(NodeVisitor visitor, P p) { - return visitor.visitClassLiteral(this, p); - } - - @Override - public String toString() { - return tree.toString(); - } - - @Override - public Collection getOperands() { - return Collections.emptyList(); - } -} diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/NodeVisitor.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/NodeVisitor.java index 06055f9a052..809ccfcf4cd 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/NodeVisitor.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/NodeVisitor.java @@ -91,15 +91,6 @@ public interface NodeVisitor { */ R visitNullLiteral(NullLiteralNode n, P p); - /** - * Visits a class literal node. - * - * @param n the {@link ClassLiteralNode} to be visited - * @param p the argument for the operation implemented by this visitor - * @return the return value of the operation implemented by this visitor - */ - R visitClassLiteral(ClassLiteralNode n, P p); - // Unary operations /** * Visits a unary minus node. diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/PrimitiveTypeNode.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/PrimitiveTypeNode.java index a69081a99ab..4a3027cad2b 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/PrimitiveTypeNode.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/PrimitiveTypeNode.java @@ -1,5 +1,6 @@ package org.checkerframework.dataflow.cfg.node; +import com.sun.source.tree.MemberSelectTree; import com.sun.source.tree.PrimitiveTypeTree; import org.checkerframework.checker.nullness.qual.Nullable; @@ -30,6 +31,12 @@ public PrimitiveTypeNode(PrimitiveTypeTree tree, Types types) { this.types = types; } + public PrimitiveTypeNode(MemberSelectTree tree, Types types) { + super(TreeUtils.typeOf(tree)); + this.tree = (PrimitiveTypeTree) tree; + this.types = types; + } + @Override public PrimitiveTypeTree getTree() { return tree; From b7c80f1428faf5ec3c5bb46ee3bfda12802a4a0b Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Sun, 15 Dec 2024 13:37:05 -0800 Subject: [PATCH 24/39] Remove extra comma --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3fd364840b4..6b5369f5524 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -94,7 +94,7 @@ jobs: fail-fast: true matrix: # jspecify-conformance and jspecify-reference-checker only tested on JDK 21. - script: ['cftests-junit', 'cftests-nonjunit', 'cftests-junit-jdk21', 'typecheck-part1', 'typecheck-part2', 'guava', 'plume-lib', 'daikon-part1', 'daikon-part2',] + script: ['cftests-junit', 'cftests-nonjunit', 'cftests-junit-jdk21', 'typecheck-part1', 'typecheck-part2', 'guava', 'plume-lib', 'daikon-part1', 'daikon-part2'] # JDK 21 used by sanity before java: [{version: '8', experimental: false}, {version: '11', experimental: false}, From f5dec68f8356c8c98c481e3173b448c3518c1ed5 Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Sun, 15 Dec 2024 16:52:59 -0500 Subject: [PATCH 25/39] Use dummy constructor parameter to prevent ClassCastException --- .../dataflow/cfg/builder/CFGTranslationPhaseOne.java | 2 +- .../checkerframework/dataflow/cfg/node/PrimitiveTypeNode.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/CFGTranslationPhaseOne.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/CFGTranslationPhaseOne.java index 497ce47dec4..9a7b683f456 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/CFGTranslationPhaseOne.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/CFGTranslationPhaseOne.java @@ -3672,7 +3672,7 @@ public Node visitMemberSelect(MemberSelectTree tree, Void p) { extendWithNode(result); return result; } else if (element.getKind() == ElementKind.FIELD) { - Node result = new PrimitiveTypeNode(tree, types); + Node result = new PrimitiveTypeNode(tree, types, false); extendWithNode((PrimitiveTypeNode) result); return result; } else { diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/PrimitiveTypeNode.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/PrimitiveTypeNode.java index 4a3027cad2b..5a2329775d3 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/PrimitiveTypeNode.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/PrimitiveTypeNode.java @@ -31,7 +31,7 @@ public PrimitiveTypeNode(PrimitiveTypeTree tree, Types types) { this.types = types; } - public PrimitiveTypeNode(MemberSelectTree tree, Types types) { + public PrimitiveTypeNode(MemberSelectTree tree, Types types, boolean dummy) { super(TreeUtils.typeOf(tree)); this.tree = (PrimitiveTypeTree) tree; this.types = types; From ac88eefe21cbcdc77b4adce69afacfe49b0941ff Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Sun, 15 Dec 2024 17:09:21 -0500 Subject: [PATCH 26/39] Change field tree to Tree type --- .../dataflow/cfg/builder/CFGTranslationPhaseOne.java | 2 +- .../dataflow/cfg/node/PrimitiveTypeNode.java | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/CFGTranslationPhaseOne.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/CFGTranslationPhaseOne.java index 9a7b683f456..497ce47dec4 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/CFGTranslationPhaseOne.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/CFGTranslationPhaseOne.java @@ -3672,7 +3672,7 @@ public Node visitMemberSelect(MemberSelectTree tree, Void p) { extendWithNode(result); return result; } else if (element.getKind() == ElementKind.FIELD) { - Node result = new PrimitiveTypeNode(tree, types, false); + Node result = new PrimitiveTypeNode(tree, types); extendWithNode((PrimitiveTypeNode) result); return result; } else { diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/PrimitiveTypeNode.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/PrimitiveTypeNode.java index 5a2329775d3..4f197861b67 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/PrimitiveTypeNode.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/PrimitiveTypeNode.java @@ -2,6 +2,7 @@ import com.sun.source.tree.MemberSelectTree; import com.sun.source.tree.PrimitiveTypeTree; +import com.sun.source.tree.Tree; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.dataflow.qual.SideEffectFree; @@ -20,7 +21,7 @@ */ public class PrimitiveTypeNode extends Node { - protected final PrimitiveTypeTree tree; + protected final Tree tree; /** For Types.isSameType. */ protected final Types types; @@ -31,14 +32,14 @@ public PrimitiveTypeNode(PrimitiveTypeTree tree, Types types) { this.types = types; } - public PrimitiveTypeNode(MemberSelectTree tree, Types types, boolean dummy) { + public PrimitiveTypeNode(MemberSelectTree tree, Types types) { super(TreeUtils.typeOf(tree)); - this.tree = (PrimitiveTypeTree) tree; + this.tree = tree; this.types = types; } @Override - public PrimitiveTypeTree getTree() { + public Tree getTree() { return tree; } From 731e05e8616f00e1866bcfd2f9d31a93bde9beca Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Sun, 15 Dec 2024 17:42:15 -0500 Subject: [PATCH 27/39] Only handle class literal --- .../dataflow/cfg/builder/CFGTranslationPhaseOne.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/CFGTranslationPhaseOne.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/CFGTranslationPhaseOne.java index 497ce47dec4..6ac6bb36e8b 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/CFGTranslationPhaseOne.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/CFGTranslationPhaseOne.java @@ -3671,7 +3671,8 @@ public Node visitMemberSelect(MemberSelectTree tree, Void p) { Node result = new PackageNameNode(tree, (PackageNameNode) expr); extendWithNode(result); return result; - } else if (element.getKind() == ElementKind.FIELD) { + } else if (element.getKind() == ElementKind.FIELD + && element.toString().equals("class")) { Node result = new PrimitiveTypeNode(tree, types); extendWithNode((PrimitiveTypeNode) result); return result; From 076d3d3a4d06bd9946eadf49b3ba5374ade87f9a Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Sun, 15 Dec 2024 17:43:26 -0500 Subject: [PATCH 28/39] PrimitiveTypeNode Javadoc --- .../dataflow/cfg/node/PrimitiveTypeNode.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/PrimitiveTypeNode.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/PrimitiveTypeNode.java index 4f197861b67..9de2f1df9b8 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/PrimitiveTypeNode.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/PrimitiveTypeNode.java @@ -20,18 +20,30 @@ *

type .class */ public class PrimitiveTypeNode extends Node { - + /** The tree that represents the type. */ protected final Tree tree; /** For Types.isSameType. */ protected final Types types; + /** + * Create a new PrimitiveTypeNode. + * + * @param tree the tree that represents the type + * @param types the types utility + */ public PrimitiveTypeNode(PrimitiveTypeTree tree, Types types) { super(TreeUtils.typeOf(tree)); this.tree = tree; this.types = types; } + /** + * Create a new PrimitiveTypeNode. + * + * @param tree the tree that represents the type + * @param types the types utility + */ public PrimitiveTypeNode(MemberSelectTree tree, Types types) { super(TreeUtils.typeOf(tree)); this.tree = tree; From 691d2069d73a3dd54043a5a75591cf5a5529db48 Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Sun, 15 Dec 2024 18:00:16 -0800 Subject: [PATCH 29/39] Handle class literal seperately --- .../checkerframework/checker/lock/LockVisitor.java | 13 +++++++++++++ .../org/checkerframework/javacutil/TreeUtils.java | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/checker/src/main/java/org/checkerframework/checker/lock/LockVisitor.java b/checker/src/main/java/org/checkerframework/checker/lock/LockVisitor.java index 6c8f71dcf9c..2bb8d48efc4 100644 --- a/checker/src/main/java/org/checkerframework/checker/lock/LockVisitor.java +++ b/checker/src/main/java/org/checkerframework/checker/lock/LockVisitor.java @@ -1117,6 +1117,19 @@ public Void visitIdentifier(IdentifierTree tree, Void p) { .getAnnotationInHierarchy(atypeFactory.GUARDEDBY); checkLockOfImplicitThis(tree, guardedBy); } + } else if (TreeUtils.isClassLiteral(tree)) { + Tree parent = getCurrentPath().getParentPath().getLeaf(); + // If the parent is not a member select, or if it is and the field is the expression, + // then the field is accessed via an implicit this. + if ((parent.getKind() != Tree.Kind.MEMBER_SELECT + || ((MemberSelectTree) parent).getExpression() == tree) + && !ElementUtils.isStatic(TreeUtils.elementFromUse(tree))) { + AnnotationMirror guardedBy = + atypeFactory + .getSelfType(tree) + .getAnnotationInHierarchy(atypeFactory.GUARDEDBY); + checkLockOfImplicitThis(tree, guardedBy); + } } return super.visitIdentifier(tree, p); } diff --git a/javacutil/src/main/java/org/checkerframework/javacutil/TreeUtils.java b/javacutil/src/main/java/org/checkerframework/javacutil/TreeUtils.java index 0d7451c973f..a4c66fb2ba0 100644 --- a/javacutil/src/main/java/org/checkerframework/javacutil/TreeUtils.java +++ b/javacutil/src/main/java/org/checkerframework/javacutil/TreeUtils.java @@ -1490,7 +1490,7 @@ public static boolean isFieldAccess(Tree tree) { /** * Compute the name of the field that the field access {@code tree} accesses. Requires {@code * tree} to be a field access, as determined by {@code isFieldAccess} (which currently also - * returns true for class literals and qualified this). + * returns true for qualified this). * * @param tree a field access tree * @return the name of the field accessed by {@code tree} From 699ffd30219183928dc511712c0a03c3eb3d1adf Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Sun, 15 Dec 2024 18:18:46 -0800 Subject: [PATCH 30/39] Also generate javaexpression for class literal and undo lockvisitor change --- .../checkerframework/checker/lock/LockVisitor.java | 13 ------------- .../dataflow/expression/JavaExpression.java | 4 ++++ 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/checker/src/main/java/org/checkerframework/checker/lock/LockVisitor.java b/checker/src/main/java/org/checkerframework/checker/lock/LockVisitor.java index 2bb8d48efc4..6c8f71dcf9c 100644 --- a/checker/src/main/java/org/checkerframework/checker/lock/LockVisitor.java +++ b/checker/src/main/java/org/checkerframework/checker/lock/LockVisitor.java @@ -1117,19 +1117,6 @@ public Void visitIdentifier(IdentifierTree tree, Void p) { .getAnnotationInHierarchy(atypeFactory.GUARDEDBY); checkLockOfImplicitThis(tree, guardedBy); } - } else if (TreeUtils.isClassLiteral(tree)) { - Tree parent = getCurrentPath().getParentPath().getLeaf(); - // If the parent is not a member select, or if it is and the field is the expression, - // then the field is accessed via an implicit this. - if ((parent.getKind() != Tree.Kind.MEMBER_SELECT - || ((MemberSelectTree) parent).getExpression() == tree) - && !ElementUtils.isStatic(TreeUtils.elementFromUse(tree))) { - AnnotationMirror guardedBy = - atypeFactory - .getSelfType(tree) - .getAnnotationInHierarchy(atypeFactory.GUARDEDBY); - checkLockOfImplicitThis(tree, guardedBy); - } } return super.visitIdentifier(tree, p); } diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/expression/JavaExpression.java b/dataflow/src/main/java/org/checkerframework/dataflow/expression/JavaExpression.java index dc4404998d0..cf4227d7c11 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/expression/JavaExpression.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/expression/JavaExpression.java @@ -28,6 +28,7 @@ import org.checkerframework.dataflow.cfg.node.MethodInvocationNode; import org.checkerframework.dataflow.cfg.node.NarrowingConversionNode; import org.checkerframework.dataflow.cfg.node.Node; +import org.checkerframework.dataflow.cfg.node.PrimitiveTypeNode; import org.checkerframework.dataflow.cfg.node.StringConversionNode; import org.checkerframework.dataflow.cfg.node.SuperNode; import org.checkerframework.dataflow.cfg.node.ThisNode; @@ -280,6 +281,9 @@ public static JavaExpression fromNode(Node receiverNode) { JavaExpression result = null; if (receiverNode instanceof FieldAccessNode) { result = fromNodeFieldAccess((FieldAccessNode) receiverNode); + } else if (receiverNode instanceof PrimitiveTypeNode) { + PrimitiveTypeNode pn = (PrimitiveTypeNode) receiverNode; + result = new ClassName(pn.getType()); } else if (receiverNode instanceof ThisNode) { result = new ThisReference(receiverNode.getType()); } else if (receiverNode instanceof SuperNode) { From 838fa797b8007953f361921221e71649cec06b42 Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Sun, 15 Dec 2024 18:43:54 -0800 Subject: [PATCH 31/39] Don't do cast and comment out unknown condition for testing --- .../java/org/checkerframework/checker/lock/LockStore.java | 8 ++++---- .../checkerframework/dataflow/expression/ClassName.java | 2 +- .../dataflow/expression/JavaExpression.java | 5 ++--- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/checker/src/main/java/org/checkerframework/checker/lock/LockStore.java b/checker/src/main/java/org/checkerframework/checker/lock/LockStore.java index cbf58ce5c44..01e9cec3fdf 100644 --- a/checker/src/main/java/org/checkerframework/checker/lock/LockStore.java +++ b/checker/src/main/java/org/checkerframework/checker/lock/LockStore.java @@ -77,10 +77,10 @@ public LockStore leastUpperBound(LockStore other) { * This is only done for @LockPossiblyHeld. This is not sound for other type qualifiers. */ public void insertLockPossiblyHeld(JavaExpression je) { - if (je.containsUnknown()) { - // Expressions containing unknown expressions are not stored. - return; - } + // if (je.containsUnknown()) { + // // Expressions containing unknown expressions are not stored. + // return; + // } if (je instanceof LocalVariable) { LocalVariable localVar = (LocalVariable) je; CFValue current = localVariableValues.get(localVar); diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/expression/ClassName.java b/dataflow/src/main/java/org/checkerframework/dataflow/expression/ClassName.java index 708bdaa6ee4..2e4ee4e13cd 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/expression/ClassName.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/expression/ClassName.java @@ -19,7 +19,7 @@ public class ClassName extends JavaExpression { /** * Creates a new ClassName object for the given type. * - * @param type the type for the new ClassName. If it will represent a class literal, the type is + * @param type the type for the new ClassName. If it represents a class literal, the type is * declared primitive, void, or array of one of them. If it represents part of a static * field access or static method invocation, the type is declared, type variable, or array * (including array of primitive). diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/expression/JavaExpression.java b/dataflow/src/main/java/org/checkerframework/dataflow/expression/JavaExpression.java index cf4227d7c11..652010ca457 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/expression/JavaExpression.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/expression/JavaExpression.java @@ -282,8 +282,7 @@ public static JavaExpression fromNode(Node receiverNode) { if (receiverNode instanceof FieldAccessNode) { result = fromNodeFieldAccess((FieldAccessNode) receiverNode); } else if (receiverNode instanceof PrimitiveTypeNode) { - PrimitiveTypeNode pn = (PrimitiveTypeNode) receiverNode; - result = new ClassName(pn.getType()); + result = new ClassName(receiverNode.getType()); } else if (receiverNode instanceof ThisNode) { result = new ThisReference(receiverNode.getType()); } else if (receiverNode instanceof SuperNode) { @@ -563,7 +562,7 @@ private static JavaExpression fromMemberSelect(MemberSelectTree memberSelectTree return new ClassName(expressionType); } if (TreeUtils.isExplicitThisDereference(memberSelectTree)) { - // the identifier is "class" + // the identifier is "this" return new ThisReference(expressionType); } From e5a3cd8cdac3a0cd39097f857e1e662dccef17c4 Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Sun, 15 Dec 2024 18:55:02 -0800 Subject: [PATCH 32/39] Don't run JSpecify first --- .../test-jspecify-reference-checker.sh | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/checker/bin-devel/test-jspecify-reference-checker.sh b/checker/bin-devel/test-jspecify-reference-checker.sh index 86557841328..f0d52adb2bd 100755 --- a/checker/bin-devel/test-jspecify-reference-checker.sh +++ b/checker/bin-devel/test-jspecify-reference-checker.sh @@ -1,26 +1,26 @@ -#!/bin/bash - -set -e -set -o verbose -set -o xtrace -export SHELLOPTS -echo "SHELLOPTS=${SHELLOPTS}" - -SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" -# shellcheck disable=SC1090 # In newer shellcheck than 0.6.0, pass: "-P SCRIPTDIR" (literally) -export ORG_GRADLE_PROJECT_useJdk17Compiler=true -source "$SCRIPTDIR"/clone-related.sh -./gradlew assembleForJavac --console=plain -Dorg.gradle.internal.http.socketTimeout=60000 -Dorg.gradle.internal.http.connectionTimeout=60000 - -GIT_SCRIPTS="$SCRIPTDIR/.git-scripts" -# TODO: remove uses of `main-eisop` once that becomes `main`. -"$GIT_SCRIPTS/git-clone-related" --upstream-branch main-eisop jspecify jspecify-reference-checker - -cd ../jspecify-reference-checker - -# Delete the eisop/jdk that was already cloned... -rm -r ../jdk -# instead clone the jspecify/jdk. -"$GIT_SCRIPTS/git-clone-related" jspecify jdk - -JSPECIFY_CONFORMANCE_TEST_MODE=details ./gradlew build conformanceTests demoTest --console=plain --include-build "$CHECKERFRAMEWORK" +##!/bin/bash +# +#set -e +#set -o verbose +#set -o xtrace +#export SHELLOPTS +#echo "SHELLOPTS=${SHELLOPTS}" +# +#SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +## shellcheck disable=SC1090 # In newer shellcheck than 0.6.0, pass: "-P SCRIPTDIR" (literally) +#export ORG_GRADLE_PROJECT_useJdk17Compiler=true +#source "$SCRIPTDIR"/clone-related.sh +#./gradlew assembleForJavac --console=plain -Dorg.gradle.internal.http.socketTimeout=60000 -Dorg.gradle.internal.http.connectionTimeout=60000 +# +#GIT_SCRIPTS="$SCRIPTDIR/.git-scripts" +## TODO: remove uses of `main-eisop` once that becomes `main`. +#"$GIT_SCRIPTS/git-clone-related" --upstream-branch main-eisop jspecify jspecify-reference-checker +# +#cd ../jspecify-reference-checker +# +## Delete the eisop/jdk that was already cloned... +#rm -r ../jdk +## instead clone the jspecify/jdk. +#"$GIT_SCRIPTS/git-clone-related" jspecify jdk +# +#JSPECIFY_CONFORMANCE_TEST_MODE=details ./gradlew build conformanceTests demoTest --console=plain --include-build "$CHECKERFRAMEWORK" From 3527e179054afdfb0ef4416897081ac2213348de Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Sun, 15 Dec 2024 23:58:19 -0800 Subject: [PATCH 33/39] Use ClassLiteralNode again and remove hacks --- .../test-jspecify-reference-checker.sh | 52 +++++++++---------- .../checker/lock/LockStore.java | 8 +-- .../cfg/builder/CFGTranslationPhaseOne.java | 5 +- .../cfg/node/AbstractNodeVisitor.java | 5 ++ .../dataflow/cfg/node/NodeVisitor.java | 9 ++++ .../dataflow/cfg/node/PrimitiveTypeNode.java | 20 ++----- .../dataflow/expression/JavaExpression.java | 7 +-- .../checkerframework/javacutil/TreeUtils.java | 8 +-- 8 files changed, 58 insertions(+), 56 deletions(-) diff --git a/checker/bin-devel/test-jspecify-reference-checker.sh b/checker/bin-devel/test-jspecify-reference-checker.sh index f0d52adb2bd..86557841328 100755 --- a/checker/bin-devel/test-jspecify-reference-checker.sh +++ b/checker/bin-devel/test-jspecify-reference-checker.sh @@ -1,26 +1,26 @@ -##!/bin/bash -# -#set -e -#set -o verbose -#set -o xtrace -#export SHELLOPTS -#echo "SHELLOPTS=${SHELLOPTS}" -# -#SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" -## shellcheck disable=SC1090 # In newer shellcheck than 0.6.0, pass: "-P SCRIPTDIR" (literally) -#export ORG_GRADLE_PROJECT_useJdk17Compiler=true -#source "$SCRIPTDIR"/clone-related.sh -#./gradlew assembleForJavac --console=plain -Dorg.gradle.internal.http.socketTimeout=60000 -Dorg.gradle.internal.http.connectionTimeout=60000 -# -#GIT_SCRIPTS="$SCRIPTDIR/.git-scripts" -## TODO: remove uses of `main-eisop` once that becomes `main`. -#"$GIT_SCRIPTS/git-clone-related" --upstream-branch main-eisop jspecify jspecify-reference-checker -# -#cd ../jspecify-reference-checker -# -## Delete the eisop/jdk that was already cloned... -#rm -r ../jdk -## instead clone the jspecify/jdk. -#"$GIT_SCRIPTS/git-clone-related" jspecify jdk -# -#JSPECIFY_CONFORMANCE_TEST_MODE=details ./gradlew build conformanceTests demoTest --console=plain --include-build "$CHECKERFRAMEWORK" +#!/bin/bash + +set -e +set -o verbose +set -o xtrace +export SHELLOPTS +echo "SHELLOPTS=${SHELLOPTS}" + +SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +# shellcheck disable=SC1090 # In newer shellcheck than 0.6.0, pass: "-P SCRIPTDIR" (literally) +export ORG_GRADLE_PROJECT_useJdk17Compiler=true +source "$SCRIPTDIR"/clone-related.sh +./gradlew assembleForJavac --console=plain -Dorg.gradle.internal.http.socketTimeout=60000 -Dorg.gradle.internal.http.connectionTimeout=60000 + +GIT_SCRIPTS="$SCRIPTDIR/.git-scripts" +# TODO: remove uses of `main-eisop` once that becomes `main`. +"$GIT_SCRIPTS/git-clone-related" --upstream-branch main-eisop jspecify jspecify-reference-checker + +cd ../jspecify-reference-checker + +# Delete the eisop/jdk that was already cloned... +rm -r ../jdk +# instead clone the jspecify/jdk. +"$GIT_SCRIPTS/git-clone-related" jspecify jdk + +JSPECIFY_CONFORMANCE_TEST_MODE=details ./gradlew build conformanceTests demoTest --console=plain --include-build "$CHECKERFRAMEWORK" diff --git a/checker/src/main/java/org/checkerframework/checker/lock/LockStore.java b/checker/src/main/java/org/checkerframework/checker/lock/LockStore.java index 01e9cec3fdf..cbf58ce5c44 100644 --- a/checker/src/main/java/org/checkerframework/checker/lock/LockStore.java +++ b/checker/src/main/java/org/checkerframework/checker/lock/LockStore.java @@ -77,10 +77,10 @@ public LockStore leastUpperBound(LockStore other) { * This is only done for @LockPossiblyHeld. This is not sound for other type qualifiers. */ public void insertLockPossiblyHeld(JavaExpression je) { - // if (je.containsUnknown()) { - // // Expressions containing unknown expressions are not stored. - // return; - // } + if (je.containsUnknown()) { + // Expressions containing unknown expressions are not stored. + return; + } if (je instanceof LocalVariable) { LocalVariable localVar = (LocalVariable) je; CFValue current = localVariableValues.get(localVar); diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/CFGTranslationPhaseOne.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/CFGTranslationPhaseOne.java index 6ac6bb36e8b..548a3ee97cf 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/CFGTranslationPhaseOne.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/CFGTranslationPhaseOne.java @@ -77,6 +77,7 @@ import org.checkerframework.dataflow.cfg.node.CatchMarkerNode; import org.checkerframework.dataflow.cfg.node.CharacterLiteralNode; import org.checkerframework.dataflow.cfg.node.ClassDeclarationNode; +import org.checkerframework.dataflow.cfg.node.ClassLiteralNode; import org.checkerframework.dataflow.cfg.node.ClassNameNode; import org.checkerframework.dataflow.cfg.node.ConditionalAndNode; import org.checkerframework.dataflow.cfg.node.ConditionalNotNode; @@ -3673,8 +3674,8 @@ public Node visitMemberSelect(MemberSelectTree tree, Void p) { return result; } else if (element.getKind() == ElementKind.FIELD && element.toString().equals("class")) { - Node result = new PrimitiveTypeNode(tree, types); - extendWithNode((PrimitiveTypeNode) result); + Node result = new ClassLiteralNode(tree, expr); + extendWithNode((ClassLiteralNode) result); return result; } else { throw new BugInCF("Unexpected element kind: " + element.getKind()); diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/AbstractNodeVisitor.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/AbstractNodeVisitor.java index 4f04678f1a4..9377d90a9f9 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/AbstractNodeVisitor.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/AbstractNodeVisitor.java @@ -358,6 +358,11 @@ public R visitPrimitiveType(PrimitiveTypeNode n, P p) { return visitNode(n, p); } + @Override + public R visitClassLiteral(ClassLiteralNode n, P p) { + return visitNode(n, p); + } + @Override public R visitClassName(ClassNameNode n, P p) { return visitNode(n, p); diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/NodeVisitor.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/NodeVisitor.java index 809ccfcf4cd..8e78a73b268 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/NodeVisitor.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/NodeVisitor.java @@ -595,6 +595,15 @@ public interface NodeVisitor { */ R visitPrimitiveType(PrimitiveTypeNode n, P p); + /** + * Visits a class literal node. + * + * @param n the {@link ClassLiteralNode} to be visited + * @param p the argument for the operation implemented by this visitor + * @return the return value of the operation implemented by this visitor + */ + R visitClassLiteral(ClassLiteralNode n, P p); + /** * Visits a class name node. * diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/PrimitiveTypeNode.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/PrimitiveTypeNode.java index 9de2f1df9b8..e8107a8704e 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/PrimitiveTypeNode.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/PrimitiveTypeNode.java @@ -1,8 +1,6 @@ package org.checkerframework.dataflow.cfg.node; -import com.sun.source.tree.MemberSelectTree; import com.sun.source.tree.PrimitiveTypeTree; -import com.sun.source.tree.Tree; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.dataflow.qual.SideEffectFree; @@ -20,8 +18,8 @@ *

type .class */ public class PrimitiveTypeNode extends Node { - /** The tree that represents the type. */ - protected final Tree tree; + /** The PrimitiveTypeTree that represents the type. */ + protected final PrimitiveTypeTree tree; /** For Types.isSameType. */ protected final Types types; @@ -38,20 +36,8 @@ public PrimitiveTypeNode(PrimitiveTypeTree tree, Types types) { this.types = types; } - /** - * Create a new PrimitiveTypeNode. - * - * @param tree the tree that represents the type - * @param types the types utility - */ - public PrimitiveTypeNode(MemberSelectTree tree, Types types) { - super(TreeUtils.typeOf(tree)); - this.tree = tree; - this.types = types; - } - @Override - public Tree getTree() { + public PrimitiveTypeTree getTree() { return tree; } diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/expression/JavaExpression.java b/dataflow/src/main/java/org/checkerframework/dataflow/expression/JavaExpression.java index 652010ca457..bd15ec22d89 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/expression/JavaExpression.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/expression/JavaExpression.java @@ -22,13 +22,13 @@ import org.checkerframework.dataflow.cfg.node.ArrayAccessNode; import org.checkerframework.dataflow.cfg.node.ArrayCreationNode; import org.checkerframework.dataflow.cfg.node.BinaryOperationNode; +import org.checkerframework.dataflow.cfg.node.ClassLiteralNode; import org.checkerframework.dataflow.cfg.node.ClassNameNode; import org.checkerframework.dataflow.cfg.node.FieldAccessNode; import org.checkerframework.dataflow.cfg.node.LocalVariableNode; import org.checkerframework.dataflow.cfg.node.MethodInvocationNode; import org.checkerframework.dataflow.cfg.node.NarrowingConversionNode; import org.checkerframework.dataflow.cfg.node.Node; -import org.checkerframework.dataflow.cfg.node.PrimitiveTypeNode; import org.checkerframework.dataflow.cfg.node.StringConversionNode; import org.checkerframework.dataflow.cfg.node.SuperNode; import org.checkerframework.dataflow.cfg.node.ThisNode; @@ -281,8 +281,9 @@ public static JavaExpression fromNode(Node receiverNode) { JavaExpression result = null; if (receiverNode instanceof FieldAccessNode) { result = fromNodeFieldAccess((FieldAccessNode) receiverNode); - } else if (receiverNode instanceof PrimitiveTypeNode) { - result = new ClassName(receiverNode.getType()); + } else if (receiverNode instanceof ClassLiteralNode) { + ClassLiteralNode cl = (ClassLiteralNode) receiverNode; + result = new ClassName(cl.getClassName().getType()); } else if (receiverNode instanceof ThisNode) { result = new ThisReference(receiverNode.getType()); } else if (receiverNode instanceof SuperNode) { diff --git a/javacutil/src/main/java/org/checkerframework/javacutil/TreeUtils.java b/javacutil/src/main/java/org/checkerframework/javacutil/TreeUtils.java index a4c66fb2ba0..d825b9c9202 100644 --- a/javacutil/src/main/java/org/checkerframework/javacutil/TreeUtils.java +++ b/javacutil/src/main/java/org/checkerframework/javacutil/TreeUtils.java @@ -1462,12 +1462,12 @@ public static boolean isFieldAccess(Tree tree) { */ // TODO: fix value for qualified this, which is not field accesses. public static @Nullable VariableElement asFieldAccess(Tree tree) { + if (isClassLiteral(tree)) { + return null; + } if (tree.getKind() == Tree.Kind.MEMBER_SELECT) { - // explicit member access (or a class literal or a qualified this) + // explicit member access (or a qualified this) MemberSelectTree memberSelect = (MemberSelectTree) tree; - if (isClassLiteral(memberSelect)) { - return null; - } assert isUseOfElement(memberSelect) : "@AssumeAssertion(nullness): tree kind"; Element el = TreeUtils.elementFromUse(memberSelect); if (el.getKind().isField()) { From e3a638141d240cb67e430fa3b609273ce94fc2ad Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Mon, 16 Dec 2024 00:03:01 -0800 Subject: [PATCH 34/39] Add ClassLiteral file --- .../dataflow/cfg/node/ClassLiteralNode.java | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/ClassLiteralNode.java diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/ClassLiteralNode.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/ClassLiteralNode.java new file mode 100644 index 00000000000..0a73c0337fb --- /dev/null +++ b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/ClassLiteralNode.java @@ -0,0 +1,54 @@ +package org.checkerframework.dataflow.cfg.node; + +import com.sun.source.tree.MemberSelectTree; +import com.sun.source.tree.Tree; + +import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.javacutil.TreeUtils; + +import java.util.Collection; +import java.util.Collections; + +/** A node for a class literal. For example: {@code String.class}. */ +public class ClassLiteralNode extends Node { + /** The tree for the class literal. */ + protected final MemberSelectTree tree; + + /** The class name of class literal */ + protected final Node className; + + /** + * Create a new ClassLiteralNode. + * + * @param tree the class literal + */ + public ClassLiteralNode(MemberSelectTree tree, Node className) { + super(TreeUtils.typeOf(tree)); + this.tree = tree; + this.className = className; + } + + @Override + public @Nullable Tree getTree() { + return tree; + } + + public Node getClassName() { + return className; + } + + @Override + public R accept(NodeVisitor visitor, P p) { + return visitor.visitClassLiteral(this, p); + } + + @Override + public String toString() { + return tree.toString(); + } + + @Override + public Collection getOperands() { + return Collections.emptyList(); + } +} From 86d7d43a60073c8b2aa6b437ffe548c90b9bd4a8 Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Mon, 16 Dec 2024 00:10:28 -0800 Subject: [PATCH 35/39] Don't check jspeicfy yet --- .../test-jspecify-reference-checker.sh | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/checker/bin-devel/test-jspecify-reference-checker.sh b/checker/bin-devel/test-jspecify-reference-checker.sh index 86557841328..f0d52adb2bd 100755 --- a/checker/bin-devel/test-jspecify-reference-checker.sh +++ b/checker/bin-devel/test-jspecify-reference-checker.sh @@ -1,26 +1,26 @@ -#!/bin/bash - -set -e -set -o verbose -set -o xtrace -export SHELLOPTS -echo "SHELLOPTS=${SHELLOPTS}" - -SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" -# shellcheck disable=SC1090 # In newer shellcheck than 0.6.0, pass: "-P SCRIPTDIR" (literally) -export ORG_GRADLE_PROJECT_useJdk17Compiler=true -source "$SCRIPTDIR"/clone-related.sh -./gradlew assembleForJavac --console=plain -Dorg.gradle.internal.http.socketTimeout=60000 -Dorg.gradle.internal.http.connectionTimeout=60000 - -GIT_SCRIPTS="$SCRIPTDIR/.git-scripts" -# TODO: remove uses of `main-eisop` once that becomes `main`. -"$GIT_SCRIPTS/git-clone-related" --upstream-branch main-eisop jspecify jspecify-reference-checker - -cd ../jspecify-reference-checker - -# Delete the eisop/jdk that was already cloned... -rm -r ../jdk -# instead clone the jspecify/jdk. -"$GIT_SCRIPTS/git-clone-related" jspecify jdk - -JSPECIFY_CONFORMANCE_TEST_MODE=details ./gradlew build conformanceTests demoTest --console=plain --include-build "$CHECKERFRAMEWORK" +##!/bin/bash +# +#set -e +#set -o verbose +#set -o xtrace +#export SHELLOPTS +#echo "SHELLOPTS=${SHELLOPTS}" +# +#SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +## shellcheck disable=SC1090 # In newer shellcheck than 0.6.0, pass: "-P SCRIPTDIR" (literally) +#export ORG_GRADLE_PROJECT_useJdk17Compiler=true +#source "$SCRIPTDIR"/clone-related.sh +#./gradlew assembleForJavac --console=plain -Dorg.gradle.internal.http.socketTimeout=60000 -Dorg.gradle.internal.http.connectionTimeout=60000 +# +#GIT_SCRIPTS="$SCRIPTDIR/.git-scripts" +## TODO: remove uses of `main-eisop` once that becomes `main`. +#"$GIT_SCRIPTS/git-clone-related" --upstream-branch main-eisop jspecify jspecify-reference-checker +# +#cd ../jspecify-reference-checker +# +## Delete the eisop/jdk that was already cloned... +#rm -r ../jdk +## instead clone the jspecify/jdk. +#"$GIT_SCRIPTS/git-clone-related" jspecify jdk +# +#JSPECIFY_CONFORMANCE_TEST_MODE=details ./gradlew build conformanceTests demoTest --console=plain --include-build "$CHECKERFRAMEWORK" From 0ec3a94cdac16d11199e129697171aff5097fdf8 Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Mon, 16 Dec 2024 00:22:31 -0800 Subject: [PATCH 36/39] Javadoc --- .../org/checkerframework/dataflow/cfg/node/ClassLiteralNode.java | 1 + 1 file changed, 1 insertion(+) diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/ClassLiteralNode.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/ClassLiteralNode.java index 0a73c0337fb..740f7a21ca0 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/ClassLiteralNode.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/ClassLiteralNode.java @@ -21,6 +21,7 @@ public class ClassLiteralNode extends Node { * Create a new ClassLiteralNode. * * @param tree the class literal + * @param className the class name for the class literal */ public ClassLiteralNode(MemberSelectTree tree, Node className) { super(TreeUtils.typeOf(tree)); From de55ec052741944ac8865deb0660631a516e9775 Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Mon, 16 Dec 2024 00:31:00 -0800 Subject: [PATCH 37/39] Javadoc --- .../org/checkerframework/dataflow/cfg/node/ClassLiteralNode.java | 1 + 1 file changed, 1 insertion(+) diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/ClassLiteralNode.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/ClassLiteralNode.java index 740f7a21ca0..d2912f2a828 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/ClassLiteralNode.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/ClassLiteralNode.java @@ -34,6 +34,7 @@ public ClassLiteralNode(MemberSelectTree tree, Node className) { return tree; } + /** Returns the class name of the class literal. */ public Node getClassName() { return className; } From 115ba244f2953e6c37983b9b4875484214553a33 Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Mon, 16 Dec 2024 03:40:54 -0500 Subject: [PATCH 38/39] Javadoc --- .../dataflow/cfg/node/ClassLiteralNode.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/ClassLiteralNode.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/ClassLiteralNode.java index d2912f2a828..dd7ef501962 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/ClassLiteralNode.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/node/ClassLiteralNode.java @@ -34,7 +34,11 @@ public ClassLiteralNode(MemberSelectTree tree, Node className) { return tree; } - /** Returns the class name of the class literal. */ + /** + * Get the class name of the class literal. + * + * @return the class name of the class literal + */ public Node getClassName() { return className; } From eda862479a6c854d2dadfd88cdcb9ba087f0bb84 Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Mon, 16 Dec 2024 20:05:20 -0500 Subject: [PATCH 39/39] Enable JSpecify check since others already passed --- .../test-jspecify-reference-checker.sh | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/checker/bin-devel/test-jspecify-reference-checker.sh b/checker/bin-devel/test-jspecify-reference-checker.sh index f0d52adb2bd..86557841328 100755 --- a/checker/bin-devel/test-jspecify-reference-checker.sh +++ b/checker/bin-devel/test-jspecify-reference-checker.sh @@ -1,26 +1,26 @@ -##!/bin/bash -# -#set -e -#set -o verbose -#set -o xtrace -#export SHELLOPTS -#echo "SHELLOPTS=${SHELLOPTS}" -# -#SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" -## shellcheck disable=SC1090 # In newer shellcheck than 0.6.0, pass: "-P SCRIPTDIR" (literally) -#export ORG_GRADLE_PROJECT_useJdk17Compiler=true -#source "$SCRIPTDIR"/clone-related.sh -#./gradlew assembleForJavac --console=plain -Dorg.gradle.internal.http.socketTimeout=60000 -Dorg.gradle.internal.http.connectionTimeout=60000 -# -#GIT_SCRIPTS="$SCRIPTDIR/.git-scripts" -## TODO: remove uses of `main-eisop` once that becomes `main`. -#"$GIT_SCRIPTS/git-clone-related" --upstream-branch main-eisop jspecify jspecify-reference-checker -# -#cd ../jspecify-reference-checker -# -## Delete the eisop/jdk that was already cloned... -#rm -r ../jdk -## instead clone the jspecify/jdk. -#"$GIT_SCRIPTS/git-clone-related" jspecify jdk -# -#JSPECIFY_CONFORMANCE_TEST_MODE=details ./gradlew build conformanceTests demoTest --console=plain --include-build "$CHECKERFRAMEWORK" +#!/bin/bash + +set -e +set -o verbose +set -o xtrace +export SHELLOPTS +echo "SHELLOPTS=${SHELLOPTS}" + +SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +# shellcheck disable=SC1090 # In newer shellcheck than 0.6.0, pass: "-P SCRIPTDIR" (literally) +export ORG_GRADLE_PROJECT_useJdk17Compiler=true +source "$SCRIPTDIR"/clone-related.sh +./gradlew assembleForJavac --console=plain -Dorg.gradle.internal.http.socketTimeout=60000 -Dorg.gradle.internal.http.connectionTimeout=60000 + +GIT_SCRIPTS="$SCRIPTDIR/.git-scripts" +# TODO: remove uses of `main-eisop` once that becomes `main`. +"$GIT_SCRIPTS/git-clone-related" --upstream-branch main-eisop jspecify jspecify-reference-checker + +cd ../jspecify-reference-checker + +# Delete the eisop/jdk that was already cloned... +rm -r ../jdk +# instead clone the jspecify/jdk. +"$GIT_SCRIPTS/git-clone-related" jspecify jdk + +JSPECIFY_CONFORMANCE_TEST_MODE=details ./gradlew build conformanceTests demoTest --console=plain --include-build "$CHECKERFRAMEWORK"