Sdílet prostřednictvím


Diagnostika strukturovaného SARIF

Kompilátor MSVC lze provést pro výstupní diagnostiku jako SARIF (Static Analysis Results Interchange Format). SARIF je strojově čitelný formát JSON.

Kompilátor MSVC vytváří diagnostiku SARIF dvěma způsoby:

  • /experimental:log Předejte přepínač na příkazovém řádku. Podrobnosti najdete v dokumentaci /experimental:log .
  • Spusťte cl.exe programově a nastavte SARIF_OUTPUT_PIPE proměnnou prostředí tak, aby načítala bloky SARIF přes kanál.

Načítání SARIF přes kanál

Nástroje, které využívají SARIF z kompilátoru MSVC, zatímco kompilace probíhá, používají kanál. Podrobnosti o vytváření kanálů Windows najdete v dokumentaci CreatePipe .

Pokud chcete načíst SARIF přes kanál, nastavte SARIF_OUTPUT_PIPE proměnnou prostředí na celočíselnou reprezentaci HANDLE UTF-16 kódování na konec zápisu kanálu a pak spusťte cl.exe. SARIF se odesílá podél potrubí následujícím způsobem:

  • Pokud je k dispozici nová diagnostika, zapíše se do tohoto kanálu.
  • Diagnostika se zapisuje do kanálu jednorázově, ne jako celý objekt SARIF.
  • Každá diagnostika je reprezentována zprávou typu Oznámení typu JSON-RPC 2.0.
  • Zpráva JSON-RPC má předponu Content-Length záhlaví s formulářem Content-Length: <N> následovaným dvěma novými spojnicemi, kde <N> je délka následující zprávy JSON-RPC v bajtech.
  • Zpráva JSON-RPC i hlavička jsou kódovány v kódování UTF-8.
  • Tento formát JSON-RPC-with-header je kompatibilní s vs-streamjsonrpc.
  • Název metody volání JSON-RPC je OnSarifResult.
  • Volání má jeden parametr, který je kódován podle názvu s názvem resultparametru .
  • Hodnota argumentu je jeden result objekt určený standardem SARIF verze 2.1.

Příklad

Tady je příklad výsledku SARIF JSON-RPC vytvořeného: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}}}]}}}

Data výsledků SARIF

Kompilátor vypíše SARIF, který může obsahovat další informace, které představují vnořenou strukturu některé diagnostiky. Diagnostika (reprezentovaná objektem result SARIF) může obsahovat "diagnostický strom" dalších informací v jeho relatedLocations poli. Tento strom je kódován pomocí tašky vlastností SARIF následujícím způsobem:

location Pole objektu properties může obsahovat nestingLevel vlastnost, jejíž hodnota je hloubka tohoto umístění v diagnostickém stromu. Pokud umístění není nestingLevel zadané, považuje se za hloubku 0 a toto umístění je podřízenou kořenovou diagnostikou reprezentovanou objektem, který result ho obsahuje. Jinak platí, že pokud je hodnota větší než hloubka umístění bezprostředně před tímto umístěním v relatedLocations poli, je toto umístění podřízeným umístěním. V opačném případě se jedná o stejné umístění, které odpovídá nejbližšímu předchozímu location místu relatedLocations v poli se stejnou hloubkou.

Příklad

Uvažujte následující kód:

struct dog {};
struct cat {};

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

struct lizard {};

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

Při kompilaci tohoto kódu kompilátor vytvoří následující result objekt (physicalLocation vlastnosti byly odebrány pro stručnost):

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

Logický diagnostický strom vytvořený ze zpráv v tomto result objektu je:

  • Pet: Žádná přetížená funkce nemohla převést všechny typy argumentů.
    • může být "void pet(kočka)"
      • 'void pet(cat)': Nemůže převést argument 1 z 'ještěrky' na 'cat'.
        • Není k dispozici žádný operátor převodu definovaný uživatelem, který by mohl provést tento převod, nebo nelze operátor volat.
    • nebo "void pet(pes)"
      • 'void pet(pes)': argument 1 nelze převést z 'ještěrky' na 'pes'
        • Není k dispozici žádný operátor převodu definovaný uživatelem, který by mohl provést tento převod, nebo nelze operátor volat.
    • při pokusu o shodu se seznamem argumentů (ještěrka)

Viz také

/experimental:log (Povolení strukturované diagnostiky SARIF)