The AST structural equivalence check did not differentiate between
a struct and a struct with same name in different namespace. When
type of a member is checked it is possible to encounter such a case
and wrongly decide that the types are similar. This problem is fixed
by check for the namespaces of a record declaration.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
I very much like the code.
L1364 is uncovered according to my coverage results.
clang/lib/AST/ASTStructuralEquivalence.cpp | ||
---|---|---|
1360–1364 | Shouldn't you also check the name as well? | |
1379 | So, the previous DC1->isTranslationUnit() guards the DC1->getParent() to never be NULL; same for DC2. | |
clang/unittests/AST/StructuralEquivalenceTest.cpp | ||
982–988 | The outer-most namespace could also be inline. | |
1004–1009 | extern "C" might be nested within other namespaces. | |
1025–1032 | Please, also test if the name of the structs is mismatched. |
How does it handle this case:
struct A {int x;}; struct A f(void) { struct A{} a; return a;
and this case:
struct b{}; struct a {int x;} // visible outside of f f(struct b {int x; } b1) { // not visibile out of f return (struct a){.x = 1}; }
In the last case the the RecordDecl's a and b can be matched (not internal statements in a function) and this is similar to the existing test cases. The struct a and struct b already fails to match because different name.
clang/lib/AST/ASTStructuralEquivalence.cpp | ||
---|---|---|
1360–1364 | Here DC1 or DC2 is already a function or translation unit, the name of it is not relevant. | |
1379 | Change to !DC1->getParent() (from DC1->isTranslationUnit())? (The line can be moved to here to increase readability, so the break statement is at end of the loop.) |
Looks like this breaks tests on windows: http://45.33.8.238/win/49558/step_7.txt
Please take a look and revert for now if it takes a while to fix.
Windows test failures occurred because wrong AST matchers in the tests. Tests will be updated to use named match.
clang/unittests/AST/StructuralEquivalenceTest.cpp | ||
---|---|---|
1037 | There is a test ctu-main.c that fails if this is false. In that code a similar construct as here (structInProto) is imported and the import fails because unsupported construct. If these are structurally not equivalent then the failure is a ODR like error (the Param inside the function prototype is different than the Param outside of it). I do not know which is the correct behavior, I think the intent in that test is that import of this construct should work (if it would be supported by ASTImporter) at least in the C case. |
clang/unittests/AST/StructuralEquivalenceTest.cpp | ||
---|---|---|
1037 | They are compatible types, so if that is the criteria then that looks reasonable. |
Shouldn't you also check the name as well?