hintonda updated this revision to Diff 48617.
hintonda added a comment.
- Fix remaining test failures caused by linkage errors.
http://reviews.llvm.org/D17362
Files:
include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDecl.cpp
test/CXX/drs/dr3xx.cpp
test/Sema/pr23090-crash-on-invalid.cpp
test/SemaCXX/linkage.cpp
test/SemaCXX/warn-unused-filescoped.cpp
Index: test/SemaCXX/warn-unused-filescoped.cpp
===================================================================
--- test/SemaCXX/warn-unused-filescoped.cpp
+++ test/SemaCXX/warn-unused-filescoped.cpp
@@ -121,7 +121,6 @@
namespace { struct A {}; }
void test(A a); // expected-warning {{unused function}}
- extern "C" void test4(A a);
}
namespace rdar8733476 {
Index: test/SemaCXX/linkage.cpp
===================================================================
--- test/SemaCXX/linkage.cpp
+++ test/SemaCXX/linkage.cpp
@@ -57,43 +57,21 @@
namespace test3 {
namespace { struct A {}; }
+ struct B {};
// CHECK: define internal void @_ZN5test34testENS_12_GLOBAL__N_11AE(
void test(A a) {}
void force() { test(A()); }
// CHECK: define void @test3(
- extern "C" void test3(A a) {}
+ extern "C" void test3(B b) {}
}
namespace {
// CHECK: define void @test4(
extern "C" void test4(void) {}
}
-// PR9316: Ensure that even non-namespace-scope function declarations in
-// a C declaration context respect that over the anonymous namespace.
-extern "C" {
- namespace {
- struct X {
- int f() {
- extern int g();
- extern int a;
-
- // Test both for mangling in the code generation and warnings from use
- // of internal, undefined names via -Werror.
- // CHECK: call i32 @g(
- // CHECK: load i32, i32* @a,
- return g() + a;
- }
- };
- }
- // Force the above function to be emitted by codegen.
- int test(X& x) {
- return x.f();
- }
-}
-
// CHECK: define linkonce_odr i8* @_ZN5test11A3fooILj0EEEPvv(
// CHECK: define linkonce_odr i8* @_ZN5test21A1BILj0EE3fooEv(
Index: test/Sema/pr23090-crash-on-invalid.cpp
===================================================================
--- /dev/null
+++ test/Sema/pr23090-crash-on-invalid.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// Don't crash (PR23090).
+
+namespace {
+
+// check return type
+struct A;
+extern "C" A *foo(); // expected-error {{'foo' has C-linkage specified, but return type '(anonymous namespace)::A *' has internal linkage}}
+A *foo();
+
+// check parameter
+struct B;
+extern "C" void bar(B*); // expected-error {{'bar' has C-linkage specified, but parameter type '(anonymous namespace)::B *' has internal linkage}}
+void bar(B*);
+
+}
Index: test/CXX/drs/dr3xx.cpp
===================================================================
--- test/CXX/drs/dr3xx.cpp
+++ test/CXX/drs/dr3xx.cpp
@@ -232,8 +232,8 @@
typedef struct {
int i;
} *ps;
- extern "C" void f(ps);
- void g(ps); // FIXME: ill-formed, type 'ps' has no linkage
+ extern "C" void f(ps); // expected-error-re {{'f' has C-linkage specified, but parameter type 'ps' (aka 'dr319::(anonymous struct {{.*}} *') has internal linkage}}
+ void g(ps);
static enum { e } a1;
enum { e2 } a2; // FIXME: ill-formed, enum type has no linkage
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -8218,6 +8218,25 @@
Diag(NewFD->getLocation(), diag::ext_out_of_line_declaration)
<< D.getCXXScopeSpec().getRange();
}
+
+ if (NewFD->isExternC()) {
+ // Check return type linkage
+ QualType R = NewFD->getReturnType();
+ if (R.getTypePtr()->getLinkage() != Linkage::ExternalLinkage) {
+ Diag(NewFD->getLocation(), diag::err_return_value_linkage)
+ << NewFD << R;
+ NewFD->setInvalidDecl();
+ }
+ // Check parameter type linkage
+ for (auto param : NewFD->parameters()) {
+ QualType P = param->getOriginalType();
+ if (P.getTypePtr()->getLinkage() != Linkage::ExternalLinkage) {
+ Diag(NewFD->getLocation(), diag::err_parameter_value_linkage)
+ << NewFD << P;
+ NewFD->setInvalidDecl();
+ }
+ }
+ }
}
ProcessPragmaWeak(S, NewFD);
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -325,6 +325,11 @@
def warn_unused_private_field: Warning<"private field %0 is not used">,
InGroup<UnusedPrivateField>, DefaultIgnore;
+def err_return_value_linkage: Error<
+ "%0 has C-linkage specified, but return type %1 has internal linkage">;
+def err_parameter_value_linkage: Error<
+ "%0 has C-linkage specified, but parameter type %1 has internal linkage">;
+
def warn_parameter_size: Warning<
"%0 is a large (%1 bytes) pass-by-value argument; "
"pass it by reference instead ?">, InGroup<LargeByValueCopy>;
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits