Yapılandırılmış SARIF Tanılaması

MSVC derleyicisi, tanılamayı SARIF (Statik Çözümleme Sonuçları Değişim Biçimi) olarak çıktıya almak için yapılabilir. SARIF, makine tarafından okunabilir JSON tabanlı bir biçimdir.

MSVC derleyicisinin SARIF tanılaması üretmesinin iki yolu vardır:

  • /experimental:log Komut satırında anahtarı geçirin. Ayrıntılar için /experimental:log belgelere bakın.
  • Program aracılığıyla başlatın cl.exe ve ortam değişkenini SARIF_OUTPUT_PIPE bir boru üzerinden SARIF bloklarını alacak şekilde ayarlayın.

BIR boru üzerinden SARIF alma

Derleme devam ederken MSVC derleyicisinden SARIF kullanan araçlar bir kanal kullanır. Windows kanalları oluşturma hakkında ayrıntılı bilgi için CreatePipe belgelere bakın.

BIR kanal üzerinden SARIF almak için ortam değişkenini SARIF_OUTPUT_PIPE öğesinin UTF-16 kodlanmış tamsayı gösterimi HANDLE olarak kanalın yazma sonuna ayarlayın ve başlatın cl.exe. SARIF, boru boyunca aşağıdaki gibi gönderilir:

  • Yeni bir tanılama kullanılabilir olduğunda, bu kanala yazılır.
  • Tanılamalar, sarif nesnesinin tamamı yerine bir kerede bir kanala yazılır.
  • Her tanılama, Notification türünde bir JSON-RPC 2.0 iletisiyle temsil edilir.
  • JSON-RPC iletisine, form Content-Length: <N> ve ardından iki yeni çizgi eklenerek Content-Length bir üst bilgi eklenir; burada <N> bayt cinsinden aşağıdaki JSON-RPC iletisinin uzunluğudur.
  • JSON-RPC iletisi ve üst bilgisi UTF-8 ile kodlanmıştır.
  • Bu JSON-RPC-with-header biçimi vs-streamjsonrpc ile uyumludur.
  • JSON-RPC çağrısının yöntem adı şeklindedir OnSarifResult.
  • Çağrısı, parametre adıyla resultada göre kodlanmış tek bir parametreye sahiptir.
  • Bağımsız değişkeninin değeri, SARIF Sürüm 2.1 standardı tarafından belirtilen tek result bir nesnedir.

Örnek

Aşağıda tarafından üretilen bir JSON-RPC SARIF sonucu örneği verilmiştır 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}}}]}}}

SARIF sonuç verileri

Derleyici, bazı tanılamaların iç içe yapısını temsil eden ek bilgiler içerebilen SARIF çıkışını oluşturur. Tanılama (SARIF nesnesiyle result temsil edilir) alanında ek bilgi relatedLocations içeren bir "tanılama ağacı" içerebilir. Bu ağaç bir SARIF özellik paketi kullanılarak aşağıdaki gibi kodlanır:

Nesnenin location properties alanı, değeri tanılama ağacındaki bu konumun derinliği olan bir nestingLevel özellik içerebilir. Bir konum belirtilmemişse nestingLevel , derinlik olarak kabul edilir 0 ve bu konum, onu içeren nesne tarafından temsil edilen kök tanılamanın result alt öğesidir. Aksi takdirde, değer alandaki bu relatedLocations konumdan hemen önceki konumun derinliğinden büyükse, bu konum bu konumun alt öğesidir. Aksi takdirde, bu konum aynı derinliğe sahip alanda en location relatedLocations yakın olanın eşdüzeyindedir.

Örnek

Aşağıdaki kodu inceleyin:

struct dog {};
struct cat {};

void pet(dog);
void pet(cat);

struct lizard {};

int main() {
    pet(lizard{});
}

Bu kod derlendiğinde, derleyici aşağıdaki result nesneyi üretir (physicalLocation özellikler kısa süre için kaldırılmıştır):

{
    "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)'"
            }
        }
    ]
}

Bu result nesnedeki iletilerden oluşturulan mantıksal tanılama ağacı:

  • 'pet': aşırı yüklenmiş hiçbir işlev tüm bağımsız değişken türlerini dönüştüremedi
    • 'void pet(cat)' olabilir
      • 'void pet(cat)': bağımsız değişken 1'i 'kertenkele'den 'kedi'ye dönüştüremez
        • Bu dönüştürmeyi gerçekleştirebilecek kullanıcı tanımlı dönüştürme işleci yok veya işleç çağrılamıyor
    • veya 'void pet(köpek)'
      • 'void pet(köpek)': bağımsız değişken 1'i 'kertenkele'den 'köpeğe' dönüştüremez
        • Bu dönüştürmeyi gerçekleştirebilecek kullanıcı tanımlı dönüştürme işleci yok veya işleç çağrılamıyor
    • '(kertenkele)' bağımsız değişken listesiyle eşleşmeye çalışırken

Ayrıca bkz.

/experimental:log (Yapılandırılmış SARIF tanılamasını etkinleştirme)