LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 23090 - Crash with extern "C" in anonymous namespace
Summary: Crash with extern "C" in anonymous namespace
Status: CONFIRMED
Alias: None
Product: clang
Classification: Unclassified
Component: C++ (show other bugs)
Version: 3.6
Hardware: All All
: P normal
Assignee: Don Hinton
URL:
Keywords:
: 23484 (view as bug list)
Depends on:
Blocks:
 
Reported: 2015-03-31 17:06 PDT by Hyman Rosen
Modified: 2016-02-17 19:54 PST (History)
7 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Hyman Rosen 2015-03-31 17:06:32 PDT

    
Comment 1 Hyman Rosen 2015-03-31 17:07:49 PDT
This code crashes clang 3.6.1:

namespace {
    extern "C" { struct G { }; G* f(int, int); }
                               G* f(int, int);
}
Comment 2 David Majnemer 2015-03-31 19:20:11 PDT
reduced a bit:
namespace {
struct G;
extern "C" G *f();
G *f();
}
Comment 3 Don Hinton 2016-02-15 15:51:43 PST
*** Bug 23484 has been marked as a duplicate of this bug. ***
Comment 4 Don Hinton 2016-02-16 20:44:32 PST
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;
Comment 5 Don Hinton 2016-02-16 21:27:14 PST
We also need to check the linkage of the parameters -- PR23484.
Comment 6 Don Hinton 2016-02-17 19:54:50 PST
Submitted patch: http://reviews.llvm.org/D17362