r323935 - PR36181: Teach CodeGen to properly ignore requests to emit dependent entities.

Shoaib Meenai via cfe-commits cfe-commits at lists.llvm.org
Wed Jan 31 16:42:04 PST 2018


Is this viable for backporting to 6.0? It fixes a bug that's been hit in various forms by quite a few people: https://bugs.llvm.org/show_bug.cgi?id=36181, https://bugs.llvm.org/show_bug.cgi?id=35473, and https://bugs.llvm.org/show_bug.cgi?id=35939.

From: cfe-commits <cfe-commits-bounces at lists.llvm.org> on behalf of Richard Smith via cfe-commits <cfe-commits at lists.llvm.org>
Reply-To: Richard Smith <richard-llvm at metafoo.co.uk>
Date: Wednesday, January 31, 2018 at 4:32 PM
To: "cfe-commits at lists.llvm.org" <cfe-commits at lists.llvm.org>
Subject: r323935 - PR36181: Teach CodeGen to properly ignore requests to emit dependent entities.

Author: rsmith
Date: Wed Jan 31 16:28:36 2018
New Revision: 323935

URL: https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject-3Frev-3D323935-26view-3Drev&d=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=o3kDXzdBUE3ljQXKeTWOMw&m=lpLH9VUhmNJcmdOGGUS4JH7kl-0dHB_UbZJavDZFar8&s=gXiqdj7RcmFitXxzq_T6trCkulPJ1hKO9JTh4N1W1Ds&e=
Log:
PR36181: Teach CodeGen to properly ignore requests to emit dependent entities.

Previously, friend function definitions within class templates slipped through
the gaps and caused the MS mangler to assert.

Added:
    cfe/trunk/test/CodeGenCXX/microsoft-abi-emit-dependent.cpp
Modified:
    cfe/trunk/include/clang/AST/DeclBase.h
    cfe/trunk/lib/AST/DeclBase.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp

Modified: cfe/trunk/include/clang/AST/DeclBase.h
URL: https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_include_clang_AST_DeclBase.h-3Frev-3D323935-26r1-3D323934-26r2-3D323935-26view-3Ddiff&d=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=o3kDXzdBUE3ljQXKeTWOMw&m=lpLH9VUhmNJcmdOGGUS4JH7kl-0dHB_UbZJavDZFar8&s=IdB02f1U8VHa1i4Dvuj1BkcyoWf9sYvY3xE1L8bzfM0&e=
==============================================================================
--- cfe/trunk/include/clang/AST/DeclBase.h (original)
+++ cfe/trunk/include/clang/AST/DeclBase.h Wed Jan 31 16:28:36 2018
@@ -836,6 +836,10 @@ public:
   void setLexicalDeclContext(DeclContext *DC);
+  /// Determine whether this declaration is a templated entity (whether it is
+  // within the scope of a template parameter).
+  bool isTemplated() const;
+
   /// isDefinedOutsideFunctionOrMethod - This predicate returns true if this
   /// scoped decl is defined outside the current function or method.  This is
   /// roughly global variables and functions, but also handles enums (which

Modified: cfe/trunk/lib/AST/DeclBase.cpp
URL: https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_AST_DeclBase.cpp-3Frev-3D323935-26r1-3D323934-26r2-3D323935-26view-3Ddiff&d=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=o3kDXzdBUE3ljQXKeTWOMw&m=lpLH9VUhmNJcmdOGGUS4JH7kl-0dHB_UbZJavDZFar8&s=3WgES9JYNm2mJaPKUnRnaFndAGpGnj0AJ9kR5ARgxao&e=
==============================================================================
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Wed Jan 31 16:28:36 2018
@@ -236,10 +236,23 @@ TemplateDecl *Decl::getDescribedTemplate
     return RD->getDescribedClassTemplate();
   else if (auto *VD = dyn_cast<VarDecl>(this))
     return VD->getDescribedVarTemplate();
+  else if (auto *AD = dyn_cast<TypeAliasDecl>(this))
+    return AD->getDescribedAliasTemplate();
   return nullptr;
}
+bool Decl::isTemplated() const {
+  // A declaration is dependent if it is a template or a template pattern, or
+  // is within (lexcially for a friend, semantically otherwise) a dependent
+  // context.
+  // FIXME: Should local extern declarations be treated like friends?
+  if (auto *AsDC = dyn_cast<DeclContext>(this))
+    return AsDC->isDependentContext();
+  auto *DC = getFriendObjectKind() ? getLexicalDeclContext() : getDeclContext();
+  return DC->isDependentContext() || isTemplateDecl() || getDescribedTemplate();
+}
+
const DeclContext *Decl::getParentFunctionOrMethod() const {
   for (const DeclContext *DC = getDeclContext();
        DC && !DC->isTranslationUnit() && !DC->isNamespace();

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_CodeGen_CodeGenModule.cpp-3Frev-3D323935-26r1-3D323934-26r2-3D323935-26view-3Ddiff&d=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=o3kDXzdBUE3ljQXKeTWOMw&m=lpLH9VUhmNJcmdOGGUS4JH7kl-0dHB_UbZJavDZFar8&s=h8Z9xGHMAkSO6Ph5TtmYjbR5XdFVkIgGMgUXGk2oMqc&e=
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Wed Jan 31 16:28:36 2018
@@ -4190,18 +4190,13 @@ void CodeGenModule::EmitDeclContext(cons
/// EmitTopLevelDecl - Emit code for a single top level declaration.
void CodeGenModule::EmitTopLevelDecl(Decl *D) {
   // Ignore dependent declarations.
-  if (D->getDeclContext() && D->getDeclContext()->isDependentContext())
+  if (D->isTemplated())
     return;
   switch (D->getKind()) {
   case Decl::CXXConversion:
   case Decl::CXXMethod:
   case Decl::Function:
-    // Skip function templates
-    if (cast<FunctionDecl>(D)->getDescribedFunctionTemplate() ||
-        cast<FunctionDecl>(D)->isLateTemplateParsed())
-      return;
-
     EmitGlobal(cast<FunctionDecl>(D));
     // Always provide some coverage mapping
     // even for the functions that aren't emitted.
@@ -4214,10 +4209,6 @@ void CodeGenModule::EmitTopLevelDecl(Dec
   case Decl::Var:
   case Decl::Decomposition:
-    // Skip variable templates
-    if (cast<VarDecl>(D)->getDescribedVarTemplate())
-      return;
-    LLVM_FALLTHROUGH;
   case Decl::VarTemplateSpecialization:
     EmitGlobal(cast<VarDecl>(D));
     if (auto *DD = dyn_cast<DecompositionDecl>(D))
@@ -4276,16 +4267,9 @@ void CodeGenModule::EmitTopLevelDecl(Dec
       DI->EmitUsingDirective(cast<UsingDirectiveDecl>(*D));
     return;
   case Decl::CXXConstructor:
-    // Skip function templates
-    if (cast<FunctionDecl>(D)->getDescribedFunctionTemplate() ||
-        cast<FunctionDecl>(D)->isLateTemplateParsed())
-      return;
-
     getCXXABI().EmitCXXConstructors(cast<CXXConstructorDecl>(D));
     break;
   case Decl::CXXDestructor:
-    if (cast<FunctionDecl>(D)->isLateTemplateParsed())
-      return;
     getCXXABI().EmitCXXDestructors(cast<CXXDestructorDecl>(D));
     break;

Added: cfe/trunk/test/CodeGenCXX/microsoft-abi-emit-dependent.cpp
URL: https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_test_CodeGenCXX_microsoft-2Dabi-2Demit-2Ddependent.cpp-3Frev-3D323935-26view-3Dauto&d=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=o3kDXzdBUE3ljQXKeTWOMw&m=lpLH9VUhmNJcmdOGGUS4JH7kl-0dHB_UbZJavDZFar8&s=mAm9nqXVQhIgVg8KPFJg-dzCh8yKufwWzfiUNbPDk-Q&e=
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-emit-dependent.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-emit-dependent.cpp Wed Jan 31 16:28:36 2018
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -emit-llvm-only -fmodules -triple x86_64-windows %s
+// PR36181
+#pragma clang module build foo
+module foo {}
+#pragma clang module contents
+template <typename T> struct A {
+  friend void f(A<T>) {}
+};
+#pragma clang module endbuild
+#pragma clang module import foo
+void g() { f(A<int>()); }


_______________________________________________
cfe-commits mailing list
cfe-commits at lists.llvm.org<mailto:cfe-commits at lists.llvm.org>
https://urldefense.proofpoint.com/v2/url?u=http-3A__lists.llvm.org_cgi-2Dbin_mailman_listinfo_cfe-2Dcommits&d=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=o3kDXzdBUE3ljQXKeTWOMw&m=lpLH9VUhmNJcmdOGGUS4JH7kl-0dHB_UbZJavDZFar8&s=DpwzUMYVSTyRYllZ8J2SVU1ikJcj5-_6D5qjr2dNSL0&e=

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180201/3cda1c7f/attachment-0001.html>


More information about the cfe-commits mailing list