[PATCH] D17362: [Sema] PR23090 Crash when return type or parameter types for extern "C" functions don't have external linkage
don hinton via cfe-commits
cfe-commits at lists.llvm.org
Sat Feb 20 14:39:54 PST 2016
hintonda updated this revision to Diff 48601.
hintonda added a comment.
Fixed additional tests.
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/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,7 @@
namespace { struct A {}; }
void test(A a); // expected-warning {{unused function}}
- extern "C" void test4(A a);
+ extern "C" void test4(A a); // expected-error {{'test4' has C-linkage specified, but parameter type 'test4::(anonymous namespace)::A' has internal linkage}}
}
namespace rdar8733476 {
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>;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D17362.48601.patch
Type: text/x-patch
Size: 3543 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160220/7a0fc3cb/attachment.bin>
More information about the cfe-commits
mailing list