<div dir="ltr">Hi Richard,<div><br></div><div>This commit has caused a second regression in Clang which triggers a new invalid -Wunused-function warning. I filed <a href="https://bugs.llvm.org/show_bug.cgi?id=36584">https://bugs.llvm.org/show_bug.cgi?id=36584</a> which contains the minimized test case for this issue. Do you mind taking a look at it?</div><div><br></div><div>Thanks,</div><div>Alex</div></div><div class="gmail_extra"><br><div class="gmail_quote">On 19 December 2017 at 11:14, Alex L <span dir="ltr"><<a href="mailto:arphaman@gmail.com" target="_blank">arphaman@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><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" target="_blank">https://bugs.llvm.org/<wbr>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="HOEnZb"><div class="h5"><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-pr<wbr>oject?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/basic<wbr>.link/p8.cpp<br>
Modified:<br>
cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td<br>
cfe/trunk/include/clang/Sema/S<wbr>ema.h<br>
cfe/trunk/include/clang/Sema/S<wbr>emaInternal.h<br>
cfe/trunk/lib/AST/Decl.cpp<br>
cfe/trunk/lib/Sema/Sema.cpp<br>
cfe/trunk/lib/Sema/SemaDecl.cp<wbr>p<br>
cfe/trunk/lib/Sema/SemaExpr.cp<wbr>p<br>
cfe/trunk/test/Analysis/<a href="http://malloc.mm" rel="noreferrer" target="_blank">malloc<wbr>.mm</a><br>
cfe/trunk/test/Analysis/refere<wbr>nce.cpp<br>
cfe/trunk/test/CodeGenCXX/debu<wbr>g-info-method.cpp<br>
cfe/trunk/test/CodeGenCXX/mang<wbr>le-ms-cxx11.cpp<br>
cfe/trunk/test/CodeGenCXX/mang<wbr>le.cpp<br>
cfe/trunk/test/PCH/<a href="http://cxx11-lambdas.mm" rel="noreferrer" target="_blank">cxx11-lambd<wbr>as.mm</a><br>
cfe/trunk/test/SemaCXX/warn-un<wbr>reachable.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-pr<wbr>oject/cfe/trunk/include/clang/<wbr>Basic/DiagnosticSemaKinds.td?<wbr>rev=313729&r1=313728&r2=<wbr>313729&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-i<wbr>nternal-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/S<wbr>ema.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-pr<wbr>oject/cfe/trunk/include/clang/<wbr>Sema/Sema.h?rev=313729&r1=<wbr>313728&r2=313729&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/Sema/S<wbr>ema.h (original)<br>
+++ cfe/trunk/include/clang/Sema/S<wbr>ema.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(Va<wbr>lueDecl *VD);<br>
+<br>
/// Obtain a sorted list of functions that are undefined but ODR-used.<br>
void getUndefinedButUsed(<br>
SmallVectorImpl<std::pair<Nam<wbr>edDecl *, SourceLocation> > &Undefined);<br>
<br>
Modified: cfe/trunk/include/clang/Sema/S<wbr>emaInternal.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-pr<wbr>oject/cfe/trunk/include/clang/<wbr>Sema/SemaInternal.h?rev=313729<wbr>&r1=313728&r2=313729&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/Sema/S<wbr>emaInternal.h (original)<br>
+++ cfe/trunk/include/clang/Sema/S<wbr>emaInternal.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.Co<wbr>ntext) == VarDecl::DeclarationOnly &&<br>
- (!Var->isExternallyVisible() || Var->isInline()) &&<br>
+ (!Var->isExternallyVisible() || Var->isInline() ||<br>
+ SemaRef.isExternalWithNoLinka<wbr>geType(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-pr<wbr>oject/cfe/trunk/lib/AST/Decl.<wbr>cpp?rev=313729&r1=313728&r2=<wbr>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::getLVForNames<wbr>paceScopeD<br>
// because of this, but unique-external linkage suits us.<br>
if (Context.getLangOpts().CPlusPl<wbr>us && !isFirstInExternCContext(Var)) {<br>
LinkageInfo TypeLV = getLVForType(*Var->getType(), computation);<br>
- if (TypeLV.getLinkage() != ExternalLinkage &&<br>
- TypeLV.getLinkage() != ModuleLinkage)<br>
+ if (!isExternallyVisible(TypeLV.g<wbr>etLinkage()))<br>
return LinkageInfo::uniqueExternal();<br>
if (!LV.isVisibilityExplicit())<br>
LV.mergeVisibility(TypeLV);<br>
@@ -772,7 +771,7 @@ LinkageComputer::getLVForNames<wbr>paceScopeD<br>
QualType TypeAsWritten = Function->getType();<br>
if (TypeSourceInfo *TSI = Function->getTypeSourceInfo())<br>
TypeAsWritten = TSI->getType();<br>
- if (TypeAsWritten->getLinkage() == UniqueExternalLinkage)<br>
+ if (!isExternallyVisible(TypeAsWr<wbr>itten->getLinkage()))<br>
return LinkageInfo::uniqueExternal();<br>
}<br>
<br>
@@ -909,7 +908,7 @@ LinkageComputer::getLVForClass<wbr>Member(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::getLVForClass<wbr>Member(con<br>
QualType TypeAsWritten = MD->getType();<br>
if (TypeSourceInfo *TSI = MD->getTypeSourceInfo())<br>
TypeAsWritten = TSI->getType();<br>
- if (TypeAsWritten->getLinkage() == UniqueExternalLinkage)<br>
+ if (!isExternallyVisible(TypeAsWr<wbr>itten->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-pr<wbr>oject/cfe/trunk/lib/Sema/Sema.<wbr>cpp?rev=313729&r1=313728&r2=<wbr>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(Nam<wbr>edDecl *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::isExternalWithNoLinkageT<wbr>ype(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(V<wbr>D);<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>(ND<wbr>))<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(F<wbr>D) &&<br>
!FD->getMostRecentDecl()->isI<wbr>nlined())<br>
continue;<br>
} else {<br>
auto *VD = cast<VarDecl>(ND);<br>
if (VD->hasDefinition() != VarDecl::DeclarationOnly)<br>
continue;<br>
- if (VD->isExternallyVisible() && !VD->getMostRecentDecl()->isIn<wbr>line())<br>
+ if (VD->isExternallyVisible() &&<br>
+ !isExternalWithNoLinkageType(V<wbr>D) &&<br>
+ !VD->getMostRecentDecl()->isIn<wbr>line())<br>
continue;<br>
}<br>
<br>
@@ -626,33 +653,43 @@ static void checkUndefinedButUsed(Sema &<br>
S.getUndefinedButUsed(Undefin<wbr>ed);<br>
if (Undefined.empty()) return;<br>
<br>
- for (SmallVectorImpl<std::pair<Nam<wbr>edDecl *, 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.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->getTyp<wbr>e()->getLinkage())<br>
+ ? diag::ext_undefined_internal_t<wbr>ype<br>
+ : diag::err_undefined_internal_t<wbr>ype)<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)->getM<wbr>ostRecentDecl()->isInline() &&<br>
+ assert(cast<VarDecl>(VD)->getM<wbr>ostRecentDecl()->isInline() &&<br>
"used var requires definition but isn't inline or internal?");<br>
- S.Diag(ND->getLocation(), diag::err_undefined_inline_var<wbr>) << ND;<br>
+ S.Diag(VD->getLocation(), diag::err_undefined_inline_var<wbr>) << 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.cp<wbr>p<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-pr<wbr>oject/cfe/trunk/lib/Sema/SemaD<wbr>ecl.cpp?rev=313729&r1=313728&<wbr>r2=313729&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/SemaDecl.cp<wbr>p (original)<br>
+++ cfe/trunk/lib/Sema/SemaDecl.cp<wbr>p 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->isThisDeclarationADefini<wbr>tion())<br>
@@ -12329,18 +12329,6 @@ Decl *Sema::ActOnFinishFunctionBody<wbr>(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()->hasA<wbr>ttr<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.cp<wbr>p<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-pr<wbr>oject/cfe/trunk/lib/Sema/SemaE<wbr>xpr.cpp?rev=313729&r1=313728&<wbr>r2=313729&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/SemaExpr.cp<wbr>p (original)<br>
+++ cfe/trunk/lib/Sema/SemaExpr.cp<wbr>p Wed Sep 20 00:22:00 2017<br>
@@ -13897,6 +13897,8 @@ void Sema::MarkFunctionReferenced(S<wbr>ource<br>
!LangOpts.GNUInline &&<br>
!Func->getMostRecentDecl()->ha<wbr>sAttr<GNUInlineAttr>())<br>
UndefinedButUsed.insert(std::<wbr>make_pair(Func->getCanonicalDe<wbr>cl(), Loc));<br>
+ else if (isExternalWithNoLinkageType(F<wbr>unc))<br>
+ UndefinedButUsed.insert(std::m<wbr>ake_pair(Func->getCanonicalDec<wbr>l(), 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-pr<wbr>oject/cfe/trunk/test/Analysis/<wbr>malloc.mm?rev=313729&r1=<wbr>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/refere<wbr>nce.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-pr<wbr>oject/cfe/trunk/test/Analysis/<wbr>reference.cpp?rev=313729&r1=<wbr>313728&r2=313729&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/Analysis/refere<wbr>nce.cpp (original)<br>
+++ cfe/trunk/test/Analysis/refere<wbr>nce.cpp Wed Sep 20 00:22:00 2017<br>
@@ -117,6 +117,11 @@ void testRetroactiveNullReference(i<wbr>nt *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/basic<wbr>.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-pr<wbr>oject/cfe/trunk/test/CXX/basic<wbr>/basic.link/p8.cpp?rev=313729&<wbr>view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/CXX/basic/basic<wbr>.link/p8.cpp (added)<br>
+++ cfe/trunk/test/CXX/basic/basic<wbr>.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/debu<wbr>g-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-pr<wbr>oject/cfe/trunk/test/CodeGenCX<wbr>X/debug-info-method.cpp?rev=<wbr>313729&r1=313728&r2=313729&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/CodeGenCXX/debu<wbr>g-info-method.cpp (original)<br>
+++ cfe/trunk/test/CodeGenCXX/debu<wbr>g-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/mang<wbr>le-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-pr<wbr>oject/cfe/trunk/test/CodeGenCX<wbr>X/mangle-ms-cxx11.cpp?rev=<wbr>313729&r1=313728&r2=313729&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/CodeGenCXX/mang<wbr>le-ms-cxx11.cpp (original)<br>
+++ cfe/trunk/test/CodeGenCXX/mang<wbr>le-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<unnam<wbr>ed-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-en<wbr>umerator>@@@Z"(<br>
+// CHECK-DAG: define internal void @"\01?f@@YAXW4<unnamed-enum-en<wbr>umerator>@@@Z"(<br>
+void use_f() { f(enumerator); }<br>
<br>
Modified: cfe/trunk/test/CodeGenCXX/mang<wbr>le.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-pr<wbr>oject/cfe/trunk/test/CodeGenCX<wbr>X/mangle.cpp?rev=313729&r1=<wbr>313728&r2=313729&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/CodeGenCXX/mang<wbr>le.cpp (original)<br>
+++ cfe/trunk/test/CodeGenCXX/mang<wbr>le.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-lambd<wbr>as.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-pr<wbr>oject/cfe/trunk/test/PCH/cxx11<wbr>-lambdas.mm?rev=313729&r1=<wbr>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-lambd<wbr>as.mm</a> (original)<br>
+++ cfe/trunk/test/PCH/<a href="http://cxx11-lambdas.mm" rel="noreferrer" target="_blank">cxx11-lambd<wbr>as.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-un<wbr>reachable.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-pr<wbr>oject/cfe/trunk/test/SemaCXX/<wbr>warn-unreachable.cpp?rev=<wbr>313729&r1=313728&r2=313729&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/SemaCXX/warn-un<wbr>reachable.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/warn-un<wbr>reachable.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" target="_blank">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>
</div></div></blockquote></div><br></div>