<div dir="ltr">Hi Richard,<div><br></div><div>This commit has caused a new regression in Clang which causes an assertion failure for extern "C" function definitions whose return type is a pointer to a record. I filed <a href="https://bugs.llvm.org/show_bug.cgi?id=35697">https://bugs.llvm.org/show_bug.cgi?id=35697</a> which contains the minimized test case for this issue. Do you mind taking a look at it?</div><div><br></div><div>Cheers,</div><div>Alex </div></div><div class="gmail_extra"><br><div class="gmail_quote">On 20 September 2017 at 00:22, Richard Smith via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rsmith<br>
Date: Wed Sep 20 00:22:00 2017<br>
New Revision: 313729<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=313729&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=313729&view=rev</a><br>
Log:<br>
Implement C++ [basic.link]p8.<br>
<br>
If a function or variable has a type with no linkage (and is not extern "C"),<br>
any use of it requires a definition within the same translation unit; the idea<br>
is that it is not possible to define the entity elsewhere, so any such use is<br>
necessarily an error.<br>
<br>
There is an exception, though: some types formally have no linkage but<br>
nonetheless can be referenced from other translation units (for example, this<br>
happens to anonymous structures defined within inline functions). For entities<br>
with those types, we suppress the diagnostic except under -pedantic.<br>
<br>
Added:<br>
    cfe/trunk/test/CXX/basic/<wbr>basic.link/p8.cpp<br>
Modified:<br>
    cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td<br>
    cfe/trunk/include/clang/Sema/<wbr>Sema.h<br>
    cfe/trunk/include/clang/Sema/<wbr>SemaInternal.h<br>
    cfe/trunk/lib/AST/Decl.cpp<br>
    cfe/trunk/lib/Sema/Sema.cpp<br>
    cfe/trunk/lib/Sema/SemaDecl.<wbr>cpp<br>
    cfe/trunk/lib/Sema/SemaExpr.<wbr>cpp<br>
    cfe/trunk/test/Analysis/<a href="http://malloc.mm" rel="noreferrer" target="_blank">malloc<wbr>.mm</a><br>
    cfe/trunk/test/Analysis/<wbr>reference.cpp<br>
    cfe/trunk/test/CodeGenCXX/<wbr>debug-info-method.cpp<br>
    cfe/trunk/test/CodeGenCXX/<wbr>mangle-ms-cxx11.cpp<br>
    cfe/trunk/test/CodeGenCXX/<wbr>mangle.cpp<br>
    cfe/trunk/test/PCH/<a href="http://cxx11-lambdas.mm" rel="noreferrer" target="_blank">cxx11-<wbr>lambdas.mm</a><br>
    cfe/trunk/test/SemaCXX/warn-<wbr>unreachable.cpp<br>
<br>
Modified: cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=313729&r1=313728&r2=313729&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Basic/<wbr>DiagnosticSemaKinds.td?rev=<wbr>313729&r1=313728&r2=313729&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td Wed Sep 20 00:22:00 2017<br>
@@ -4707,6 +4707,14 @@ def note_deleted_assign_field : Note<<br>
 def warn_undefined_internal : Warning<<br>
   "%select{function|variable}0 %q1 has internal linkage but is not defined">,<br>
   InGroup<DiagGroup<"undefined-<wbr>internal">>;<br>
+def err_undefined_internal_type : Error<<br>
+  "%select{function|variable}0 %q1 is used but not defined in this "<br>
+  "translation unit, and cannot be defined in any other translation unit "<br>
+  "because its type does not have linkage">;<br>
+def ext_undefined_internal_type : Extension<<br>
+  "ISO C++ requires a definition in this translation unit for "<br>
+  "%select{function|variable}0 %q1 because its type does not have linkage">,<br>
+  InGroup<DiagGroup<"undefined-<wbr>internal-type">>;<br>
 def warn_undefined_inline : Warning<"inline function %q0 is not defined">,<br>
   InGroup<DiagGroup<"undefined-<wbr>inline">>;<br>
 def err_undefined_inline_var : Error<"inline variable %q0 is not defined">;<br>
<br>
Modified: cfe/trunk/include/clang/Sema/<wbr>Sema.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=313729&r1=313728&r2=313729&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Sema/Sema.h?rev=313729&<wbr>r1=313728&r2=313729&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/Sema/<wbr>Sema.h (original)<br>
+++ cfe/trunk/include/clang/Sema/<wbr>Sema.h Wed Sep 20 00:22:00 2017<br>
@@ -1086,6 +1086,11 @@ public:<br>
   /// definition in this translation unit.<br>
   llvm::MapVector<NamedDecl *, SourceLocation> UndefinedButUsed;<br>
<br>
+  /// Determine if VD, which must be a variable or function, is an external<br>
+  /// symbol that nonetheless can't be referenced from outside this translation<br>
+  /// unit because its type has no linkage and it's not extern "C".<br>
+  bool isExternalWithNoLinkageType(<wbr>ValueDecl *VD);<br>
+<br>
   /// Obtain a sorted list of functions that are undefined but ODR-used.<br>
   void getUndefinedButUsed(<br>
       SmallVectorImpl<std::pair<<wbr>NamedDecl *, SourceLocation> > &Undefined);<br>
<br>
Modified: cfe/trunk/include/clang/Sema/<wbr>SemaInternal.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/SemaInternal.h?rev=313729&r1=313728&r2=313729&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Sema/SemaInternal.h?rev=<wbr>313729&r1=313728&r2=313729&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/Sema/<wbr>SemaInternal.h (original)<br>
+++ cfe/trunk/include/clang/Sema/<wbr>SemaInternal.h Wed Sep 20 00:22:00 2017<br>
@@ -73,7 +73,8 @@ inline void MarkVarDeclODRUsed(VarDecl *<br>
   // Keep track of used but undefined variables.<br>
   // FIXME: We shouldn't suppress this warning for static data members.<br>
   if (Var->hasDefinition(SemaRef.<wbr>Context) == VarDecl::DeclarationOnly &&<br>
-      (!Var->isExternallyVisible() || Var->isInline()) &&<br>
+      (!Var->isExternallyVisible() || Var->isInline() ||<br>
+       SemaRef.<wbr>isExternalWithNoLinkageType(<wbr>Var)) &&<br>
       !(Var->isStaticDataMember() && Var->hasInit())) {<br>
     SourceLocation &old = SemaRef.UndefinedButUsed[Var-><wbr>getCanonicalDecl()];<br>
     if (old.isInvalid())<br>
<br>
Modified: cfe/trunk/lib/AST/Decl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=313729&r1=313728&r2=313729&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/AST/<wbr>Decl.cpp?rev=313729&r1=313728&<wbr>r2=313729&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/AST/Decl.cpp (original)<br>
+++ cfe/trunk/lib/AST/Decl.cpp Wed Sep 20 00:22:00 2017<br>
@@ -721,8 +721,7 @@ LinkageComputer::<wbr>getLVForNamespaceScopeD<br>
     // because of this, but unique-external linkage suits us.<br>
     if (Context.getLangOpts().<wbr>CPlusPlus && !isFirstInExternCContext(Var)) {<br>
       LinkageInfo TypeLV = getLVForType(*Var->getType(), computation);<br>
-      if (TypeLV.getLinkage() != ExternalLinkage &&<br>
-          TypeLV.getLinkage() != ModuleLinkage)<br>
+      if (!isExternallyVisible(TypeLV.<wbr>getLinkage()))<br>
         return LinkageInfo::uniqueExternal();<br>
       if (!LV.isVisibilityExplicit())<br>
         LV.mergeVisibility(TypeLV);<br>
@@ -772,7 +771,7 @@ LinkageComputer::<wbr>getLVForNamespaceScopeD<br>
       QualType TypeAsWritten = Function->getType();<br>
       if (TypeSourceInfo *TSI = Function->getTypeSourceInfo())<br>
         TypeAsWritten = TSI->getType();<br>
-      if (TypeAsWritten->getLinkage() == UniqueExternalLinkage)<br>
+      if (!isExternallyVisible(<wbr>TypeAsWritten->getLinkage()))<br>
         return LinkageInfo::uniqueExternal();<br>
     }<br>
<br>
@@ -909,7 +908,7 @@ LinkageComputer::<wbr>getLVForClassMember(con<br>
   const NamedDecl *explicitSpecSuppressor = nullptr;<br>
<br>
   if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {<br>
-    // If the type of the function uses a type with unique-external<br>
+    // If the type of the function uses a type that has non-externally-visible<br>
     // linkage, it's not legally usable from outside this translation unit.<br>
     // But only look at the type-as-written. If this function has an<br>
     // auto-deduced return type, we can't compute the linkage of that type<br>
@@ -922,7 +921,7 @@ LinkageComputer::<wbr>getLVForClassMember(con<br>
       QualType TypeAsWritten = MD->getType();<br>
       if (TypeSourceInfo *TSI = MD->getTypeSourceInfo())<br>
         TypeAsWritten = TSI->getType();<br>
-      if (TypeAsWritten->getLinkage() == UniqueExternalLinkage)<br>
+      if (!isExternallyVisible(<wbr>TypeAsWritten->getLinkage()))<br>
         return LinkageInfo::uniqueExternal();<br>
     }<br>
     // If this is a method template specialization, use the linkage for<br>
@@ -1119,6 +1118,9 @@ LinkageInfo LinkageComputer::getLVForClo<br>
                                              Decl *ContextDecl,<br>
                                              LVComputationKind computation) {<br>
   // This lambda has its linkage/visibility determined by its owner.<br>
+  // FIXME: This is wrong. A lambda never formally has linkage; if this<br>
+  // calculation determines the lambda has external linkage, it should be<br>
+  // downgraded to VisibleNoLinkage.<br>
   if (ContextDecl) {<br>
     if (isa<ParmVarDecl>(ContextDecl)<wbr>)<br>
       DC = ContextDecl->getDeclContext()-<wbr>>getRedeclContext();<br>
<br>
Modified: cfe/trunk/lib/Sema/Sema.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=313729&r1=313728&r2=313729&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>Sema.cpp?rev=313729&r1=313728&<wbr>r2=313729&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/Sema.cpp (original)<br>
+++ cfe/trunk/lib/Sema/Sema.cpp Wed Sep 20 00:22:00 2017<br>
@@ -582,6 +582,23 @@ static bool ShouldRemoveFromUnused(Sema<br>
   return false;<br>
 }<br>
<br>
+static bool isFunctionOrVarDeclExternC(<wbr>NamedDecl *ND) {<br>
+  if (auto *FD = dyn_cast<FunctionDecl>(ND))<br>
+    return FD->isExternC();<br>
+  return cast<VarDecl>(ND)->isExternC()<wbr>;<br>
+}<br>
+<br>
+/// Determine whether ND is an external-linkage function or variable whose<br>
+/// type has no linkage.<br>
+bool Sema::<wbr>isExternalWithNoLinkageType(<wbr>ValueDecl *VD) {<br>
+  // Note: it's not quite enough to check whether VD has UniqueExternalLinkage,<br>
+  // because we also want to catch the case where its type has VisibleNoLinkage,<br>
+  // which does not affect the linkage of VD.<br>
+  return getLangOpts().CPlusPlus && VD->hasExternalFormalLinkage() &&<br>
+         !isExternalFormalLinkage(VD-><wbr>getType()->getLinkage()) &&<br>
+         !isFunctionOrVarDeclExternC(<wbr>VD);<br>
+}<br>
+<br>
 /// Obtains a sorted list of functions and variables that are undefined but<br>
 /// ODR-used.<br>
 void Sema::getUndefinedButUsed(<br>
@@ -598,17 +615,27 @@ void Sema::getUndefinedButUsed(<br>
     if (isa<CXXDeductionGuideDecl>(<wbr>ND))<br>
       continue;<br>
<br>
+    if (ND->hasAttr<DLLImportAttr>() || ND->hasAttr<DLLExportAttr>()) {<br>
+      // An exported function will always be emitted when defined, so even if<br>
+      // the function is inline, it doesn't have to be emitted in this TU. An<br>
+      // imported function implies that it has been exported somewhere else.<br>
+      continue;<br>
+    }<br>
+<br>
     if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {<br>
       if (FD->isDefined())<br>
         continue;<br>
       if (FD->isExternallyVisible() &&<br>
+          !isExternalWithNoLinkageType(<wbr>FD) &&<br>
           !FD->getMostRecentDecl()-><wbr>isInlined())<br>
         continue;<br>
     } else {<br>
       auto *VD = cast<VarDecl>(ND);<br>
       if (VD->hasDefinition() != VarDecl::DeclarationOnly)<br>
         continue;<br>
-      if (VD->isExternallyVisible() && !VD->getMostRecentDecl()-><wbr>isInline())<br>
+      if (VD->isExternallyVisible() &&<br>
+          !isExternalWithNoLinkageType(<wbr>VD) &&<br>
+          !VD->getMostRecentDecl()-><wbr>isInline())<br>
         continue;<br>
     }<br>
<br>
@@ -626,33 +653,43 @@ static void checkUndefinedButUsed(Sema &<br>
   S.getUndefinedButUsed(<wbr>Undefined);<br>
   if (Undefined.empty()) return;<br>
<br>
-  for (SmallVectorImpl<std::pair<<wbr>NamedDecl *, SourceLocation> >::iterator<br>
-         I = Undefined.begin(), E = Undefined.end(); I != E; ++I) {<br>
-    NamedDecl *ND = I->first;<br>
-<br>
-    if (ND->hasAttr<DLLImportAttr>() || ND->hasAttr<DLLExportAttr>()) {<br>
-      // An exported function will always be emitted when defined, so even if<br>
-      // the function is inline, it doesn't have to be emitted in this TU. An<br>
-      // imported function implies that it has been exported somewhere else.<br>
-      continue;<br>
-    }<br>
-<br>
-    if (!ND->isExternallyVisible()) {<br>
-      S.Diag(ND->getLocation(), diag::warn_undefined_internal)<br>
-        << isa<VarDecl>(ND) << ND;<br>
-    } else if (auto *FD = dyn_cast<FunctionDecl>(ND)) {<br>
+  for (auto Undef : Undefined) {<br>
+    ValueDecl *VD = cast<ValueDecl>(Undef.first);<br>
+    SourceLocation UseLoc = Undef.second;<br>
+<br>
+    if (S.<wbr>isExternalWithNoLinkageType(<wbr>VD)) {<br>
+      // C++ [basic.link]p8:<br>
+      //   A type without linkage shall not be used as the type of a variable<br>
+      //   or function with external linkage unless<br>
+      //    -- the entity has C language linkage<br>
+      //    -- the entity is not odr-used or is defined in the same TU<br>
+      //<br>
+      // As an extension, accept this in cases where the type is externally<br>
+      // visible, since the function or variable actually can be defined in<br>
+      // another translation unit in that case.<br>
+      S.Diag(VD->getLocation(), isExternallyVisible(VD-><wbr>getType()->getLinkage())<br>
+                                    ? diag::ext_undefined_internal_<wbr>type<br>
+                                    : diag::err_undefined_internal_<wbr>type)<br>
+        << isa<VarDecl>(VD) << VD;<br>
+    } else if (!VD->isExternallyVisible()) {<br>
+      // FIXME: We can promote this to an error. The function or variable can't<br>
+      // be defined anywhere else, so the program must necessarily violate the<br>
+      // one definition rule.<br>
+      S.Diag(VD->getLocation(), diag::warn_undefined_internal)<br>
+        << isa<VarDecl>(VD) << VD;<br>
+    } else if (auto *FD = dyn_cast<FunctionDecl>(VD)) {<br>
       (void)FD;<br>
       assert(FD->getMostRecentDecl()<wbr>->isInlined() &&<br>
              "used object requires definition but isn't inline or internal?");<br>
       // FIXME: This is ill-formed; we should reject.<br>
-      S.Diag(ND->getLocation(), diag::warn_undefined_inline) << ND;<br>
+      S.Diag(VD->getLocation(), diag::warn_undefined_inline) << VD;<br>
     } else {<br>
-      assert(cast<VarDecl>(ND)-><wbr>getMostRecentDecl()->isInline(<wbr>) &&<br>
+      assert(cast<VarDecl>(VD)-><wbr>getMostRecentDecl()->isInline(<wbr>) &&<br>
              "used var requires definition but isn't inline or internal?");<br>
-      S.Diag(ND->getLocation(), diag::err_undefined_inline_<wbr>var) << ND;<br>
+      S.Diag(VD->getLocation(), diag::err_undefined_inline_<wbr>var) << VD;<br>
     }<br>
-    if (I->second.isValid())<br>
-      S.Diag(I->second, diag::note_used_here);<br>
+    if (UseLoc.isValid())<br>
+      S.Diag(UseLoc, diag::note_used_here);<br>
   }<br>
<br>
   S.UndefinedButUsed.clear();<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDecl.<wbr>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=313729&r1=313728&r2=313729&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>SemaDecl.cpp?rev=313729&r1=<wbr>313728&r2=313729&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/SemaDecl.<wbr>cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDecl.<wbr>cpp Wed Sep 20 00:22:00 2017<br>
@@ -3827,7 +3827,7 @@ void Sema::MergeVarDecl(VarDecl *New, Lo<br>
     }<br>
   }<br>
<br>
-  // If this redeclaration makes the function inline, we may need to add it to<br>
+  // If this redeclaration makes the variable inline, we may need to add it to<br>
   // UndefinedButUsed.<br>
   if (!Old->isInline() && New->isInline() && Old->isUsed(false) &&<br>
       !Old->getDefinition() && !New-><wbr>isThisDeclarationADefinition()<wbr>)<br>
@@ -12329,18 +12329,6 @@ Decl *Sema::<wbr>ActOnFinishFunctionBody(Decl<br>
       }<br>
     }<br>
<br>
-    // The only way to be included in UndefinedButUsed is if there is an<br>
-    // ODR use before the definition. Avoid the expensive map lookup if this<br>
-    // is the first declaration.<br>
-    if (!FD->isFirstDecl() && FD->getPreviousDecl()->isUsed(<wbr>)) {<br>
-      if (!FD->isExternallyVisible())<br>
-        UndefinedButUsed.erase(FD);<br>
-      else if (FD->isInlined() &&<br>
-               !LangOpts.GNUInline &&<br>
-               (!FD->getPreviousDecl()-><wbr>hasAttr<GNUInlineAttr>()))<br>
-        UndefinedButUsed.erase(FD);<br>
-    }<br>
-<br>
     // If the function implicitly returns zero (like 'main') or is naked,<br>
     // don't complain about missing return statements.<br>
     if (FD->hasImplicitReturnZero() || FD->hasAttr<NakedAttr>())<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaExpr.<wbr>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=313729&r1=313728&r2=313729&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>SemaExpr.cpp?rev=313729&r1=<wbr>313728&r2=313729&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/SemaExpr.<wbr>cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaExpr.<wbr>cpp Wed Sep 20 00:22:00 2017<br>
@@ -13897,6 +13897,8 @@ void Sema::MarkFunctionReferenced(<wbr>Source<br>
              !LangOpts.GNUInline &&<br>
              !Func->getMostRecentDecl()-><wbr>hasAttr<GNUInlineAttr>())<br>
       UndefinedButUsed.insert(std::<wbr>make_pair(Func-><wbr>getCanonicalDecl(), Loc));<br>
+    else if (isExternalWithNoLinkageType(<wbr>Func))<br>
+      UndefinedButUsed.insert(std::<wbr>make_pair(Func-><wbr>getCanonicalDecl(), Loc));<br>
   }<br>
<br>
   Func->markUsed(Context);<br>
<br>
Modified: cfe/trunk/test/Analysis/<a href="http://malloc.mm" rel="noreferrer" target="_blank">malloc<wbr>.mm</a><br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/malloc.mm?rev=313729&r1=313728&r2=313729&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/<wbr>Analysis/malloc.mm?rev=313729&<wbr>r1=313728&r2=313729&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/Analysis/<a href="http://malloc.mm" rel="noreferrer" target="_blank">malloc<wbr>.mm</a> (original)<br>
+++ cfe/trunk/test/Analysis/<a href="http://malloc.mm" rel="noreferrer" target="_blank">malloc<wbr>.mm</a> Wed Sep 20 00:22:00 2017<br>
@@ -187,7 +187,7 @@ typedef volatile struct {<br>
  void *opaque1;<br>
  long opaque2;<br>
 } OSQueueHead;<br>
-void OSAtomicEnqueue( OSQueueHead *__list, void *__new, size_t __offset) __attribute__((weak_import));<br>
+extern "C" void OSAtomicEnqueue( OSQueueHead *__list, void *__new, size_t __offset) __attribute__((weak_import));<br>
 static inline void radar11111210(OSQueueHead *pool) {<br>
     void *newItem = malloc(4);<br>
     OSAtomicEnqueue(pool, newItem, 4);<br>
<br>
Modified: cfe/trunk/test/Analysis/<wbr>reference.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/reference.cpp?rev=313729&r1=313728&r2=313729&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/<wbr>Analysis/reference.cpp?rev=<wbr>313729&r1=313728&r2=313729&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/Analysis/<wbr>reference.cpp (original)<br>
+++ cfe/trunk/test/Analysis/<wbr>reference.cpp Wed Sep 20 00:22:00 2017<br>
@@ -117,6 +117,11 @@ void testRetroactiveNullReference(<wbr>int *x<br>
   y = 5; // expected-warning{{Dereference of null pointer}}<br>
 }<br>
<br>
+namespace TestReferenceAddress {<br>
+struct S { int &x; };<br>
+S getS();<br>
+S *getSP();<br>
+<br>
 void testReferenceAddress(int &x) {<br>
 // FIXME: Move non-zero reference assumption out of RangeConstraintManager.cpp:422<br>
 #ifdef ANALYZER_CM_Z3<br>
@@ -127,23 +132,19 @@ void testReferenceAddress(int &x) {<br>
   clang_analyzer_eval(&ref() != 0); // expected-warning{{TRUE}}<br>
 #endif<br>
<br>
-  struct S { int &x; };<br>
-<br>
-  extern S getS();<br>
 #ifdef ANALYZER_CM_Z3<br>
   clang_analyzer_eval(&getS().x != 0); // expected-warning{{UNKNOWN}}<br>
 #else<br>
   clang_analyzer_eval(&getS().x != 0); // expected-warning{{TRUE}}<br>
 #endif<br>
<br>
-  extern S *getSP();<br>
 #ifdef ANALYZER_CM_Z3<br>
   clang_analyzer_eval(&getSP()-><wbr>x != 0); // expected-warning{{UNKNOWN}}<br>
 #else<br>
   clang_analyzer_eval(&getSP()-><wbr>x != 0); // expected-warning{{TRUE}}<br>
 #endif<br>
 }<br>
-<br>
+}<br>
<br>
 void testFunctionPointerReturn(void *opaque) {<br>
   typedef int &(*RefFn)();<br>
<br>
Added: cfe/trunk/test/CXX/basic/<wbr>basic.link/p8.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/basic/basic.link/p8.cpp?rev=313729&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/CXX/<wbr>basic/basic.link/p8.cpp?rev=<wbr>313729&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/CXX/basic/<wbr>basic.link/p8.cpp (added)<br>
+++ cfe/trunk/test/CXX/basic/<wbr>basic.link/p8.cpp Wed Sep 20 00:22:00 2017<br>
@@ -0,0 +1,69 @@<br>
+// RUN: %clang_cc1 -std=c++2a -verify %s -pedantic<br>
+<br>
+template<typename T> struct Template {};<br>
+<br>
+struct Linkage1 { struct Inner {}; };<br>
+typedef struct { struct Inner {}; } Linkage2;<br>
+<br>
+typedef struct {} const NoLinkage1;<br>
+auto x = [] {};<br>
+typedef decltype(x) NoLinkage2;<br>
+auto f() { return [] {}; }<br>
+typedef decltype(f()) NoLinkage3;<br>
+<br>
+inline auto g() { return [] {}; }<br>
+typedef decltype(g()) VisibleNoLinkage1;<br>
+inline auto y = [] {};<br>
+typedef decltype(x) VisibleNoLinkage2;<br>
+inline auto h() { struct {} x; return x; }<br>
+typedef decltype(h()) VisibleNoLinkage3;<br>
+<br>
+extern Linkage1 linkage1v;<br>
+extern Linkage1::Inner linkage1iv;<br>
+extern Linkage2 linkage2v;<br>
+extern Linkage2::Inner linkage2iv;<br>
+extern Template<Linkage1> linkaget1v;<br>
+extern Linkage1 linkage1f();<br>
+void linkage2f(Linkage2);<br>
+<br>
+void use_linkage() {<br>
+  &linkage1v, &linkage1iv, &linkage2v, &linkage2iv, &linkaget1v; // expected-warning 5{{unused}}<br>
+  linkage1f();<br>
+  linkage2f({});<br>
+}<br>
+<br>
+extern NoLinkage1 no_linkage1(); // expected-error {{function 'no_linkage1' is used but not defined in this translation unit}}<br>
+extern NoLinkage2 no_linkage2(); // expected-error {{function 'no_linkage2' is used but not defined in this translation unit}}<br>
+extern NoLinkage3 no_linkage3(); // expected-error {{function 'no_linkage3' is used but not defined in this translation unit}}<br>
+<br>
+void use_no_linkage() {<br>
+  no_linkage1(); // expected-note {{used here}}<br>
+  no_linkage2(); // expected-note {{used here}}<br>
+  no_linkage3(); // expected-note {{used here}}<br>
+}<br>
+<br>
+// FIXME: This should emit an extension warning. It does not because we<br>
+// incorrectly give the lambda external linkage.<br>
+extern VisibleNoLinkage1 visible_no_linkage1();<br>
+<br>
+// FIXME: We should accept this as an extension. We don't because we<br>
+// incorrectly give the lambda no linkage instead of "VisibleNoLinkage".<br>
+extern VisibleNoLinkage2 visible_no_linkage2(); // expected-error {{used but not defined}}<br>
+<br>
+// This case is correctly accepted as an extension.<br>
+extern VisibleNoLinkage3 visible_no_linkage3(); // expected-warning {{ISO C++ requires a definition}}<br>
+<br>
+void use_visible_no_linkage() {<br>
+  visible_no_linkage1();<br>
+  visible_no_linkage2(); // expected-note {{used here}}<br>
+  visible_no_linkage3(); // expected-note {{used here}}<br>
+}<br>
+<br>
+<br>
+extern inline int not_defined; // expected-error {{not defined}}<br>
+extern inline int defined_after_use;<br>
+void use_inline_vars() {<br>
+  not_defined = 1; // expected-note {{used here}}<br>
+  defined_after_use = 2;<br>
+}<br>
+inline int defined_after_use;<br>
<br>
Modified: cfe/trunk/test/CodeGenCXX/<wbr>debug-info-method.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/debug-info-method.cpp?rev=313729&r1=313728&r2=313729&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/<wbr>CodeGenCXX/debug-info-method.<wbr>cpp?rev=313729&r1=313728&r2=<wbr>313729&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/CodeGenCXX/<wbr>debug-info-method.cpp (original)<br>
+++ cfe/trunk/test/CodeGenCXX/<wbr>debug-info-method.cpp Wed Sep 20 00:22:00 2017<br>
@@ -20,6 +20,7 @@ union {<br>
 class A {<br>
 protected:<br>
   void foo(int, A, decltype(u));<br>
+  void bar();<br>
 };<br>
<br>
 void A::foo(int, A, decltype(u)) {<br>
@@ -29,3 +30,5 @@ A a;<br>
<br>
 int A::*x = 0;<br>
 int (A::*y)(int) = 0;<br>
+<br>
+void A::bar() { foo(0, *this, u); }<br>
<br>
Modified: cfe/trunk/test/CodeGenCXX/<wbr>mangle-ms-cxx11.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-ms-cxx11.cpp?rev=313729&r1=313728&r2=313729&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/<wbr>CodeGenCXX/mangle-ms-cxx11.<wbr>cpp?rev=313729&r1=313728&r2=<wbr>313729&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/CodeGenCXX/<wbr>mangle-ms-cxx11.cpp (original)<br>
+++ cfe/trunk/test/CodeGenCXX/<wbr>mangle-ms-cxx11.cpp Wed Sep 20 00:22:00 2017<br>
@@ -160,6 +160,8 @@ struct { } a;<br>
 decltype(a) fun(decltype(a) x, decltype(a)) { return x; }<br>
 // CHECK-DAG: @"\01?fun@PR18022@@YA?AU<<wbr>unnamed-type-a>@1@U21@0@Z"<br>
<br>
+void use_fun() { fun(a, a); }<br>
+<br>
 }<br>
<br>
 inline int define_lambda() {<br>
@@ -280,7 +282,7 @@ void g() {<br>
<br>
 namespace PR18204 {<br>
 template <typename T><br>
-int f(T *);<br>
+int f(T *) { return 0; }<br>
 static union {<br>
   int n = f(this);<br>
 };<br>
@@ -346,4 +348,5 @@ int call_it = (A::default_args(), 1);<br>
<br>
 enum { enumerator };<br>
 void f(decltype(enumerator)) {}<br>
-// CHECK-DAG: define void @"\01?f@@YAXW4<unnamed-enum-<wbr>enumerator>@@@Z"(<br>
+// CHECK-DAG: define internal void @"\01?f@@YAXW4<unnamed-enum-<wbr>enumerator>@@@Z"(<br>
+void use_f() { f(enumerator); }<br>
<br>
Modified: cfe/trunk/test/CodeGenCXX/<wbr>mangle.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle.cpp?rev=313729&r1=313728&r2=313729&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/<wbr>CodeGenCXX/mangle.cpp?rev=<wbr>313729&r1=313728&r2=313729&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/CodeGenCXX/<wbr>mangle.cpp (original)<br>
+++ cfe/trunk/test/CodeGenCXX/<wbr>mangle.cpp Wed Sep 20 00:22:00 2017<br>
@@ -893,7 +893,8 @@ namespace test39 {<br>
     struct {} a;<br>
   } *foo;<br>
   template<typename T> void func(T) {}<br>
-  void test(foo x) {<br>
+  void test() {<br>
+    foo x;<br>
     func(x->a);<br>
   }<br>
 }<br>
<br>
Modified: cfe/trunk/test/PCH/<a href="http://cxx11-lambdas.mm" rel="noreferrer" target="_blank">cxx11-<wbr>lambdas.mm</a><br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx11-lambdas.mm?rev=313729&r1=313728&r2=313729&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/PCH/<wbr>cxx11-lambdas.mm?rev=313729&<wbr>r1=313728&r2=313729&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/PCH/<a href="http://cxx11-lambdas.mm" rel="noreferrer" target="_blank">cxx11-<wbr>lambdas.mm</a> (original)<br>
+++ cfe/trunk/test/PCH/<a href="http://cxx11-lambdas.mm" rel="noreferrer" target="_blank">cxx11-<wbr>lambdas.mm</a> Wed Sep 20 00:22:00 2017<br>
@@ -39,7 +39,7 @@ int init_capture(T t) {<br>
 }<br>
<br>
 struct X {<br>
-  template <typename T> X(T);<br>
+  template <typename T> X(T) {}<br>
 };<br>
 struct Y { Y(const X &x = [] {}); };<br>
<br>
<br>
Modified: cfe/trunk/test/SemaCXX/warn-<wbr>unreachable.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-unreachable.cpp?rev=313729&r1=313728&r2=313729&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/<wbr>SemaCXX/warn-unreachable.cpp?<wbr>rev=313729&r1=313728&r2=<wbr>313729&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/SemaCXX/warn-<wbr>unreachable.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/warn-<wbr>unreachable.cpp Wed Sep 20 00:22:00 2017<br>
@@ -49,22 +49,26 @@ void test3() {<br>
       (halt()); // expected-warning {{will never be executed}}<br>
 }<br>
<br>
-void test4() {<br>
+namespace Test4 {<br>
   struct S {<br>
     int mem;<br>
   } s;<br>
   S &foor();<br>
-  halt(), foor()// expected-warning {{will never be executed}}<br>
-    .mem;<br>
+  void test4() {<br>
+    halt(), foor()// expected-warning {{will never be executed}}<br>
+      .mem;<br>
+  }<br>
 }<br>
<br>
-void test5() {<br>
+namespace Test5 {<br>
   struct S {<br>
     int mem;<br>
   } s;<br>
   S &foonr() __attribute__((noreturn));<br>
-  foonr()<br>
-    .mem;       // expected-warning {{will never be executed}}<br>
+  void test5() {<br>
+    foonr()<br>
+      .mem;       // expected-warning {{will never be executed}}<br>
+  }<br>
 }<br>
<br>
 void test6() {<br>
<br>
<br>
______________________________<wbr>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>