Skip to content
This repository has been archived by the owner on Mar 30, 2021. It is now read-only.

Fix VarDecl Import #482

Merged
merged 1 commit into from
Aug 31, 2018
Merged

Fix VarDecl Import #482

merged 1 commit into from
Aug 31, 2018

Conversation

martong
Copy link

@martong martong commented Aug 23, 2018

Fixes #477

@martong martong requested a review from balazske August 23, 2018 14:08
auto *Recent = const_cast<VarDecl *>(MergeWithVar->getMostRecentDecl());
updateAttrAndFlags(D, MergeWithVar);
ToVar->setPreviousDecl(Recent);
}

// Merge the initializer.
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not a "merge" rather an import.

ASSERT_TRUE(ToD0);
ASSERT_TRUE(ToD1);
EXPECT_NE(ToD0, ToD1);
EXPECT_EQ(ToD1->getPreviousDecl() ,ToD0);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better variable names can be used: FromDWithInit, FromDWithDef and similar.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, good point.

@@ -1421,13 +1423,22 @@ bool ASTNodeImporter::ImportDefinition(VarDecl *From, VarDecl *To,
if (To->getAnyInitializer())
return false;

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really this function does not ensure the definition, only the initializer? (If "definition" is not the same as initializer.)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the definition may be independent from the initializer.
Perhaps a better name would be just ImportInitializer.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed to ImportInitializer.

LexicalDC->addDeclInternal(ToVar);
if (MergeWithVar) {
auto *Recent = const_cast<VarDecl *>(MergeWithVar->getMostRecentDecl());
updateAttrAndFlags(D, MergeWithVar);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The updateAttrAndFlags is used to update data (from D) in the found Decl. I think this should be called at the MapImported cases (line 3223 and 3229).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will not work that way. Just tried and moved updateAttrAndFlags before the MapImported calls, and the unit test which test the used flag fails.
If we think about it this is logical, since we should update the used flag when we do create a new VarDecl, and that is happening once we reach to this line.
In those lines you mentioned (line 3223 and 3229) we do not create any new declaration, thus there is nothing to update.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably include it in both places? At create the used flag should be copied anyway. If an imported Decl is mapped to an existing, the imported may have the used flag set but the existing not, in this case the update is needed. Probably this case does not occur any more in the unit test because way of importing has changed (but the unit test originally was made to test the case when there is an existing VarDecl and an imported VarDecl is mapped to that and the used flag should be updated).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, makes sense, I am going to check that and also the test.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, I've written two new test cases which exercises those cases. And indeed it is needed to add updateAttrAndFlags there.
Then I realized that we have to do this always after we found an existing decl or even if we created a new one.
This seems like a general rule, so I added the call of updateAttrAndFlags into Import::(Decl*).

@@ -3178,8 +3199,8 @@ Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {

// Try to find a variable in our own ("to") context with the same name and
// in the same context as the variable we're importing.
VarDecl *MergeWithVar = nullptr;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be renamed to ExistingVar or similar.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed to FoundByLookup, since that is how we call it in VisitFunctionDecl too.

@martong
Copy link
Author

martong commented Aug 24, 2018

Added a new commit, so you can easily track what changed, before merge I'll squash.

VarDecl *FoundDef = FoundVar->getDefinition();
if (D->isThisDeclarationADefinition() && FoundDef) {
return Importer.MapImported(D, FoundDef);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there no problem with update of initializer? If the D is definition and has initializer, and the found has no initializer, it is not updated. (But theoretically the variable can have only one definition, so the definition of D should be the same as the found one, with initializer.)

Copy link
Author

@martong martong Aug 24, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, good point, but I don't think that could be a problem exactly because what you have written in the parentheses.
I would not merge the initializer. Intstead, we could diagnose an ODR error here if we see that the two definitions have different initializers, I added a FIXME for that.

@martong
Copy link
Author

martong commented Aug 30, 2018

run tests

1 similar comment
@martong
Copy link
Author

martong commented Aug 30, 2018

run tests

@@ -3211,11 +3246,11 @@ Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
return nullptr;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure if this array type import is needed with the new code. The FoundVar is updated (setType) but later we create a new VarDecl instead (and if a new VarDecl is created it should contain all new information, the existing should not be changed, no "merge" is done).
In line 3239 the getToContext is used with D that is in the FromContext, is this correct?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I agree, this comes from the "From" context.
Also, I created a new issue to revisit this code: #485

Decl *FromTU = getTuDecl(
"int x = 1; int f() { return x; }", Lang_CXX, "input1.cc");
auto *FromD =
FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is good if we are sure that there is not any other hidden generated function in FromTU. Better is to match always with name.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, thank you.

@martong
Copy link
Author

martong commented Aug 31, 2018

Update: squashed the commits into one.

@martong martong merged commit 4cf7f40 into Ericsson:ctu-clang6 Aug 31, 2018
@martong
Copy link
Author

martong commented Sep 3, 2018

@martong martong deleted the fix_VarDecl branch September 3, 2018 14:57
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants