cebowleratibm created this revision.
cebowleratibm added a reviewer: daltenty.
Herald added a project: All.
cebowleratibm requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

An assertion failure was encountered after https://reviews.llvm.org/D126340:

llvm/clang/lib/AST/Decl.cpp:1510: clang::LinkageInfo 
clang::LinkageComputer::getLVForDecl(const clang::NamedDecl *, 
clang::LVComputationKind): Assertion `D->getCachedLinkage() == LV.getLinkage()' 
failed.

See chromium bug 
<https://bugs.chromium.org/p/chromium/issues/detail?id=1331274#c2> for a 
reproducer.

Note D126340 <https://reviews.llvm.org/D126340> was reverted and re-landed.  
The original problem can still be reproduced using the appropriate options as 
outlined in the new test.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D128223

Files:
  clang/lib/AST/Decl.cpp
  clang/test/CodeGenCXX/linkage-static-local-crash.cpp


Index: clang/test/CodeGenCXX/linkage-static-local-crash.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/linkage-static-local-crash.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple powerpc-ibm-aix 
-mdefault-visibility-export-mapping=explicit -fvisibility-inlines-hidden 
-emit-llvm %s -o - | FileCheck %s
+
+struct C {
+  template <typename> 
+  __attribute__((__visibility__("hidden"))) 
+  static int& f() {
+    static int g = 42;
+    return g;
+  }
+};
+
+template<typename T>
+void foo(T i) { C::f<T>(); }
+
+void bar() {
+  foo([]{});
+}
+
+// CHECK: @"_ZZN1C1fIZ3barvE3$_0EERivE1g" = internal global i32 42, align 4
Index: clang/lib/AST/Decl.cpp
===================================================================
--- clang/lib/AST/Decl.cpp
+++ clang/lib/AST/Decl.cpp
@@ -1349,19 +1349,24 @@
     // If a function is hidden by -fvisibility-inlines-hidden option and
     // is not explicitly attributed as a hidden function,
     // we should not make static local variables in the function hidden.
-    LV = getLVForDecl(FD, computation);
-    if (isa<VarDecl>(D) && useInlineVisibilityHidden(FD) &&
-        !LV.isVisibilityExplicit() &&
-        !Context.getLangOpts().VisibilityInlinesHiddenStaticLocalVar) {
+    bool mayBeVisible = 
+        isa<VarDecl>(D) && useInlineVisibilityHidden(FD) &&
+        !Context.getLangOpts().VisibilityInlinesHiddenStaticLocalVar;
+    LVComputationKind nestedComputation =
+        mayBeVisible
+            ? LVComputationKind(computation.getExplicitVisibilityKind())
+            : computation;
+    LV = getLVForDecl(FD, nestedComputation);
+    if (mayBeVisible && !LV.isVisibilityExplicit()) {
       assert(cast<VarDecl>(D)->isStaticLocal());
       // If this was an implicitly hidden inline method, check again for
       // explicit visibility on the parent class, and use that for static 
locals
       // if present.
       if (const auto *MD = dyn_cast<CXXMethodDecl>(FD))
-        LV = getLVForDecl(MD->getParent(), computation);
+        LV = getLVForDecl(MD->getParent(), nestedComputation);
       if (!LV.isVisibilityExplicit()) {
         Visibility globalVisibility =
-            computation.isValueVisibility()
+            nestedComputation.isValueVisibility()
                 ? Context.getLangOpts().getValueVisibilityMode()
                 : Context.getLangOpts().getTypeVisibilityMode();
         return LinkageInfo(VisibleNoLinkage, globalVisibility,


Index: clang/test/CodeGenCXX/linkage-static-local-crash.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/linkage-static-local-crash.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple powerpc-ibm-aix -mdefault-visibility-export-mapping=explicit -fvisibility-inlines-hidden -emit-llvm %s -o - | FileCheck %s
+
+struct C {
+  template <typename> 
+  __attribute__((__visibility__("hidden"))) 
+  static int& f() {
+    static int g = 42;
+    return g;
+  }
+};
+
+template<typename T>
+void foo(T i) { C::f<T>(); }
+
+void bar() {
+  foo([]{});
+}
+
+// CHECK: @"_ZZN1C1fIZ3barvE3$_0EERivE1g" = internal global i32 42, align 4
Index: clang/lib/AST/Decl.cpp
===================================================================
--- clang/lib/AST/Decl.cpp
+++ clang/lib/AST/Decl.cpp
@@ -1349,19 +1349,24 @@
     // If a function is hidden by -fvisibility-inlines-hidden option and
     // is not explicitly attributed as a hidden function,
     // we should not make static local variables in the function hidden.
-    LV = getLVForDecl(FD, computation);
-    if (isa<VarDecl>(D) && useInlineVisibilityHidden(FD) &&
-        !LV.isVisibilityExplicit() &&
-        !Context.getLangOpts().VisibilityInlinesHiddenStaticLocalVar) {
+    bool mayBeVisible = 
+        isa<VarDecl>(D) && useInlineVisibilityHidden(FD) &&
+        !Context.getLangOpts().VisibilityInlinesHiddenStaticLocalVar;
+    LVComputationKind nestedComputation =
+        mayBeVisible
+            ? LVComputationKind(computation.getExplicitVisibilityKind())
+            : computation;
+    LV = getLVForDecl(FD, nestedComputation);
+    if (mayBeVisible && !LV.isVisibilityExplicit()) {
       assert(cast<VarDecl>(D)->isStaticLocal());
       // If this was an implicitly hidden inline method, check again for
       // explicit visibility on the parent class, and use that for static locals
       // if present.
       if (const auto *MD = dyn_cast<CXXMethodDecl>(FD))
-        LV = getLVForDecl(MD->getParent(), computation);
+        LV = getLVForDecl(MD->getParent(), nestedComputation);
       if (!LV.isVisibilityExplicit()) {
         Visibility globalVisibility =
-            computation.isValueVisibility()
+            nestedComputation.isValueVisibility()
                 ? Context.getLangOpts().getValueVisibilityMode()
                 : Context.getLangOpts().getTypeVisibilityMode();
         return LinkageInfo(VisibleNoLinkage, globalVisibility,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to