<div dir="ltr">The MSDN page says they can be discarded if you turn on the linker option /OPT:REF.  My intrepretation is that yes, they can be discarded, but only at link time.</div><div class="gmail_extra"><br><br><div class="gmail_quote">
On Fri, May 17, 2013 at 1:38 PM, Rafael Espíndola <span dir="ltr"><<a href="mailto:rafael.espindola@gmail.com" target="_blank">rafael.espindola@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Can they be discarded? If so, please add a comment saying that they<br>
can. If not, you need no use weak_odr.<br>
<div><div class="h5"><br>
On 17 May 2013 13:22, Reid Kleckner <<a href="mailto:rnk@google.com">rnk@google.com</a>> wrote:<br>
> selectany only applies to externally visible global variables.  It has<br>
> the effect of making the data linkonce.  MSDN doesn't seem to require<br>
> that all definitions be the same, which means clang shouldn't use<br>
> linkonceodr.<br>
><br>
> <a href="http://llvm-reviews.chandlerc.com/D814" target="_blank">http://llvm-reviews.chandlerc.com/D814</a><br>
><br>
> Files:<br>
>   include/clang/Basic/Attr.td<br>
>   include/clang/Basic/DiagnosticSemaKinds.td<br>
>   lib/CodeGen/CodeGenModule.cpp<br>
>   lib/Sema/SemaDecl.cpp<br>
>   lib/Sema/SemaDeclAttr.cpp<br>
>   test/CodeGen/ms-declspecs.c<br>
>   test/SemaCXX/attr-selectany.cpp<br>
><br>
> Index: include/clang/Basic/Attr.td<br>
> ===================================================================<br>
> --- include/clang/Basic/Attr.td<br>
> +++ include/clang/Basic/Attr.td<br>
> @@ -948,6 +948,10 @@<br>
>    let Spellings = [Keyword<"__forceinline">];<br>
>  }<br>
><br>
> +def SelectAny : InheritableAttr {<br>
> +  let Spellings = [Declspec<"selectany">];<br>
> +}<br>
> +<br>
>  def Win64 : InheritableAttr {<br>
>    let Spellings = [Keyword<"__w64">];<br>
>  }<br>
> Index: include/clang/Basic/DiagnosticSemaKinds.td<br>
> ===================================================================<br>
> --- include/clang/Basic/DiagnosticSemaKinds.td<br>
> +++ include/clang/Basic/DiagnosticSemaKinds.td<br>
> @@ -1950,6 +1950,8 @@<br>
>    "weak identifier %0 never declared">;<br>
>  def err_attribute_weak_static : Error<<br>
>    "weak declaration cannot have internal linkage">;<br>
> +def err_attribute_selectany_non_extern_data : Error<<br>
> +  "'selectany' can only be applied to data items with external linkage">;<br>
>  def warn_attribute_weak_import_invalid_on_definition : Warning<<br>
>    "'weak_import' attribute cannot be specified on a definition">,<br>
>    InGroup<IgnoredAttributes>;<br>
> Index: lib/CodeGen/CodeGenModule.cpp<br>
> ===================================================================<br>
> --- lib/CodeGen/CodeGenModule.cpp<br>
> +++ lib/CodeGen/CodeGenModule.cpp<br>
> @@ -1937,7 +1937,12 @@<br>
>      return llvm::Function::DLLImportLinkage;<br>
>    else if (D->hasAttr<DLLExportAttr>())<br>
>      return llvm::Function::DLLExportLinkage;<br>
> -  else if (D->hasAttr<WeakAttr>()) {<br>
> +  else if (D->hasAttr<SelectAnyAttr>()) {<br>
> +    // MSDN does not say that selectany globals all have to have the same<br>
> +    // definition, so we use linkonce instead of linkonceodr here to be<br>
> +    // conservative.<br>
> +    return llvm::GlobalVariable::LinkOnceAnyLinkage;<br>
> +  } else if (D->hasAttr<WeakAttr>()) {<br>
>      if (GV->isConstant())<br>
>        return llvm::GlobalVariable::WeakODRLinkage;<br>
>      else<br>
> Index: lib/Sema/SemaDecl.cpp<br>
> ===================================================================<br>
> --- lib/Sema/SemaDecl.cpp<br>
> +++ lib/Sema/SemaDecl.cpp<br>
> @@ -4636,6 +4636,15 @@<br>
>        ND.dropAttr<WeakRefAttr>();<br>
>      }<br>
>    }<br>
> +<br>
> +  // 'selectany' only applies to externally visible varable declarations.<br>
> +  // It does not apply to functions.<br>
> +  if (SelectAnyAttr *Attr = ND.getAttr<SelectAnyAttr>()) {<br>
> +    if (isa<FunctionDecl>(ND) || !ND.isExternallyVisible()) {<br>
> +      S.Diag(Attr->getLocation(), diag::err_attribute_selectany_non_extern_data);<br>
> +      ND.dropAttr<SelectAnyAttr>();<br>
> +    }<br>
> +  }<br>
>  }<br>
><br>
>  /// Given that we are within the definition of the given function,<br>
> Index: lib/Sema/SemaDeclAttr.cpp<br>
> ===================================================================<br>
> --- lib/Sema/SemaDeclAttr.cpp<br>
> +++ lib/Sema/SemaDeclAttr.cpp<br>
> @@ -4690,6 +4690,16 @@<br>
>                               Attr.getAttributeSpellingListIndex()));<br>
>  }<br>
><br>
> +static void handleSelectAnyAttr(Sema &S, Decl *D, const AttributeList &Attr) {<br>
> +  if (!checkMicrosoftExt(S, Attr))<br>
> +    return;<br>
> +  // Check linkage after possibly merging declaratinos.  See<br>
> +  // checkAttributesAfterMerging().<br>
> +  D->addAttr(::new (S.Context)<br>
> +             SelectAnyAttr(Attr.getRange(), S.Context,<br>
> +                           Attr.getAttributeSpellingListIndex()));<br>
> +}<br>
> +<br>
>  //===----------------------------------------------------------------------===//<br>
>  // Top Level Sema Entry Points<br>
>  //===----------------------------------------------------------------------===//<br>
> @@ -4916,6 +4926,9 @@<br>
>    case AttributeList::AT_ForceInline:<br>
>      handleForceInlineAttr(S, D, Attr);<br>
>      break;<br>
> +  case AttributeList::AT_SelectAny:<br>
> +    handleSelectAnyAttr(S, D, Attr);<br>
> +    break;<br>
><br>
>    // Thread safety attributes:<br>
>    case AttributeList::AT_GuardedVar:<br>
> Index: test/CodeGen/ms-declspecs.c<br>
> ===================================================================<br>
> --- test/CodeGen/ms-declspecs.c<br>
> +++ test/CodeGen/ms-declspecs.c<br>
> @@ -1,5 +1,10 @@<br>
>  // RUN: %clang_cc1 -triple i386-pc-win32 %s -emit-llvm -fms-compatibility -o - | FileCheck %s<br>
><br>
> +__declspec(selectany) int x1 = 1;<br>
> +const __declspec(selectany) int x2 = 2;<br>
> +// CHECK: @x1 = linkonce global i32 1, align 4<br>
> +// CHECK: @x2 = linkonce constant i32 2, align 4<br>
> +<br>
>  struct __declspec(align(16)) S {<br>
>    char x;<br>
>  };<br>
> Index: test/SemaCXX/attr-selectany.cpp<br>
> ===================================================================<br>
> --- /dev/null<br>
> +++ test/SemaCXX/attr-selectany.cpp<br>
> @@ -0,0 +1,26 @@<br>
> +// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify %s<br>
> +// MSVC produces similar diagnostics.<br>
> +<br>
> +__declspec(selectany) void foo() { } // expected-error{{'selectany' can only be applied to data items with external linkage}}<br>
> +<br>
> +__declspec(selectany) int x1 = 1;<br>
> +<br>
> +const __declspec(selectany) int x2 = 2; // expected-error{{'selectany' can only be applied to data items with external linkage}}<br>
> +<br>
> +extern const __declspec(selectany) int x3 = 3;<br>
> +<br>
> +extern const int x4;<br>
> +const __declspec(selectany) int x4 = 4;<br>
> +<br>
> +// MSDN says this is incorrect, but MSVC doesn't diagnose it.<br>
> +extern __declspec(selectany) int x5;<br>
> +<br>
> +static __declspec(selectany) int x6 = 2; // expected-error{{'selectany' can only be applied to data items with external linkage}}<br>
> +<br>
> +class X {<br>
> + public:<br>
> +  X(int i) { i++; };<br>
> +  int i;<br>
> +};<br>
> +<br>
> +__declspec(selectany) X x(1);<br>
><br>
</div></div>> _______________________________________________<br>
> cfe-commits mailing list<br>
> <a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
><br>
</blockquote></div><br></div>