Diagnostics SARIF structurés
Le compilateur MSVC peut être effectué pour générer des diagnostics en tant que SARIF (format d’échange des résultats d’analyse statique). SARIF est un format JSON lisible par l’ordinateur.
Il existe deux façons de faire en sorte que le compilateur MSVC produise des diagnostics SARIF :
- Passez le
/experimental:log
commutateur sur la ligne de commande. Pour plus d’informations, consultez la documentation/experimental:log
. - Lancez
cl.exe
programmatiquement et définissez laSARIF_OUTPUT_PIPE
variable d’environnement pour récupérer des blocs SARIF via un canal.
Récupération de SARIF via un canal
Les outils qui consomment SARIF à partir du compilateur MSVC pendant qu’une compilation est en cours utilisent un canal. Consultez la documentation pour CreatePipe
plus d’informations sur la création de canaux Windows.
Pour récupérer SARIF via un canal, définissez la SARIF_OUTPUT_PIPE
variable d’environnement sur la représentation entière encodée UTF-16 du HANDLE
canal à la fin d’écriture du canal, puis lancez cl.exe
. SARIF est envoyé le long du canal comme suit :
- Lorsqu’un nouveau diagnostic est disponible, il est écrit dans ce canal.
- Les diagnostics sont écrits dans le canal un-à-temps plutôt qu’en tant qu’objet SARIF entier.
- Chaque diagnostic est représenté par un message JSON-RPC 2.0 de type Notification.
- Le message JSON-RPC est précédé d’un
Content-Length
en-tête avec le formulaireContent-Length: <N>
suivi de deux nouvelles lignes, où<N>
est la longueur du message JSON-RPC suivant en octets. - Le message JSON-RPC et l’en-tête sont tous deux encodés dans UTF-8.
- Ce format JSON-RPC-with-header est compatible avec vs-streamjsonrpc.
- Le nom de la méthode pour l’appel JSON-RPC est
OnSarifResult
. - L’appel a un paramètre unique qui est encodé par nom avec le nom
result
du paramètre . - La valeur de l’argument est un objet unique
result
tel que spécifié par la norme SARIF Version 2.1.
Exemple
Voici un exemple de résultat SARIF JSON-RPC produit par cl.exe
:
Content-Length: 334
{"jsonrpc":"2.0","method":"OnSarifResult","params":{"result":{"ruleId":"C1034","level":"fatal","message":{"text":"iostream: no include path set"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"file:///C:/Users/sybrand/source/repos/cppcon-diag/cppcon-diag/cppcon-diag.cpp"},"region":{"startLine":1,"startColumn":10}}}]}}}{"jsonrpc":"2.0","method":"OnSarifResult","params":{"result":{"ruleId":"C1034","level":"fatal","message":{"text":"iostream: no include path set"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"file:///C:/Users/sybrand/source/repos/cppcon-diag/cppcon-diag/cppcon-diag.cpp"},"region":{"startLine":1,"startColumn":10}}}]}}}
Données de résultat SARIF
Le compilateur génère SARIF qui peut inclure des informations supplémentaires pour représenter la structure imbriquée de certains diagnostics. Un diagnostic (représenté par un result
objet SARIF) peut contenir une « arborescence de diagnostic » d’informations supplémentaires dans son relatedLocations
champ. Cette arborescence est encodée à l’aide d’un conteneur de propriétés SARIF comme suit :
Le champ d’un location
properties
objet peut contenir une nestingLevel
propriété dont la valeur correspond à la profondeur de cet emplacement dans l’arborescence de diagnostic. Si un emplacement n’a pas d’emplacement nestingLevel
spécifié, la profondeur est considérée 0
comme étant un enfant du diagnostic racine représenté par l’objet contenant celui-ci result
. Sinon, si la valeur est supérieure à la profondeur de l’emplacement qui précède immédiatement cet emplacement dans le relatedLocations
champ, cet emplacement est un enfant de cet emplacement. Sinon, cet emplacement est un frère du plus proche précédent location
dans le relatedLocations
champ avec la même profondeur.
Exemple
Prenez le code suivant :
struct dog {};
struct cat {};
void pet(dog);
void pet(cat);
struct lizard {};
int main() {
pet(lizard{});
}
Lorsque ce code est compilé, le compilateur produit l’objet suivant result
(physicalLocation
les propriétés ont été supprimées pour la concision) :
{
"ruleId": "C2665",
"level": "error",
"message": {
"text": "'pet': no overloaded function could convert all the argument types"
},
"relatedLocations": [
{
"id": 0,
"message": {
"text": "could be 'void pet(cat)'"
}
},
{
"id": 1,
"message": {
"text": "'void pet(cat)': cannot convert argument 1 from 'lizard' to 'cat'"
},
"properties": {
"nestingLevel": 1
}
},
{
"id": 2,
"message": {
"text": "No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called"
},
"properties": {
"nestingLevel": 2
}
},
{
"id": 3,
"message": {
"text": "or 'void pet(dog)'"
}
},
{
"id": 4,
"message": {
"text": "'void pet(dog)': cannot convert argument 1 from 'lizard' to 'dog'"
},
"properties": {
"nestingLevel": 1
}
},
{
"id": 5,
"message": {
"text": "No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called"
},
"properties": {
"nestingLevel": 2
}
},
{
"id": 6,
"message": {
"text": "while trying to match the argument list '(lizard)'"
}
}
]
}
L’arborescence de diagnostics logiques produite à partir des messages de cet result
objet est la suivante :
- 'pet' : aucune fonction surchargée ne peut convertir tous les types d’arguments
- pourrait être 'void pet(cat)'
- 'void pet(cat)' : impossible de convertir l’argument 1 de 'lézard' en 'cat'
- Aucun opérateur de conversion défini par l’utilisateur disponible qui peut effectuer cette conversion, ou l’opérateur ne peut pas être appelé
- 'void pet(cat)' : impossible de convertir l’argument 1 de 'lézard' en 'cat'
- ou 'void pet(dog)'
- 'void pet(dog)' : impossible de convertir l’argument 1 de 'lézard' en 'dog'
- Aucun opérateur de conversion défini par l’utilisateur disponible qui peut effectuer cette conversion, ou l’opérateur ne peut pas être appelé
- 'void pet(dog)' : impossible de convertir l’argument 1 de 'lézard' en 'dog'
- lors de la tentative de correspondance avec la liste d’arguments '(lézard)'
- pourrait être 'void pet(cat)'
Voir aussi
/experimental:log
(Activer les diagnostics SARIF structurés)