Analyzability
Diese optionale Erweiterung der C-Sprache schränkt die möglichen Ergebnisse der Ausführung einiger Formen von undefiniertem Verhalten ein, was die Effektivität der statischen Analyse solcher Programme verbessert. Analyzability ist nur dann garantiert aktiviert, wenn die vordefinierte Makrokonstante __STDC_ANALYZABLE__(C11) vom Compiler definiert wird.
Wenn der Compiler Analyzability unterstützt, werden alle Sprach- oder Bibliothekskonstrukte, deren Verhalten undefiniert ist, weiter in kritisches und begrenztes undefiniertes Verhalten klassifiziert, und das Verhalten aller begrenzten UB-Fälle ist wie unten angegeben eingeschränkt.
Inhalt |
[bearbeiten] Kritisches undefiniertes Verhalten
Kritisches UB ist undefiniertes Verhalten, das möglicherweise einen Speicherwrite oder eine volatile Speicherlesung außerhalb der Grenzen eines beliebigen Objekts durchführt. Ein Programm mit kritischem undefiniertem Verhalten kann anfällig für Sicherheitslücken sein.
Nur die folgenden undefinierten Verhaltensweisen sind kritisch
- Zugriff auf ein Objekt außerhalb seiner Lebensdauer (z.B. über einen hängenden Zeiger)
- Schreiben in ein Objekt, dessen Deklarationen nicht kompatibel sind
- Funktionsaufruf über einen Funktionszeiger, dessen Typ nicht kompatibel mit dem Typ der Funktion ist, auf die er zeigt
- lvalue-Ausdruck wird ausgewertet, bezeichnet aber kein Objekt
- Versuch der Modifikation eines String-Literals
- Dereferenzierung eines ungültigen (Null-, unbestimmten usw.) oder hinter dem Ende liegenden Zeigers
- Modifikation eines const-Objekts über einen nicht-const-Zeiger
- Aufruf einer Standardbibliotheksfunktion oder eines Makros mit ungültigem Argument
- Aufruf einer variadischen Standardbibliotheksfunktion mit unerwartetem Argumenttyp (z.B. Aufruf von printf mit einem Argument des Typs, das nicht mit seinem Konversionsspezifizierer übereinstimmt)
- longjmp, wenn kein setjmp im aufrufenden Bereich vorhanden ist, über Threads hinweg oder aus dem Bereich eines VM-Typs heraus.
- Jede Verwendung eines Zeigers, der von free oder realloc freigegeben wurde
- Jede String- oder Wide-String-Bibliotheksfunktion greift auf ein Array außerhalb der Grenzen zu
[bearbeiten] Begrenztes undefiniertes Verhalten
Begrenztes UB ist undefiniertes Verhalten, das keinen illegalen Speicherwrite durchführen kann, obwohl es abstürzen und unbestimmte Werte erzeugen oder speichern kann.
- Alle nicht als kritisch aufgeführten undefinierten Verhaltensweisen sind begrenzt, einschließlich
- multithreaded Datenrennen
- Verwendung von unbestimmten Werten mit automatischem Speicherplatz
- Strict-Aliasing-Verstöße
- Fehlgerichteter Objektzugriff
- Vorzeichenbehafteter Ganzzahl-Überlauf
- Nicht sequenzierte Nebeneffekte modifizieren dieselbe Skalare oder modifizieren und lesen dieselbe Skalare
- Gleitkomma-zu-Ganzzahl- oder Zeiger-zu-Ganzzahl-Konvertierungsüberläufe
- Bitweises Verschieben um eine negative oder zu große Bitanzahl
- Ganzzahlige Division durch Null
- Verwendung eines void-Ausdrucks
- direkte Zuweisung oder memcpy von inexakt überlappenden Objekten
- restrict-Verstöße
- usw.. ALLE undefinierten Verhaltensweisen, die nicht auf der kritischen Liste stehen.
[bearbeiten] Anmerkungen
Begrenztes undefiniertes Verhalten deaktiviert bestimmte Optimierungen: Die Kompilierung mit aktivierter Analyzability erhält die Kausalität des Quellcodes, die andernfalls durch undefiniertes Verhalten verletzt werden kann.
Die Analyzability-Erweiterung erlaubt als Form von implementierungsdefinierten Verhalten, dass der Laufzeit-Constraint-Handler aufgerufen wird, wenn ein Trap auftritt.
[bearbeiten] Referenzen
- C11-Standard (ISO/IEC 9899:2011)
- 6.10.8.3/1 Conditional feature macros (S. 177)
- Annex L Analyzability (S. 652-653)