Translating C code into safe Rust is an effective way to ensure its memory safety. Compared to rule-based translation which produces Rust code that remains largely unsafe, LLM-based methods can generate more idiomatic and safer Rust code because LLMs have been trained on vast amount of human-written idiomatic code. Although promising, existing LLM-based methods still struggle with project-level C-to-Rust translation. They typically partition a C project into smaller units (\eg{} functions) based on call graphs and translate them bottom-up to resolve program dependencies. However, this bottom-up, unit-by-unit paradigm often fails to translate pointers due to the lack of a global perspective on their usage. To address this problem, we propose a novel C-Rust Pointer Knowledge Graph (KG) that enriches a code-dependency graph with two types of pointer semantics: (i) pointer-usage information which record global behaviors such as points-to flows and map lower-level struct usage to higher-level units; and (ii) Rust-oriented annotations which encode ownership, mutability, nullability, and lifetime. Synthesizing the \kg{} with LLMs, we further propose \ourtool{}, which implements a project-level C-to-Rust translation technique. In \ourtool{}, the \kg{} provides LLMs with comprehensive pointer semantics from a global perspective, thus guiding LLMs towards generating safe and idiomatic Rust code from a given C project. Our experiments show that \ourtool{} reduces unsafe usages in translated Rust by 99.9\% compared to both rule-based translation and traditional LLM-based rewriting, while achieving an average 29.3\% higher functional correctness than those fuzzing-enhanced LLM methods.
Traduction au Niveau du Projet de C vers Rust via l'Intégration Synergique de Graphes de Connaissances et de Grands Modèles de Langage
- ID de l'article : 2510.10956
- Titre : Project-Level C-to-Rust Translation via Synergistic Integration of Knowledge Graphs and Large Language Models
- Auteurs : Zhiqiang Yuan, Wenjun Mao, Zhuo Chen, Xiyue Shang, Chong Wang, Yiling Lou, Xin Peng
- Classification : cs.SE (Génie Logiciel), cs.AI (Intelligence Artificielle)
- Date de Publication : 13 octobre 2025
- Lien de l'article : https://arxiv.org/abs/2510.10956
La traduction du code C en code Rust sécurisé constitue une méthode efficace pour assurer la sécurité mémoire. Comparées aux méthodes de traduction basées sur des règles qui produisent une grande quantité de code non sécurisé, les approches basées sur les grands modèles de langage (LLM) peuvent générer du code Rust plus idiomatique et sécurisé. Cependant, les méthodes LLM existantes rencontrent toujours des difficultés dans la traduction C vers Rust au niveau du projet, notamment en manquant d'une perspective globale lors du traitement des pointeurs. Pour résoudre ce problème, cet article propose un nouveau graphe de connaissances des pointeurs C-Rust (KG) qui enrichit le graphe de dépendances du code par deux sémantiques de pointeurs : (1) les informations d'utilisation des pointeurs enregistrant les comportements globaux ; (2) les annotations orientées Rust codifiant la propriété, la mutabilité, la nullabilité et les durées de vie. Sur la base de ce graphe de connaissances, la technique PTRMAPPER est proposée, réalisant la traduction C vers Rust au niveau du projet. Les expériences montrent que PTRMAPPER réduit l'utilisation de code non sécurisé de 99,9 % par rapport aux méthodes basées sur des règles et aux LLM traditionnels, et améliore en moyenne la correction fonctionnelle de 29,3 %.
Le langage C est largement utilisé dans les systèmes d'exploitation, les systèmes embarqués et les applications critiques pour les performances, mais sa gestion manuelle de la mémoire et ses opérations directes sur les pointeurs entraînent fréquemment des vulnérabilités de sécurité telles que les débordements de tampon et les fuites mémoire. Rust, en tant qu'alternative moderne, assure la sécurité mémoire tout en maintenant les performances du langage C. Par conséquent, la traduction automatique du code C hérité en Rust devient une nécessité urgente.
- Méthodes basées sur des règles : Dépendent de règles prédéfinies, le code Rust produit utilise largement des blocs unsafe, des pointeurs bruts et des appels de fonction externe, présentant toujours des risques de sécurité
- Méthodes LLM existantes : Adoptent un paradigme de traduction unitaire ascendant, manquent d'une perspective globale d'utilisation des pointeurs, rencontrent fréquemment des conflits définition-utilisation dans la traduction des pointeurs
Il existe des différences fondamentales entre C et Rust dans l'utilisation des pointeurs :
- Langage C : Les pointeurs sont hautement flexibles, seul le type est spécifié à la définition, la lecture et l'écriture peuvent être librement modifiées à l'utilisation
- Langage Rust : L'utilisation des pointeurs est strictement limitée, la propriété, la mutabilité et la durée de vie doivent être explicitement spécifiées à la définition, l'utilisation doit strictement respecter les règles du vérificateur d'emprunt
- Proposition d'un nouveau graphe de connaissances des pointeurs C-Rust (KG) : Capable de modéliser de manière complète les dépendances des unités de code, les informations d'utilisation des pointeurs et les annotations orientées Rust à partir du contexte au niveau du projet
- Conception de la technique de traduction au niveau du projet PTRMAPPER : Utilisant le KG des pointeurs C-Rust en synergie avec les LLM pour traduire les projets C en code Rust sécurisé et idiomatique
- Réalisation d'améliorations de performance significatives : Génération de code Rust plus idiomatique, plus sécurisé et d'une correction supérieure
- Fourniture d'une vérification expérimentale complète : Les expériences d'ablation démontrent l'importance des informations d'utilisation des pointeurs et des annotations orientées Rust pour améliorer la performance de traduction
Étant donné un projet C, traduire automatiquement celui-ci en un projet Rust fonctionnellement équivalent, sécurisé en mémoire et idiomatique. L'entrée est un ensemble de fichiers de code source C, la sortie est un projet Rust compilable et exécutable.
PTRMAPPER comprend trois phases principales :
Conception du Schéma du Graphe de Connaissances :
- Graphe de dépendances du code : Décrit les relations de dépendance entre les unités de code (fonctions, structures, énumérations, etc.)
- Informations d'utilisation des pointeurs : Capture le comportement des pointeurs au niveau du projet, incluant :
- Entités : Param (paramètre), Value (valeur de retour), Member (membre), Pointer (pointeur), etc.
- Relations : derivesFrom (relation de dérivation), mayAlias/noAlias (relation d'alias), pointsTo (relation de pointage), etc.
- Annotations orientées Rust : Contenant la propriété, la mutabilité, la nullabilité, les durées de vie et autres sémantiques
Processus de Construction :
- Extraction du graphe de dépendances du code : Utilisation de l'analyse statique pour extraire les unités de code et leurs relations de dépendance
- Extraction des informations d'utilisation des pointeurs : Adoption d'une stratégie d'analyse sensible au contexte et sensible aux champs
- Extraction des annotations orientées Rust : Analyse de la durée de vie des pointeurs basée sur des règles prédéfinies et annotation des sémantiques correspondantes
Identification et Ordonnancement des Unités de Traduction :
- Utilisation de l'algorithme de Tarjan pour détecter les composantes fortement connexes (SCC)
- Chaque SCC est traité comme une unité de traduction indépendante
- Tri topologique pour déterminer l'ordre de traduction ascendant
Extraction de la Sémantique des Pointeurs :
Pour chaque unité de traduction, extraction de la connaissance sémantique des pointeurs correspondante du KG, fournie au LLM sous la forme de triplets <entité1, relation, entité2>.
Traduction Incrémentale et Vérification :
- Intégration de l'unité de traduction, de la connaissance sémantique des pointeurs et du contexte Rust déjà traduit dans l'invite de traduction
- Chaque unité de traduction générée est immédiatement intégrée au projet Rust et vérifiée par compilation
- Si des erreurs surviennent, un mécanisme de correction d'erreurs est déclenché
Utilisation de la version Rust du KG des pointeurs pour fournir au LLM un contexte sémantique au niveau du projet :
- Les relations de dépendance aident à identifier précisément les unités de code liées aux erreurs
- Les annotations orientées Rust fournissent des conseils sémantiques précis pour une correction efficace
- Modélisation de la sémantique globale des pointeurs : Première intégration des informations d'utilisation des pointeurs au niveau du projet et de la sémantique spécifique à Rust dans un graphe de connaissances
- Paradigme de traduction synergique : Combinaison de la perspective globale du graphe de connaissances avec la capacité générative du LLM
- Mécanisme de vérification incrémentale : Détection et correction rapides des erreurs, prévention de l'accumulation d'erreurs
- Correction d'erreurs intelligente : Basée sur les informations sémantiques du KG plutôt que sur les seuls messages d'erreur du compilateur
Utilisation de 16 projets C réels de l'ensemble de données CROWN, avec des lignes de code allant de 154 à 14 829, incluant :
- Petits projets : avl, buffer, genann, quadtree, rgba, urlparser, etc.
- Grands projets : bzip2, heman, lodepng, etc.
Pour évaluer l'équivalence fonctionnelle, des tests unitaires ont été construits manuellement, réalisant une couverture de lignes de 81,4 % à 97,7 % et une couverture de fonctions de 92,9 % à 100,0 %.
Évaluation de l'Idiomaticité :
- Lint Alert Count : Utilisation de Rust-Clippy pour compter les avertissements de code non idiomatique
- Unsafe Usage Count : Utilisation de Cargo-geiger pour compter les utilisations de code unsafe
Évaluation de la Correction :
- Compiled : Proportion de fonctions compilées avec succès
- Equiv. : Proportion de fonctions passant les tests unitaires
- Comparaison d'idiomaticité : CROWN (basée sur des règles), PR2 (réécriture LLM)
- Comparaison de correction : FLOURINE (méthode LLM améliorée par test de fuzzing)
- Expériences d'ablation : PTRTRANSPS, PTRTRANSPU, PTRTRANSRA, PTRTRANSEC et autres variantes
- LLM : ChatGPT-4o, temperature=0
- Analyse statique : Clang, Doxygen, framework SVF
- Correction d'erreurs : Maximum 5 itérations
- Vérification de compilation : cargo check
Amélioration Significative de l'Idiomaticité :
- Par rapport à CROWN : Réduction des avertissements Lint de 94,9 % (6 802 → 349), réduction de l'utilisation unsafe de 99,9 % (141 866 → 85)
- Par rapport à PR2 : Réduction des avertissements Lint de 91,8 % (4 272 → 349), réduction de l'utilisation unsafe de 99,9 % (134 185 → 85)
Amélioration Substantielle de la Correction :
- Par rapport à FLOURINE : Taux de compilation réussi amélioré de 28,4 % (98,3 % vs 69,9 %), taux d'équivalence fonctionnelle amélioré de 29,3 % (81,6 % vs 52,3 %)
- Petits projets (avl, rgba, ht, bst) réalisant 100 % d'équivalence fonctionnelle
Les expériences d'ablation valident l'importance de chaque composant :
- Sans sémantique des pointeurs (PTRTRANSPS) : Taux d'équivalence baisse de 81,6 % à 59,5 %, baisse de 22,1 %
- Informations d'utilisation des pointeurs uniquement (PTRTRANSRA) : Performance inférieure à la version complète
- Annotations Rust uniquement (PTRTRANSPU) : Même baisse de performance
- Sans correction d'erreurs (PTRTRANSEC) : Taux d'équivalence baisse de 81,6 % à 50,8 %, baisse de 30,8 %
PTRMAPPER montre une performance stable à différents niveaux de complexité :
- Lignes de code : Performance stable avec l'augmentation de la complexité, FLOURINE chute drastiquement
- Relations de dépendance : Taux d'équivalence de 57,1 % pour dépendances [16,44), FLOURINE à 0 %
- Nombre de pointeurs : Taux d'équivalence de 50,0 % pour pointeurs [20,50), FLOURINE à 0 %
Prenant le projet Quadtree comme exemple, démonstration de la façon dont PTRMAPPER résout les conflits d'emprunt complexes :
- Identification du paramètre
tree comme emprunt immuable &Quadtree - Séparation de
root comme emprunt mutable &mut QuadtreeNode - Extraction de
key_free comme paramètre indépendant pour éviter les conflits d'emprunt - Traitement correct de la sémantique de propriété
- Méthodes basées sur des règles : Corrode, C2RUST, etc., produisant une grande quantité de code unsafe
- Méthodes basées sur LLM : SPECTRA, FLOURINE, etc., manquant de perspective globale
- Méthodes de traduction unitaire : SYZYGY, etc., présentant une perte de sémantique des pointeurs
- Première modélisation systématique de la sémantique des pointeurs au niveau du projet
- Approche synergique combinant l'analyse statique et la génération LLM
- Amélioration significative de la sécurité et de la correction
- Le graphe de connaissances des pointeurs C-Rust résout efficacement le problème de perte de sémantique des pointeurs dans la traduction au niveau du projet
- L'intégration synergique de l'analyse statique et du LLM améliore significativement la qualité de traduction
- Les mécanismes de vérification incrémentale et de correction d'erreurs intelligente assurent la fiabilité de la traduction
- Surcharge de construction : La construction du graphe de connaissances nécessite un temps d'analyse statique supplémentaire
- Dépendance aux règles : L'extraction d'annotations Rust dépend de règles prédéfinies, pouvant présenter une couverture incomplète
- Échelle du projet : La scalabilité sur les projets de très grande taille reste à vérifier
- Intervention manuelle : Les cas complexes peuvent nécessiter quelques ajustements manuels
- Optimisation de l'efficacité de construction du graphe de connaissances
- Extension à d'autres paires de langages de programmation
- Intégration de techniques d'analyse de programme supplémentaires
- Amélioration du degré d'automatisation
- Forte Innovativité : Première combinaison de graphes de connaissances et de LLM pour la traduction de code, résolvant les problèmes fondamentaux des méthodes existantes
- Méthode Systématique : De l'analyse des problèmes à la conception des solutions, tout est complet, la trajectoire technique est claire
- Expérimentation Complète : 16 projets réels, multiples méthodes de comparaison, expériences d'ablation détaillées
- Résultats Significatifs : Améliorations substantielles dans les trois dimensions de sécurité, idiomaticité et correction
- Valeur Pratique Élevée : Résout des problèmes d'ingénierie réels, possédant de fortes perspectives d'application
- Problèmes de Scalabilité : La complexité computationnelle de l'analyse statique peut limiter l'application sur les projets de très grande taille
- Complétude des Règles : Les règles d'extraction d'annotations Rust peuvent ne pas couvrir tous les cas limites
- Limitations d'Évaluation : Principalement validé sur des projets de petite et moyenne taille, la performance sur les grands projets nécessite une vérification supplémentaire
- Dépendance à la Qualité : L'efficacité de la méthode dépend largement de la précision de l'analyse statique
- Contribution Académique : Fournit un nouveau paradigme de recherche pour le domaine de la traduction de code, combinant l'analyse de programme et l'IA générative
- Valeur d'Ingénierie : Fournit un outil pratique pour la migration C vers Rust, contribuant à l'amélioration de la sécurité logicielle
- Inspiration Technique : L'idée de guider les LLM par graphes de connaissances peut être généralisée à d'autres tâches de génération de code
- Migration de Systèmes Hérités : Adapté aux projets nécessitant la migration de bases de code C vers Rust
- Applications Critiques pour la Sécurité : Pour le développement de systèmes avec des exigences élevées de sécurité mémoire
- Outils d'Automatisation : Peut être intégré dans les IDE ou les pipelines CI/CD
- Éducation et Formation : Aide les développeurs à apprendre les concepts de sécurité mémoire de Rust
L'article cite 76 références connexes, couvrant plusieurs domaines tels que la traduction de code, l'analyse de programme et les grands modèles de langage, fournissant une base théorique solide pour la recherche.
Évaluation Globale : Ceci est un article de recherche en génie logiciel de haute qualité qui combine de manière innovante les graphes de connaissances et les grands modèles de langage pour résoudre les problèmes clés de la traduction C vers Rust. La conception de la méthode est raisonnable, la vérification expérimentale est complète et les résultats sont convaincants. Bien que présentant certaines limitations, il ouvre une nouvelle direction de recherche pour le domaine de la traduction de code, possédant une importance académique et une signification pratique importantes.