r182962 - Fix PR16060.

Rafael Espindola rafael.espindola at gmail.com
Thu May 30 14:23:15 PDT 2013


Author: rafael
Date: Thu May 30 16:23:15 2013
New Revision: 182962

URL: http://llvm.org/viewvc/llvm-project?rev=182962&view=rev
Log:
Fix PR16060.

The testcase in PR16060 points out that while template arguments can
show that a type is not externally visible, the standards still says
they have external linkage.

In terms of our implementation, it means that we should merge just the
isExternallyVisible bit, not the formal linkage.

Modified:
    cfe/trunk/include/clang/Basic/Visibility.h
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/test/SemaCXX/linkage2.cpp

Modified: cfe/trunk/include/clang/Basic/Visibility.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Visibility.h?rev=182962&r1=182961&r2=182962&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Visibility.h (original)
+++ cfe/trunk/include/clang/Basic/Visibility.h Thu May 30 16:23:15 2013
@@ -89,6 +89,20 @@ public:
     mergeLinkage(other.getLinkage());
   }
 
+  void mergeExternalVisibility(Linkage L) {
+    Linkage ThisL = getLinkage();
+    if (!isExternallyVisible(L)) {
+      if (ThisL == VisibleNoLinkage)
+        ThisL = NoLinkage;
+      else if (ThisL == ExternalLinkage)
+        ThisL = UniqueExternalLinkage;
+    }
+    setLinkage(ThisL);
+  }
+  void mergeExternalVisibility(LinkageInfo Other) {
+    mergeExternalVisibility(Other.getLinkage());
+  }
+
   /// Merge in the visibility 'newVis'.
   void mergeVisibility(Visibility newVis, bool newExplicit) {
     Visibility oldVis = getVisibility();

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=182962&r1=182961&r2=182962&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Thu May 30 16:23:15 2013
@@ -471,7 +471,9 @@ static void mergeTemplateLV(LinkageInfo
   // instantiation with a visibility attribute.
   const TemplateArgumentList &templateArgs = spec->getTemplateArgs();
   LinkageInfo argsLV = getLVForTemplateArgumentList(templateArgs, computation);
-  LV.mergeMaybeWithVisibility(argsLV, considerVisibility);
+  if (considerVisibility)
+    LV.mergeVisibility(argsLV);
+  LV.mergeExternalVisibility(argsLV);
 }
 
 static bool useInlineVisibilityHidden(const NamedDecl *D) {
@@ -863,8 +865,9 @@ static LinkageInfo getLVForClassMember(c
     // Modify the variable's linkage by its type, but ignore the
     // type's visibility unless it's a definition.
     LinkageInfo typeLV = getLVForType(*VD->getType(), computation);
-    LV.mergeMaybeWithVisibility(typeLV,
-                 !LV.isVisibilityExplicit() && !classLV.isVisibilityExplicit());
+    if (!LV.isVisibilityExplicit() && !classLV.isVisibilityExplicit())
+      LV.mergeVisibility(typeLV);
+    LV.mergeExternalVisibility(typeLV);
 
     if (isExplicitMemberSpecialization(VD)) {
       explicitSpecSuppressor = VD;

Modified: cfe/trunk/test/SemaCXX/linkage2.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/linkage2.cpp?rev=182962&r1=182961&r2=182962&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/linkage2.cpp (original)
+++ cfe/trunk/test/SemaCXX/linkage2.cpp Thu May 30 16:23:15 2013
@@ -186,3 +186,18 @@ namespace test17 {
     g();
   }
 }
+
+namespace test18 {
+  template <typename T> struct foo {
+    template <T *P> static void f() {}
+    static void *g() { return (void *)f<&x>; }
+    static T x;
+  };
+  template <typename T> T foo<T>::x;
+  inline void *f() {
+    struct S {
+    };
+    return foo<S>::g();
+  }
+  void *h() { return f(); }
+}





More information about the cfe-commits mailing list