Skip to content

Fix duplicated artifical call-edges when performing two-phase pointer analysis - #220

Merged
zhangt2333 merged 1 commit into
pascal-lab:masterfrom
lollipop190:master
Aug 26, 2026
Merged

Fix duplicated artifical call-edges when performing two-phase pointer analysis#220
zhangt2333 merged 1 commit into
pascal-lab:masterfrom
lollipop190:master

Conversation

@lollipop190

@lollipop190 lollipop190 commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Fix: duplicated artifical call edges generated by IRModelPlugin in two-phase pointer analyses

Summary

This PR prevents duplicate artificial call edges from being generated by IRModelPlugin during two-phase pointer analyses such as Zipper and Zipper-e.

Problem

Advanced pointer analyses such as Zipper and Zipper-e first perform a context-insensitive pre-analysis and then run a selective context-sensitive analysis over the same World.

Take DoPriviledgedModel as an example, which is a concrete subclass of IRModelPlugin, and models AccessController.doPrivileged(...) by creating an artificial instance Invoke for PrivilegedAction.run(). Constructing the Invoke registers it with its receiver variable through Var.addInvoke().

However, the artificial Invoke created during the pre-analysis remains registered after that analysis finishes. The selective analysis then creates another equivalent artificial Invoke. As a result, the receiver variable contains artificial invocations from both analysis phases.

When DefaultSolver.processCall() processes the statements returned by Var.getInvokes(), both equivalent Invoke objects are processed, causing the same logical artificial call edge to be generated more than once. Because the two call sites are distinct objects, these duplicate edges are not deduplicated by the call graph.

Reproduction

  1. Build Tai-e (the latest commit 0abf36d) and run Zipper-e guided 2obj pointer analysis on antlr from dacapo-2006:
-java 6 -cp java-benchmarks/dacapo-2006/antlr.jar:java-benchmarks/dacapo-2006/antlr-deps.jar -m Harness -a pta=cs:2-obj;advanced:zipper-e;reflection-log:java-benchmarks/dacapo-2006/antlr-refl.log;
  1. Explicitly print the extra call edges

To expose the duplicates directly, temporarily add the following block in ResultProcessor.logStatistics() immediately after the #call graph edges log statement:

result.getCallGraph().edges()
        .filter(edge -> edge.getCallSite().getIndex() < 0)
        .collect(Collectors.groupingBy(
                Object::toString, Collectors.counting()))
        .entrySet().stream()
        .filter(entry -> entry.getValue() > 1)
        .sorted(Map.Entry.comparingByKey())
        .forEach(entry -> System.out.println(
                "###EXTRA_CALL_EDGE:" + entry.getValue() +
                        "\t" + entry.getKey()));

which prints duplicated artificial edges such as:

###EXTRA_CALL_EDGE:2	[INTERFACE]<NativeModel: void doPrivileged()>[-1@L-1] %v2 = invokeinterface %v1.run() -> <NativeModel$1: java.lang.Object run()>

Fix

My current fix is to add IRModelPlugin.onFinish(), which now unregisters generated artificial instance invocations from their receiver variables so that subsequent solver runs no longer observe stale statements.

@github-actions

github-actions Bot commented Aug 25, 2026

Copy link
Copy Markdown

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@lollipop190

Copy link
Copy Markdown
Contributor Author

I have read the CLA Document and I hereby sign the CLA

github-actions Bot added a commit that referenced this pull request Aug 25, 2026
@zhangt2333 zhangt2333 changed the title Fix: duplicated artifical call-edges when performing two-phase pointer analysis Fix duplicated artifical call-edges when performing two-phase pointer analysis Aug 26, 2026
@codecov

codecov Bot commented Aug 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 76.46%. Comparing base (0abf36d) to head (0f9de17).

Additional details and impacted files
@@             Coverage Diff              @@
##             master     #220      +/-   ##
============================================
- Coverage     76.47%   76.46%   -0.01%     
- Complexity     7440     7441       +1     
============================================
  Files           657      657              
  Lines         25061    25069       +8     
  Branches       3717     3717              
============================================
+ Hits          19165    19169       +4     
  Misses         4504     4504              
- Partials       1392     1396       +4     
Files with missing lines Coverage Δ
...l/taie/analysis/pta/plugin/util/IRModelPlugin.java 82.97% <100.00%> (+3.49%) ⬆️

... and 5 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@zhangt2333 zhangt2333 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for submitting this PR and for taking the time to investigate this issue. The problem does exist, and it requires careful observation to uncover, so this is a valuable finding.

However, we see several limitations in the current solution:

  • It only addresses artificially generated Invoke statements. The same underlying issue may also affect other statement types, such as artificial field or array loads and stores, so the broader problem is not fully resolved.
  • It relies on an internal API and should not be considered the final design. Removing IR statements during the analysis lifecycle could potentially affect the monotonicity of the analysis. We have manually verified that this particular implementation does not currently cause such a problem, but we plan to redesign this part so that such an API is no longer needed.
  • It does not include a minimal reproducer or regression test case, which makes the behavior and the risk of future regressions more difficult to validate.

For these reasons, our initial preference would have been to track this as an issue rather than treat the current PR as the complete solution. We would then consider a more systematic approach—for example, consistently removing all generated statements, or addressing the problem at a fundamental level by centrally managing all artificial statements. The exact approach still needs to be discussed by the team.

That said, given the timing and the importance of supporting active community contributions, I plan to merge this PR directly as a short-term fix and address the problem comprehensively in follow-up commits.

Thank you again for finding and reporting this issue.

@zhangt2333
zhangt2333 merged commit 89aa399 into pascal-lab:master Aug 26, 2026
5 of 6 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 26, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants