[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
Wed Feb 17 17:57:56 PST 2016
hintonda created this revision.
hintonda added reviewers: majnemer, rsmith.
hintonda added a subscriber: cfe-commits.
Added checks to make sure the return type and parameter types for functions
declared as extern "C" have external linkage.
http://reviews.llvm.org/D17362
Files:
include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDecl.cpp
test/Sema/pr23090-crash-on-invalid.cpp
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: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -8206,6 +8206,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
@@ -319,6 +319,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.48267.patch
Type: text/x-patch
Size: 2431 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160218/0d02cc95/attachment.bin>
More information about the cfe-commits
mailing list