Skip to content

[clang][ASTImporter] fix variable inline of CXX17 #87314

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 5, 2024

Conversation

jcsxky
Copy link
Contributor

@jcsxky jcsxky commented Apr 2, 2024

Fix crash in the testcase from #75114 (comment)
Forget to set inline of variable declaration would make isThisDeclarationADefinition get incorrect result and didn't get imported variable. This will lead to a new VarTemplateDecl being created and call setDescribedVarTemplate again which produces the crash.

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Apr 2, 2024
@llvmbot
Copy link
Member

llvmbot commented Apr 2, 2024

@llvm/pr-subscribers-clang

Author: Qizhi Hu (jcsxky)

Changes

Fix crash int the testcase from #75114 (comment)
Forget to set inline of variable declaration would make isThisDeclarationADefinition get incorrect result and didn't get imported variable. This will lead to a new VarTemplateDecl being created and call setDescribedVarTemplate again which produce the crash.


Full diff: https://github.com/llvm/llvm-project/pull/87314.diff

2 Files Affected:

  • (modified) clang/lib/AST/ASTImporter.cpp (+7-2)
  • (modified) clang/unittests/AST/ASTImporterTest.cpp (+28)
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 94a47a8f619018..cfdb2cb5c778e3 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -4579,7 +4579,12 @@ ExpectedDecl ASTNodeImporter::VisitVarDecl(VarDecl *D) {
     if (!RedeclOrErr)
       return RedeclOrErr.takeError();
   }
-
+  if (D->isInlineSpecified()) {
+    ToVar->setInlineSpecified();
+  }
+  if (D->isInline()) {
+    ToVar->setImplicitlyInline();
+  }
   return ToVar;
 }
 
@@ -6410,7 +6415,7 @@ ExpectedDecl ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
     }
     ToVarTD->setPreviousDecl(Recent);
   }
-
+  // Importer.MapImported(D, ToVarTD);
   return ToVarTD;
 }
 
diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp
index 35ab7e3b7fe314..d57736830f0223 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -5317,6 +5317,34 @@ TEST_P(ASTImporterOptionSpecificTestBase,
   EXPECT_FALSE(ToX);
 }
 
+TEST_P(ASTImporterOptionSpecificTestBase, VarTemplateDeclInlineWithCXX17) {
+  Decl *FromTU = getTuDecl(
+      R"(
+      struct S {
+        template <unsigned> static constexpr bool X = true;
+      };
+      )",
+      Lang_CXX17, "input1.cc");
+  Decl *FromTU2 = getTuDecl(
+      R"(
+      struct S {
+        template <unsigned> static constexpr bool X = true;
+        template <typename T> void get() { X<sizeof(T)>; }
+      };
+      template <typename T> T qvariant_cast(const S &v) { return v.get; }
+      )",
+      Lang_CXX17, "input2.cc");
+  auto *FromX = FirstDeclMatcher<VarTemplateDecl>().match(
+      FromTU, varTemplateDecl(hasName("X")));
+  auto *ToX = Import(FromX, Lang_CXX17);
+  EXPECT_TRUE(ToX);
+  auto *FromX2 = FirstDeclMatcher<VarTemplateDecl>().match(
+      FromTU2, varTemplateDecl(hasName("X")));
+  auto *ToX2 = Import(FromX2, Lang_CXX17);
+  EXPECT_TRUE(ToX2);
+  EXPECT_TRUE(ToX == ToX2);
+}
+
 TEST_P(ASTImporterOptionSpecificTestBase, VarTemplateParameterDeclContext) {
   constexpr auto Code =
       R"(

@jcsxky jcsxky force-pushed the fix-var-inline-cxx17 branch from 2f57934 to 1a10718 Compare April 2, 2024 05:28
@jcsxky jcsxky requested review from balazske and NagyDonat April 2, 2024 05:40
Copy link
Contributor

@NagyDonat NagyDonat left a comment

Choose a reason for hiding this comment

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

Looks good, but I'm not familiar enough with these details of the standard to provide a definite review.

template <unsigned> static constexpr bool X = true;
template <typename T> void get() { X<sizeof(T)>; }
};
template <typename T> T qvariant_cast(const S &v) { return v.get; }
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
template <typename T> T qvariant_cast(const S &v) { return v.get; }
template <typename U> U qvariant_cast(const S &v) { return v.get; }

At first I thought that the template argument typename T of this definition is intended to correspond to the same type as the typename T in the definition of get, while it seems to be a different type, and if this is true, then it'd be better to use a different name. (By the way, is it intentional that you return v.get without calling it?)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have no idea what these code wants to do and just pick up from the comment. It can reproduce the crash and demonstrate this fix works(I think). The type name has been updated.

@NagyDonat NagyDonat requested review from steakhal and whisperity April 2, 2024 12:04
Copy link
Contributor

@steakhal steakhal left a comment

Choose a reason for hiding this comment

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

I only had generic nits, as I'm not really in the domain. Consider my review as such.

@jcsxky jcsxky force-pushed the fix-var-inline-cxx17 branch from 1a10718 to 6ba08ef Compare April 3, 2024 08:41
}
if (D->isInline()) {
ToVar->setImplicitlyInline();
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

I would like to move these lines to line 4513 (after ToVar->setLexicalDeclContext(LexicalDC);), and braces are not needed:

  if (D->isInlineSpecified())
    ToVar->setInlineSpecified();
  if (D->isInline())
    ToVar->setImplicitlyInline();

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Seems to be more reasonable. Code has been updated. Thanks!

@jcsxky jcsxky force-pushed the fix-var-inline-cxx17 branch from 6ba08ef to b77a782 Compare April 4, 2024 02:58
Copy link
Collaborator

@balazske balazske left a comment

Choose a reason for hiding this comment

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

For me the test and fix looks good, test crashes without the fix (llvm-project/clang/lib/AST/ASTContext.cpp:1474: void clang::ASTContext::setTemplateOrSpecializationInfo(clang::VarDecl*, clang::ASTContext::TemplateOrSpecializationInfo): Assertion `!TemplateOrInstantiation[Inst] && "Already noted what the variable was instantiated from"' failed.).

(One very small thing is that after the second import in the test EXPECT_TRUE would be better.)

@jcsxky jcsxky force-pushed the fix-var-inline-cxx17 branch from b77a782 to 888f6fc Compare April 4, 2024 09:22
@jcsxky
Copy link
Contributor Author

jcsxky commented Apr 4, 2024

For me the test and fix looks good, test crashes without the fix (llvm-project/clang/lib/AST/ASTContext.cpp:1474: void clang::ASTContext::setTemplateOrSpecializationInfo(clang::VarDecl*, clang::ASTContext::TemplateOrSpecializationInfo): Assertion `!TemplateOrInstantiation[Inst] && "Already noted what the variable was instantiated from"' failed.).

(One very small thing is that after the second import in the test EXPECT_TRUE would be better.)

Fixed!

@jcsxky jcsxky merged commit ab80d00 into llvm:main Apr 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants