This code crashes clang 3.6.1: namespace { extern "C" { struct G { }; G* f(int, int); } G* f(int, int); }
reduced a bit: namespace { struct G; extern "C" G *f(); G *f(); }
*** Bug 23484 has been marked as a duplicate of this bug. ***
In David's example, annotated below, #2 will assert/crash, which I now believe is correct behavior. #1 has ExternalLinkage and #2 has UniqueExternalLinkage which triggers the assert. namespace { Struct G; extern "C" G *f(); // #1 G *f(); // #2 } I believe the problem is actually with #1 which is invalid. Since the return type is declared within an unnamed namespace, it has UniqueExternalLinkage. However, extern "C" functions, no matter where they occur, have ExternalLinkage. I've looked, but can't find an appropriate error, but believe it should trigger at the end of Sema::CheckFunctionDeclaration() -- in the diff below, I've added an assert that demonstrates the logic. If I'm correct in my analysis, is there an existing error code I can use, or do I need to add one? diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index d26e5e1..5808e48 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -8613,6 +8613,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, // But, issue any diagnostic on the first declaration only. if (Previous.empty() && NewFD->isExternC()) { QualType R = NewFD->getReturnType(); + assert(R.getTypePtr()->getLinkage() == Linkage::ExternalLinkage); if (R->isIncompleteType() && !R->isVoidType()) Diag(NewFD->getLocation(), diag::warn_return_value_udt_incomplete) << NewFD << R;
We also need to check the linkage of the parameters -- PR23484.
Submitted patch: http://reviews.llvm.org/D17362