Gibt es eine Möglichkeit, Inline-Funktion ODR-Verletzungen zu erkennen?

8

Also habe ich diesen Code in 2 separaten Übersetzungseinheiten:

%Vor%

Bei normalem Kompilieren ist das Ergebnis 10 . Bei der Kompilierung mit -O3 (Inlining on) bekomme ich 11 .

Ich habe eindeutig eine ODR-Verletzung für func() gemacht.

Es zeigte sich, als ich begann, Quellen verschiedener DLLs in weniger DLLs zusammenzuführen.

Ich habe es versucht:

  • GCC 5.1 -Wodr (benötigt -flto )
  • Goldlinker mit -detect-odr-violations
  • Setzen von ASAN_OPTIONS=detect_odr_violation=1 vor dem Ausführen einer instrumentierten Binärdatei mit dem Adressdesinfizierer.

Asan kann angeblich andere ODR-Verstöße (globale Vars mit verschiedenen Typen oder so ähnlichem ...) abfangen.

Dies ist ein wirklich unangenehmes C ++ - Problem und ich bin erstaunt es gibt keine zuverlässigen Werkzeuge, um es zu erkennen.

Vielleicht habe ich eines der Tools, die ich ausprobiert habe, missbraucht? Oder gibt es dafür ein anderes Werkzeug?

BEARBEITEN :

Das Problem bleibt unbemerkt, auch wenn ich die 2 Implementierungen von func() drastisch anders mache, damit sie nicht auf die gleiche Menge an Anweisungen kompiliert werden.

Dies betrifft auch Klassenmethoden, die im Klassenkörper definiert sind - sie sind implizit inline.

%Vor%

Legacy-Code mit vielen Kopieren / Einfügen + kleine Änderungen danach ist eine Freude.

    
onqtam 30.07.2015, 11:24
quelle

2 Antworten

3

Der einfachste Weg, solche Bedenken zu erkennen, besteht darin, alle Funktionen in eine einzige Kompilierungseinheit zu kopieren (erstellen Sie sie bei Bedarf vorübergehend). Jeder C ++ - Compiler kann dann beim Kompilieren dieser Datei doppelte Definitionen erkennen und melden.

    
Peter 30.07.2015, 11:54
quelle
5

Die Werkzeuge sind nicht perfekt.

Ich denke, die Prüfung von Gold wird nur bemerken, wenn die Symbole unterschiedliche Typen oder unterschiedliche Größen haben, was hier nicht der Fall ist (beide Funktionen werden auf die gleiche Anzahl von Anweisungen kompiliert, nur mit einem anderen Direktwert).

Ich bin mir nicht sicher, warum -Wodr hier nicht funktioniert, aber ich denke, es funktioniert nur für Typen, nicht für Funktionen, dh es werden zwei in Konflikt stehende Definitionen eines Klassentyps gefunden T , aber nicht func() .

Ich weiß nichts über ASans ODR-Überprüfung.

    
Jonathan Wakely 30.07.2015 11:46
quelle