[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