[flang-commits] [flang] [flang] Fix ISO_Fortran_binding.h to work better with C++ code (PR #82556)

via flang-commits flang-commits at lists.llvm.org
Wed Feb 21 16:23:32 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-driver

Author: Pete Steinfeld (psteinfeld)

<details>
<summary>Changes</summary>

[flang] Fix ISO_Fortran_binding.h to work better with C++ code

This stems from working on LANL's "dopey" project -- https://github.com/lanl/dopey.

That project contains C++ code which includes the header file "ISO_Fortran_binding.h".  The dopey code  wraps that include with an 'extern "C"' clause since the standard (18.5.1, paragraph 1) says that the file" shall contain C structure definitions, typedef declarations, ...".  But the clang++ compiler emits error messages objecting to the fact that ISO_Fortran_binding.h contains templates.

This change fixes that by preceding the problematic code in ISO_Fortran_binding.h with language linkage clauses that specify that they contain C++ code rather than C code.

In the accompanying test, I needed to account for the fact that some people build the compiler by doing a `make check-flang`.  In this case, the clang compiler which is required by the test will not be built.

Here's an example of a C++ program that shows the problem:
```
  extern "C" {
  #include "ISO_Fortran_binding.h"
  }
  int main() {
    return 0;
  }
```

---
Full diff: https://github.com/llvm/llvm-project/pull/82556.diff


2 Files Affected:

- (modified) flang/include/flang/ISO_Fortran_binding.h (+4-4) 
- (added) flang/test/Driver/iso-fortran-binding.cpp (+32) 


``````````diff
diff --git a/flang/include/flang/ISO_Fortran_binding.h b/flang/include/flang/ISO_Fortran_binding.h
index 4a28d3322a38f0..3f74a7e56f1755 100644
--- a/flang/include/flang/ISO_Fortran_binding.h
+++ b/flang/include/flang/ISO_Fortran_binding.h
@@ -125,7 +125,7 @@ namespace cfi_internal {
 // The below structure emulates a flexible array. This structure does not take
 // care of getting the memory storage. Note that it already contains one element
 // because a struct cannot be empty.
-template <typename T> struct FlexibleArray : T {
+extern "C++" template <typename T> struct FlexibleArray : T {
   RT_API_ATTRS T &operator[](int index) { return *(this + index); }
   const RT_API_ATTRS T &operator[](int index) const { return *(this + index); }
   RT_API_ATTRS operator T *() { return this; }
@@ -163,12 +163,12 @@ typedef struct CFI_cdesc_t {
 // needed, for C++'s CFI_cdesc_t's emulated flexible
 // dim[] array.
 namespace cfi_internal {
-template <int r> struct CdescStorage : public CFI_cdesc_t {
+extern "C++" template <int r> struct CdescStorage : public CFI_cdesc_t {
   static_assert((r > 1 && r <= CFI_MAX_RANK), "CFI_INVALID_RANK");
   CFI_dim_t dim[r - 1];
 };
-template <> struct CdescStorage<1> : public CFI_cdesc_t {};
-template <> struct CdescStorage<0> : public CFI_cdesc_t {};
+extern "C++" template <> struct CdescStorage<1> : public CFI_cdesc_t {};
+extern "C++" template <> struct CdescStorage<0> : public CFI_cdesc_t {};
 } // namespace cfi_internal
 #define CFI_CDESC_T(rank) \
   FORTRAN_ISO_NAMESPACE_::cfi_internal::CdescStorage<rank>
diff --git a/flang/test/Driver/iso-fortran-binding.cpp b/flang/test/Driver/iso-fortran-binding.cpp
new file mode 100644
index 00000000000000..f977451c729f8a
--- /dev/null
+++ b/flang/test/Driver/iso-fortran-binding.cpp
@@ -0,0 +1,32 @@
+! UNSUPPORTED: system-windows
+! RUN: split-file %s %t
+! RUN: chmod +x %t/runtest.sh
+! RUN: %t/runtest.sh %t %t/cppfile.cpp %flang | FileCheck %s
+
+!--- cppfile.cpp
+extern "C" {
+#include "ISO_Fortran_binding.h"
+}
+#include<iostream>
+
+int main() {
+  std::cout << "PASS\n";
+  return 0;
+}
+
+// CHECK: PASS
+!--- runtest.sh
+#!/bin/bash
+TMPDIR=$1
+CPPFILE=$2
+FLANG=$3
+BINDIR=`dirname $FLANG`
+CPPCOMP=$BINDIR/clang++
+if [ -x $CCOMP ]
+then
+  $CPPCOMP $CPPFILE -o $TMPDIR/a.out
+  $TMPDIR/a.out # should print "PASS"
+else
+  # No clang compiler, just pass by default
+  echo "PASS"
+fi

``````````

</details>


https://github.com/llvm/llvm-project/pull/82556


More information about the flang-commits mailing list