diff --git a/configure b/configure
index 2fdad3c82f..2837eb6a74 100755
--- a/configure
+++ b/configure
@@ -150,24 +150,6 @@ add_to() {
     eval $1=\${$1:+\"\$$1 \"}\$2
 }
 
-update_cxxflags() {
-    # Set QEMU_CXXFLAGS from QEMU_CFLAGS by filtering out those
-    # options which some versions of GCC's C++ compiler complain about
-    # because they only make sense for C programs.
-    QEMU_CXXFLAGS="$QEMU_CXXFLAGS -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS"
-    CXXFLAGS=$(echo "$CFLAGS" | sed s/-std=gnu99/-std=gnu++11/)
-    for arg in $QEMU_CFLAGS; do
-        case $arg in
-            -Wstrict-prototypes|-Wmissing-prototypes|-Wnested-externs|\
-            -Wold-style-declaration|-Wold-style-definition|-Wredundant-decls)
-                ;;
-            *)
-                QEMU_CXXFLAGS=${QEMU_CXXFLAGS:+$QEMU_CXXFLAGS }$arg
-                ;;
-        esac
-    done
-}
-
 compile_object() {
   local_cflags="$1"
   do_cc $CFLAGS $QEMU_CFLAGS $local_cflags -c -o $TMPO $TMPC
@@ -6561,38 +6543,6 @@ if test "$cpu" = "s390x" ; then
   fi
 fi
 
-# Check that the C++ compiler exists and works with the C compiler.
-# All the QEMU_CXXFLAGS are based on QEMU_CFLAGS. Keep this at the end to don't miss any other that could be added.
-if has $cxx; then
-    cat > $TMPC <<EOF
-int c_function(void);
-int main(void) { return c_function(); }
-EOF
-
-    compile_object
-
-    cat > $TMPCXX <<EOF
-extern "C" {
-   int c_function(void);
-}
-int c_function(void) { return 42; }
-EOF
-
-    update_cxxflags
-
-    if do_cxx $CXXFLAGS $QEMU_CXXFLAGS -o $TMPE $TMPCXX $TMPO $QEMU_LDFLAGS; then
-        # C++ compiler $cxx works ok with C compiler $cc
-        :
-    else
-        echo "C++ compiler $cxx does not work with C compiler $cc"
-        echo "Disabling C++ specific optional code"
-        cxx=
-    fi
-else
-    echo "No C++ compiler available; disabling C++ specific optional code"
-    cxx=
-fi
-
 echo_version() {
     if test "$1" = "yes" ; then
         echo "($2)"
@@ -7523,7 +7473,6 @@ echo "NM=$nm" >> $config_host_mak
 echo "PKG_CONFIG=$pkg_config_exe" >> $config_host_mak
 echo "WINDRES=$windres" >> $config_host_mak
 echo "CFLAGS=$CFLAGS" >> $config_host_mak
-echo "CXXFLAGS=$CXXFLAGS" >> $config_host_mak
 echo "CFLAGS_NOPIE=$CFLAGS_NOPIE" >> $config_host_mak
 echo "QEMU_CFLAGS=$QEMU_CFLAGS" >> $config_host_mak
 echo "QEMU_CXXFLAGS=$QEMU_CXXFLAGS" >> $config_host_mak
@@ -8023,8 +7972,6 @@ meson_quote() {
 }
 
 echo "# Automatically generated by configure - do not modify" > $cross
-echo "[properties]" >> $cross
-test -z "$cxx" && echo "link_language = 'c'" >> $cross
 echo "[binaries]" >> $cross
 echo "c = $(meson_quote $cc)" >> $cross
 test -n "$cxx" && echo "cpp = $(meson_quote $cxx)" >> $cross
diff --git a/meson.build b/meson.build
index 84a3e610e7..a222a50a23 100644
--- a/meson.build
+++ b/meson.build
@@ -34,8 +34,6 @@ have_block = have_system or have_tools
 
 add_project_arguments(config_host['QEMU_CFLAGS'].split(),
                       native: false, language: ['c', 'objc'])
-add_project_arguments(config_host['QEMU_CXXFLAGS'].split(),
-                      native: false, language: 'cpp')
 add_project_link_arguments(config_host['QEMU_LDFLAGS'].split(),
                            native: false, language: ['c', 'cpp', 'objc'])
 add_project_arguments(config_host['QEMU_INCLUDES'].split(),
@@ -43,9 +41,31 @@ add_project_arguments(config_host['QEMU_INCLUDES'].split(),
 
 python = import('python').find_installation()
 
-link_language = meson.get_external_property('link_language', 'cpp')
-if link_language == 'cpp'
-  add_languages('cpp', required: true, native: false)
+##################
+# Compiler flags #
+##################
+
+link_language = 'c'
+if add_languages('cpp', required: false, native: false)
+  cxx = meson.get_compiler('cpp')
+  add_project_arguments('-D__STDC_LIMIT_MACROS', '-D__STDC_CONSTANT_MACROS',
+                        '-D__STDC_CONSTANT_MACROS',
+                        native: false, language: 'cpp')
+  foreach i : config_host['QEMU_CFLAGS'].split()
+    if i in [ '-Wstrict-prototypes', '-Wmissing-prototypes', '-Wnested-externs',
+              '-Wold-style-declaration', '-Wold-style-definition', '-Wredundant-decls' ]
+      # do nothing
+    elif i.startswith('-W')
+      add_project_arguments(cxx.get_supported_arguments(i), native: false, language: 'cpp')
+    else
+      add_project_arguments(i, native: false, language: 'cpp')
+    endif
+  endforeach
+  if cxx.links(files('scripts/empty.c'))
+    link_language = 'cpp'
+  else
+    warning('C++ compiler does not work with C compiler, disabling C++ code')
+  endif
 endif
 if host_machine.system() == 'darwin'
   add_languages('objc', required: false, native: false)
diff --git a/scripts/empty.c b/scripts/empty.c
new file mode 100644
index 0000000000..8f20b7e5f2
--- /dev/null
+++ b/scripts/empty.c
@@ -0,0 +1,6 @@
+/*
+ * An empty C file.  We need to make it a file and not include it
+ * in meson.build, so that we force it to compile with the C front-end
+ * and link with the C++ front-end.
+ */
+int main(void) { return 0; }
