one definition rule - что это такое, и как с этим жить
TRANSCRIPT
ODR-CHECK
4
Compilation/linking
compile
compile
compile .cpp .obj .exe
.cpp .obj
.cpp .obj ar
.lib
link
И ЦИЯ
5
enumeration
enum Foo {
e1,
e2,
eCount
};
const char* FooToString(Foo x);
int main() {
std::cout << FooToString(e2) << std::endl;
return 0;
}
enum Foo {
e1,
eCount
};
const char xxx [] = «can you see me?!!»
const char* msg [eCount] = {
«e1»
};
const char* canYouSeeMe = xxx;
const char* FooToString(Foo x) {return msg[x];}
И ЦИЯ
6
struct A : private boost::noncopyable {
A() : x(«0») {}
const std::string x;
int y;
};
void Modify(A& a);
int main() {
A a;
Modify(a);
std::cout << a.x << std::endl;
return 0;
}
struct A : private boost::noncopyable {
A();
int x;
const std::string y;
};
void Modify(A& a) {
a.x += 1;
}
И ЦИЯ
7
pragma pack
#pragma pack(push, 1)
struct C {
char c;
uint32_t x;
};
#pragma pack(pop)
void Modify(C* c, size_t pos);
int main() {
std::string x = «0»;
C c[8] = {0};
Modify(c, 6);
std::cout << x << std::endl;
return 0;
}
struct C {
char c;
uint32_t x;
};
void Modify(C* c, size_t pos) {
c[pos].x += 1;
}
И ЦИЯ
8
К
• , ,
• + Х assert, core dump, ,
• - « »
•Code review • - ,
•gcc –Wodr, gold –detect-odr-violations • +
• - , false positive
•Amalgamation (sqlite) • +
• -
• -
И Е Ы
14
#pragma detect_mismatch
#pragma detect_mismatch(«my_name», «my_value1») /// cpp1.cpp
#pragma detect_mismatch(«my_name», «my_value2») /// cpp2.cpp
cpp2.obj : error LNK2038: mismatch detected for 'my_name': value ‘my_value ' doesn't match value ‘my_value ' in cpp1.obj
dumpbin /ALL cpp1.obj
Linker Directives
-----------------
/FAILIFMISMATCH:"my_name=my_value1"
/DEFAULTLIB:"MSVCRTD"
/DEFAULTLIB:"OLDNAMES"
ODR-CHECK
17
Compilation/linking
compile
compile
compile .cpp .obj .exe
.cpp .obj
.cpp .obj ar
.lib
link
ODR-CHECK
18
Checking for ODR violations
emit-ast
emit-ast
emit-ast .cpp .ast .ast
.cpp .ast
.cpp .ast merge-ast
.ast
merge-ast
ODR-CHECK
19
Compilation
http://clang.llvm.org/docs/IntroductionToTheClangAST.html
http://clang.llvm.org/docs/InternalsManual.html
.cpp token
stream ASTContext
Preprocessor/Lexer Sema LLVM IR
ASTFrontendAction (CodeGenAction)
ODR-CHECK
20
Storing AST to file
.cpp token
stream ASTContext
Preprocessor/Lexer Sema .ast
ASTFrontendAction (GeneratePCHAction)
ODR-CHECK
23
RecursiveASTVisitor
namespace m {
struct X {
int a;
};
}
clang ../main.cpp -Xclang -ast-dump -fsyntax-only
http://clang.llvm.org/docs/RAVFrontendAction.html
ODR-CHECK
24
ASTImporter
TranslationUnitDecl (From) TranslationUnitDecl (To)
|-Node |-Node
`-Node `-Node
`-Node `-Node
ASTNodeImporter
ODR-CHECK
25
ASTNodeImporter
namespace m { /// 4. NamespaceDecl(NamedDecl, DeclContext)
namespace n { /// 3. NamespaceDecl (NamedDecl, DeclContext)
struct X { /// 2. CXXRecordDecl (..., TypeDecl, DeclContext)
struct Y { /// 1. CXXRecordDecl (..., TypeDecl, DeclContext)
int a; /// <- IMPORT
};
};
}
}
ODR-CHECK
26
StructuralEquivalenceContext
namespace m {
struct X {
int a;
long b;
};
struct Y {
X x;
int b;
};
struct Z {
int b;
};
}
namespace m {
struct X {
int a;
long b;
};
struct Y {
X x;
long b;
};
struct Z {
int a;
};
}
ODR-CHECK
27
И cmake
clang++ -DMY_SUPER_DEFINE –Wall –I/my/include –emit-ast source_file.cpp –o source_file.ast
clang++ -cc1 –emit-pch –o lib_file.ast -ast-merge source_file1.ast –ast-merge source_file2.ast
cmake ../src -DCMAKE_TOOLCHAIN_FILE=d:/tools/ClangOdrCheckToolchain.cmake –D...
make
ODR-CHECK
28
Sample output
namespace m {
struct X {
int x;
#if defined (M1)
int z;
#endif /* M1 */
};
}
ODR-CHECK
29
Sample output
In file included from d:\pixel\projects\odr-check\odr-check-test\src\data\src\m1.cpp:3:
d:\pixel\projects\odr-check\odr-check-test\src\data\src/h1.h:11:8: warning: type 'struct m::X' has incompatible definitions in different translation units
struct X
^
d:\pixel\projects\odr-check\odr-check-test\src\data\src/h1.h:16:7: note: field 'z' has type 'int' here
int z;
^
d:\pixel\projects\odr-check\odr-check-test\src\data\src/h1.h:11:8: note: no corresponding field here
struct X
^
ODR-CHECK
30
ИТ
• PoC: https://github.com/prograholic/clang/tree/odr-check
• Production Ready (milestone: check tool on some Boost libraries) • Memory consumption (huge ASTs)
• Minimize import amount (static, unnamed namespaces, templates)
•Merge changes to clang/master
LET'S TALK? mail: [email protected]
twitter: @prograholic
https://github.com/prograholic/odr-check
https://github.com/prograholic/clang/tree/odr-check