r215579 - [modules] Fix a rejects-valid resulting from emitting an inline function

Richard Smith richard-llvm at metafoo.co.uk
Wed Aug 13 14:15:10 PDT 2014


Author: rsmith
Date: Wed Aug 13 16:15:09 2014
New Revision: 215579

URL: http://llvm.org/viewvc/llvm-project?rev=215579&view=rev
Log:
[modules] Fix a rejects-valid resulting from emitting an inline function
recursively within the emission of another inline function. This ultimately
led to us emitting the same inline function definition twice, which we then
rejected because we believed we had a mangled name conflict.

Modified:
    cfe/trunk/lib/CodeGen/ModuleBuilder.cpp
    cfe/trunk/test/Modules/Inputs/cxx-irgen-top.h
    cfe/trunk/test/Modules/cxx-irgen.cpp

Modified: cfe/trunk/lib/CodeGen/ModuleBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ModuleBuilder.cpp?rev=215579&r1=215578&r2=215579&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/ModuleBuilder.cpp (original)
+++ cfe/trunk/lib/CodeGen/ModuleBuilder.cpp Wed Aug 13 16:15:09 2014
@@ -117,10 +117,14 @@ namespace {
     }
 
     void EmitDeferredDecls() {
+      if (DeferredInlineMethodDefinitions.empty())
+        return;
+
       // Emit any deferred inline method definitions. Note that more deferred
       // methods may be added during this loop, since ASTConsumer callbacks
       // can be invoked if AST inspection results in declarations being added.
-      for (unsigned I = 0; I < DeferredInlineMethodDefinitions.size(); ++I)
+      HandlingTopLevelDeclRAII HandlingDecl(*this);
+      for (unsigned I = 0; I != DeferredInlineMethodDefinitions.size(); ++I)
         Builder->EmitTopLevelDecl(DeferredInlineMethodDefinitions[I]);
       DeferredInlineMethodDefinitions.clear();
     }

Modified: cfe/trunk/test/Modules/Inputs/cxx-irgen-top.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/cxx-irgen-top.h?rev=215579&r1=215578&r2=215579&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/cxx-irgen-top.h (original)
+++ cfe/trunk/test/Modules/Inputs/cxx-irgen-top.h Wed Aug 13 16:15:09 2014
@@ -38,3 +38,14 @@ namespace OperatorDeleteLookup {
   template<typename T> struct B { void operator delete(void*); virtual ~B() {} typedef int t; };
   typedef B<int>::t b_int_instantated;
 }
+
+namespace EmitInlineMethods {
+  struct A {
+    void f() {}
+    void g();
+  };
+  struct B {
+    void f();
+    void g() {}
+  };
+}

Modified: cfe/trunk/test/Modules/cxx-irgen.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/cxx-irgen.cpp?rev=215579&r1=215578&r2=215579&view=diff
==============================================================================
--- cfe/trunk/test/Modules/cxx-irgen.cpp (original)
+++ cfe/trunk/test/Modules/cxx-irgen.cpp Wed Aug 13 16:15:09 2014
@@ -1,5 +1,6 @@
 // RUN: rm -rf %t
 // RUN: %clang_cc1 -fmodules -x objective-c++ -std=c++11 -fmodules-cache-path=%t -I %S/Inputs -triple %itanium_abi_triple -disable-llvm-optzns -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fmodules -x objective-c++ -std=c++11 -fmodules-cache-path=%t -I %S/Inputs -triple %itanium_abi_triple -disable-llvm-optzns -emit-llvm -g -o - %s | FileCheck %s
 // FIXME: When we have a syntax for modules in C++, use that.
 
 @import cxx_irgen_top;
@@ -10,6 +11,22 @@ CtorInit<int> x;
 @import cxx_irgen_left;
 @import cxx_irgen_right;
 
+// Keep these two namespace definitions separate; merging them hides the bug.
+namespace EmitInlineMethods {
+  // CHECK-DAG: define linkonce_odr void @_ZN17EmitInlineMethods1C1fEPNS_1AE(
+  // CHECK-DAG: declare void @_ZN17EmitInlineMethods1A1gEv(
+  struct C {
+    __attribute__((used)) void f(A *p) { p->g(); }
+  };
+}
+namespace EmitInlineMethods {
+  // CHECK-DAG: define linkonce_odr void @_ZN17EmitInlineMethods1D1fEPNS_1BE(
+  // CHECK-DAG: define linkonce_odr void @_ZN17EmitInlineMethods1B1gEv(
+  struct D {
+    __attribute__((used)) void f(B *p) { p->g(); }
+  };
+}
+
 // CHECK-DAG: define available_externally hidden {{signext i32|i32}} @_ZN1SIiE1gEv({{.*}} #[[ALWAYS_INLINE:.*]] align
 int a = S<int>::g();
 





More information about the cfe-commits mailing list