Is there a way to detect inline function ODR violations?

我只是一个虾纸丫 提交于 2019-12-21 07:14:16

问题


So I have this code in 2 separate translation units:

// a.cpp
#include <stdio.h>
inline int func() { return 5; }
int proxy();
int main() { printf("%d", func() + proxy()); }

// b.cpp
inline int func() { return 6; }
int proxy() { return func(); }

When compiled normally the result is 10. When compiled with -O3 (inlining on) I get 11.

I have clearly done an ODR violation for func().

It showed up when I started merging sources of different dll's into fewer dll's.

I have tried:

  • GCC 5.1 -Wodr (which requires -flto)
  • gold linker with -detect-odr-violations
  • setting ASAN_OPTIONS=detect_odr_violation=1 before running an instrumented binary with the address sanitizer.

Asan can supposedly catch other ODR violations (global vars with different types or something like that...)

This is a really nasty C++ issue and I am amazed there isn't reliable tooling for detecting it.

Pherhaps I have misused one of the tools I tried? Or is there a different tool for this?

EDIT:

The problem remains unnoticed even when I make the 2 implementations of func() drastically different so they don't get compiled to the same amount of instructions.

This also affects class methods defined inside the class body - they are implicitly inline.

// a.cpp
struct A { int data; A() : data(5){} };

// b.cpp
struct A { int data; A() : data(6){} };

Legacy code with lots of copy/paste + minor modifications after that is a joy.


回答1:


The simplest way to detect such concerns is to copy all the functions into a single compilation unit (create one temporarily if needed). Any C++ compiler will then be able to detect and report duplicate definitions when compiling that file.




回答2:


The tools are imperfect.

I think Gold's check will only notice when the symbols have different types or different sizes, which isn't true here (both functions will compile to the same number of instructions, just using a different immediate value).

I'm not sure why -Wodr doesn't work here, but I think it only works for types, not functions, i.e. it will detect two conflicting definitions of a class type T but not your func().

I don't know anything about ASan's ODR checking.



来源:https://stackoverflow.com/questions/31722473/is-there-a-way-to-detect-inline-function-odr-violations

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!