Repository: mesonbuild/meson

Issue:
c++ has_header_symbol doesn't work (at all?)
A couple of cases I tried when checking for the existence of a c++ symbol didn't seem to work correctly.

e.g. a basic check for the existence of 'int' in 'cstdio' fails with:

Command line:  ccache c++ /tmp/tmpvyiil7cr/testfile.cpp -O0 -c -o /tmp/tmpvyiil7cr/output.exe
Code:
# include <cstdio>

int main () { int; }
Compiler stdout:
/tmp/tmpvyiil7cr/testfile.cpp: In function ‘int main()’:
/tmp/tmpvyiil7cr/testfile.cpp:3:15: error: declaration does not declare anything [-fpermissive]
int main () { int; }
              ^~~

That's before we even start dealing with classes and templates ;)



Discussion:

Resolving patch:
diff --git a/mesonbuild/compilers.py b/mesonbuild/compilers.py
--- a/mesonbuild/compilers.py
+++ b/mesonbuild/compilers.py
@@ -512,6 +512,13 @@ def get_compile_only_args(self):
     def get_no_optimization_args(self):
         return ['-O0']
 
+    def get_compiler_check_args(self):
+        '''
+        Get arguments useful for compiler checks such as being permissive in
+        the code quality and not doing any optimization.
+        '''
+        return self.get_no_optimization_args()
+
     def get_output_args(self, target):
         return ['-o', target]
 
@@ -643,9 +650,14 @@ def has_header_symbol(self, hname, symbol, prefix, env, extra_args=None, depende
             extra_args = []
         templ = '''{2}
 #include <{0}>
-int main () {{ {1}; }}'''
-        # Pass -O0 to ensure that the symbol isn't optimized away
-        args = extra_args + self.get_no_optimization_args()
+int main () {{
+  /* If it's not defined as a macro, try to use as a symbol */
+  #ifndef {1}
+    {1};
+  #endif
+  return 0;
+}}'''
+        args = extra_args + self.get_compiler_check_args()
         return self.compiles(templ.format(hname, symbol, prefix), env, args, dependencies)
 
     @contextlib.contextmanager
@@ -784,7 +796,7 @@ def cross_sizeof(self, element, prefix, env, extra_args=None, dependencies=None)
 %s
 int temparray[%d-sizeof(%s)];
 '''
-        args = extra_args + self.get_no_optimization_args()
+        args = extra_args + self.get_compiler_check_args()
         if not self.compiles(element_exists_templ.format(prefix, element), env, args, dependencies):
             return -1
         for i in range(1, 1024):
@@ -833,7 +845,7 @@ def cross_alignment(self, typename, env, extra_args=None, dependencies=None):
 
 int testarray[%d-offsetof(struct tmp, target)];
 '''
-        args = extra_args + self.get_no_optimization_args()
+        args = extra_args + self.get_compiler_check_args()
         if not self.compiles(type_exists_templ.format(typename), env, args, dependencies):
             return -1
         for i in range(1, 1024):
@@ -918,7 +930,7 @@ def _have_prototype_templ():
         head = '#include <limits.h>\n{0}\n'
         # We don't know what the function takes or returns, so try to use it as
         # a function pointer
-        main = '\nint main() {{ int a = (int) &{1}; }}'
+        main = '\nint main() {{ void *a = (void*) &{1}; }}'
         return head, main
 
     def has_function(self, funcname, prefix, env, extra_args=None, dependencies=None):
@@ -967,9 +979,8 @@ def has_function(self, funcname, prefix, env, extra_args=None, dependencies=None
             head, main = self._no_prototype_templ()
         templ = head + stubs_fail + main
 
-        # Add -O0 to ensure that the symbol isn't optimized away by the compiler
-        args = extra_args + self.get_no_optimization_args()
-        if self.links(templ.format(prefix, funcname), env, extra_args, dependencies):
+        args = extra_args + self.get_compiler_check_args()
+        if self.links(templ.format(prefix, funcname), env, args, dependencies):
             return True
         # Some functions like alloca() are defined as compiler built-ins which
         # are inlined by the compiler, so test for that instead. Built-ins are
@@ -1048,6 +1059,20 @@ def sanity_check(self, work_dir, environment):
         code = 'class breakCCompiler;int main(int argc, char **argv) { return 0; }\n'
         return self.sanity_check_impl(work_dir, environment, 'sanitycheckcpp.cc', code)
 
+    def has_header_symbol(self, hname, symbol, prefix, env, extra_args=None, dependencies=None):
+        # Check if it's a C-like symbol
+        if super().has_header_symbol(hname, symbol, prefix, env, extra_args, dependencies):
+            return True
+        # Check if it's a class or a template
+        if extra_args is None:
+            extra_args = []
+        templ = '''{2}
+#include <{0}>
+using {1};
+int main () {{ return 0; }}'''
+        args = extra_args + self.get_compiler_check_args()
+        return self.compiles(templ.format(hname, symbol, prefix), env, args, dependencies)
+
 class ObjCCompiler(CCompiler):
     def __init__(self, exelist, version, is_cross, exe_wrap):
         self.language = 'objc'
@@ -1858,9 +1883,10 @@ def get_link_debugfile_args(self, targetfile):
         pdbarr += ['pdb']
         return ['/DEBUG', '/PDB:' + '.'.join(pdbarr)]
 
-class VisualStudioCPPCompiler(VisualStudioCCompiler):
+class VisualStudioCPPCompiler(VisualStudioCCompiler, CPPCompiler):
     def __init__(self, exelist, version, is_cross, exe_wrap):
         self.language = 'cpp'
+        CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
         VisualStudioCCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
         self.base_options = ['b_pch'] # FIXME add lto, pgo and the like
 
@@ -2035,6 +2061,12 @@ def get_option_link_args(self, options):
             return options['cpp_winlibs'].value
         return []
 
+    def get_compiler_check_args(self):
+        # -fpermissive allows non-conforming code to compile which is necessary
+        # for many C++ checks. Particularly, the has_header_symbol check is
+        # too strict without this and always fails.
+        return self.get_no_optimization_args() + ['-fpermissive']
+
 class GnuObjCCompiler(GnuCompiler,ObjCCompiler):
 
     def __init__(self, exelist, version, is_cross, exe_wrapper=None, defines=None):
@@ -2057,6 +2089,12 @@ def __init__(self, exelist, version, is_cross, exe_wrapper=None, defines=None):
                           '2': ['-Wall', '-Wextra', '-Winvalid-pch', '-Wnon-virtual-dtor'],
                           '3' : ['-Wall', '-Wpedantic', '-Wextra', '-Winvalid-pch', '-Wnon-virtual-dtor']}
 
+    def get_compiler_check_args(self):
+        # -fpermissive allows non-conforming code to compile which is necessary
+        # for many ObjC++ checks. Particularly, the has_header_symbol check is
+        # too strict without this and always fails.
+        return self.get_no_optimization_args() + ['-fpermissive']
+
 class ClangCompiler():
     def __init__(self, clang_type):
         self.id = 'clang'


Test patch:
diff --git a/test cases/common/111 has header symbol/meson.build b/test cases/common/111 has header symbol/meson.build
--- a/test cases/common/111 has header symbol/meson.build	
+++ b/test cases/common/111 has header symbol/meson.build	
@@ -1,18 +1,32 @@
-project('has header symbol', 'c')
+project('has header symbol', 'c', 'cpp')
 
 cc = meson.get_compiler('c')
+cpp = meson.get_compiler('cpp')
 
-assert (cc.has_header_symbol('stdio.h', 'int'), 'base types should always be available')
-assert (cc.has_header_symbol('stdio.h', 'printf'), 'printf function not found')
-assert (cc.has_header_symbol('stdio.h', 'FILE'), 'FILE structure not found')
-assert (cc.has_header_symbol('limits.h', 'INT_MAX'), 'INT_MAX define not found')
-assert (not cc.has_header_symbol('limits.h', 'guint64'), 'guint64 is not defined in limits.h')
-assert (not cc.has_header_symbol('stdlib.h', 'FILE'), 'FILE structure is defined in stdio.h, not stdlib.h')
-assert (not cc.has_header_symbol('stdlol.h', 'printf'), 'stdlol.h shouldn\'t exist')
-assert (not cc.has_header_symbol('stdlol.h', 'int'), 'shouldn\'t be able to find "int" with invalid header')
+foreach comp : [cc, cpp]
+  assert (comp.has_header_symbol('stdio.h', 'int'), 'base types should always be available')
+  assert (comp.has_header_symbol('stdio.h', 'printf'), 'printf function not found')
+  assert (comp.has_header_symbol('stdio.h', 'FILE'), 'FILE structure not found')
+  assert (comp.has_header_symbol('limits.h', 'INT_MAX'), 'INT_MAX define not found')
+  assert (not comp.has_header_symbol('limits.h', 'guint64'), 'guint64 is not defined in limits.h')
+  assert (not comp.has_header_symbol('stdlib.h', 'FILE'), 'FILE structure is defined in stdio.h, not stdlib.h')
+  assert (not comp.has_header_symbol('stdlol.h', 'printf'), 'stdlol.h shouldn\'t exist')
+  assert (not comp.has_header_symbol('stdlol.h', 'int'), 'shouldn\'t be able to find "int" with invalid header')
+endforeach
 
 # This is likely only available on Glibc, so just test for it
 if cc.has_function('ppoll')
   assert (not cc.has_header_symbol('poll.h', 'ppoll'), 'ppoll should not be accessible without _GNU_SOURCE')
   assert (cc.has_header_symbol('poll.h', 'ppoll', prefix : '#define _GNU_SOURCE'), 'ppoll should be accessible with _GNU_SOURCE')
 endif
+
+assert (cpp.has_header_symbol('iostream', 'std::iostream'), 'iostream not found in iostream.h')
+assert (cpp.has_header_symbol('vector', 'std::vector'), 'vector not found in vector.h')
+assert (not cpp.has_header_symbol('limits.h', 'std::iostream'), 'iostream should not be defined in limits.h')
+
+boost = dependency('boost', required : false)
+if boost.found()
+  assert (cpp.has_header_symbol('boost/math/quaternion.hpp', 'boost::math::quaternion', dependencies : boost), 'quaternion not found')
+else
+  assert (not cpp.has_header_symbol('boost/math/quaternion.hpp', 'boost::math::quaternion', dependencies : boost), 'quaternion found?!')
+endif
diff --git a/test cases/common/33 try compile/meson.build b/test cases/common/33 try compile/meson.build
--- a/test cases/common/33 try compile/meson.build	
+++ b/test cases/common/33 try compile/meson.build	
@@ -1,4 +1,4 @@
-project('try compile', 'c')
+project('try compile', 'c', 'cpp')
 
 code = '''#include<stdio.h>
 void func() { printf("Something.\n"); }
@@ -8,19 +8,20 @@ breakcode = '''#include<nonexisting.h>
 void func() { printf("This won't work.\n"); }
 '''
 
-compiler = meson.get_compiler('c')
-if compiler.compiles(code, name : 'should succeed') == false
-  error('Compiler is fail.')
-endif
+foreach compiler : [meson.get_compiler('c'), meson.get_compiler('cpp')]
+  if compiler.compiles(code, name : 'should succeed') == false
+    error('Compiler ' + compiler.get_id() + ' is fail.')
+  endif
 
-if compiler.compiles(files('valid.c'), name : 'should succeed') == false
-  error('Compiler is fail.')
-endif
+  if compiler.compiles(files('valid.c'), name : 'should succeed') == false
+    error('Compiler ' + compiler.get_id() + ' is fail.')
+  endif
 
-if compiler.compiles(breakcode, name : 'should fail')
-  error('Compiler returned true on broken code.')
-endif
+  if compiler.compiles(breakcode, name : 'should fail')
+    error('Compiler ' + compiler.get_id() + ' returned true on broken code.')
+  endif
 
-if compiler.compiles(files('invalid.c'), name : 'should fail')
-  error('Compiler returned true on broken code.')
-endif
+  if compiler.compiles(files('invalid.c'), name : 'should fail')
+    error('Compiler ' + compiler.get_id() + ' returned true on broken code.')
+  endif
+endforeach
diff --git a/test cases/common/35 sizeof/meson.build b/test cases/common/35 sizeof/meson.build
--- a/test cases/common/35 sizeof/meson.build	
+++ b/test cases/common/35 sizeof/meson.build	
@@ -1,13 +1,33 @@
-project('sizeof', 'c')
+project('sizeof', 'c', 'cpp')
 
+# Test with C
 cc = meson.get_compiler('c')
+
 intsize = cc.sizeof('int')
 wcharsize = cc.sizeof('wchar_t', prefix : '#include<wchar.h>')
 
 cd = configuration_data()
 cd.set('INTSIZE', intsize)
 cd.set('WCHARSIZE', wcharsize)
+cd.set('CONFIG', 'config.h')
 configure_file(input : 'config.h.in', output : 'config.h', configuration : cd)
+s = configure_file(input : 'prog.c.in', output : 'prog.c', configuration : cd)
 
-e = executable('prog', 'prog.c')
+e = executable('prog', s)
 test('sizeof test', e)
+
+# Test with C++
+cpp = meson.get_compiler('cpp')
+
+intsize = cpp.sizeof('int')
+wcharsize = cpp.sizeof('wchar_t', prefix : '#include<wchar.h>')
+
+cdpp = configuration_data()
+cdpp.set('INTSIZE', intsize)
+cdpp.set('WCHARSIZE', wcharsize)
+cdpp.set('CONFIG', 'config.hpp')
+configure_file(input : 'config.h.in', output : 'config.hpp', configuration : cdpp)
+spp = configure_file(input : 'prog.c.in', output : 'prog.cc', configuration : cdpp)
+
+epp = executable('progpp', spp)
+test('sizeof test c++', epp)
diff --git a/test cases/common/35 sizeof/prog.c b/test cases/common/35 sizeof/prog.c.in
similarity index 87%
rename from test cases/common/35 sizeof/prog.c
rename to test cases/common/35 sizeof/prog.c.in
--- a/test cases/common/35 sizeof/prog.c	
+++ b/test cases/common/35 sizeof/prog.c.in	
@@ -1,6 +1,6 @@
-#include"config.h"
-#include<stdio.h>
-#include<wchar.h>
+#include "@CONFIG@"
+#include <stdio.h>
+#include <wchar.h>
 
 int main(int argc, char **argv) {
     if(INTSIZE != sizeof(int)) {
diff --git a/test cases/common/37 has header/meson.build b/test cases/common/37 has header/meson.build
--- a/test cases/common/37 has header/meson.build	
+++ b/test cases/common/37 has header/meson.build	
@@ -1,11 +1,11 @@
-project('has header', 'c')
+project('has header', 'c', 'cpp')
 
-cc = meson.get_compiler('c')
+foreach comp : [meson.get_compiler('c'), meson.get_compiler('cpp')]
+  if comp.has_header('stdio.h') == false
+    error('Stdio missing.')
+  endif
 
-if cc.has_header('stdio.h') == false
-  error('Stdio missing.')
-endif
-
-if cc.has_header('ouagadougou.h')
-  error('Found non-existant header.')
-endif
+  if comp.has_header('ouagadougou.h')
+    error('Found non-existant header.')
+  endif
+endforeach
diff --git a/test cases/common/39 tryrun/meson.build b/test cases/common/39 tryrun/meson.build
--- a/test cases/common/39 tryrun/meson.build	
+++ b/test cases/common/39 tryrun/meson.build	
@@ -1,14 +1,14 @@
-project('tryrun', 'c')
+project('tryrun', 'c', 'cpp')
 
 # Complex to exercise all code paths.
 if meson.is_cross_build()
   if meson.has_exe_wrapper()
-    cc = meson.get_compiler('c', native : false)
+    compilers = [meson.get_compiler('c', native : false), meson.get_compiler('cpp', native : false)]
   else
-    cc = meson.get_compiler('c', native : true)
+    compilers = [meson.get_compiler('c', native : true), meson.get_compiler('cpp', native : true)]
   endif
 else
-  cc = meson.get_compiler('c')
+  compilers = [meson.get_compiler('c'), meson.get_compiler('cpp')]
 endif
 
 ok_code = '''#include<stdio.h>
@@ -32,45 +32,47 @@ INPUTS = [
   ['File', files('ok.c'), files('error.c'), files('no_compile.c')],
 ]
 
-foreach input : INPUTS
-  type = input[0]
-  ok = cc.run(input[1], name : type + ' should succeed')
-  err = cc.run(input[2], name : type + ' should fail')
-  noc = cc.run(input[3], name : type + ' does not compile')
+foreach cc : compilers
+  foreach input : INPUTS
+    type = input[0]
+    ok = cc.run(input[1], name : type + ' should succeed')
+    err = cc.run(input[2], name : type + ' should fail')
+    noc = cc.run(input[3], name : type + ' does not compile')
 
-  if noc.compiled()
-    error(type + ' compilation fail test failed.')
-  else
-    message(type + ' fail detected properly.')
-  endif
+    if noc.compiled()
+      error(type + ' compilation fail test failed.')
+    else
+      message(type + ' fail detected properly.')
+    endif
 
-  if ok.compiled()
-    message(type + ' compilation worked.')
-  else
-    error(type + ' compilation did not work.')
-  endif
+    if ok.compiled()
+      message(type + ' compilation worked.')
+    else
+      error(type + ' compilation did not work.')
+    endif
 
-  if ok.returncode() == 0
-    message(type + ' return code ok.')
-  else
-    error(type + ' return code fail')
-  endif
+    if ok.returncode() == 0
+      message(type + ' return code ok.')
+    else
+      error(type + ' return code fail')
+    endif
 
-  if err.returncode() == 1
-    message(type + ' bad return code ok.')
-  else
-    error(type + ' bad return code fail.')
-  endif
+    if err.returncode() == 1
+      message(type + ' bad return code ok.')
+    else
+      error(type + ' bad return code fail.')
+    endif
 
-  if ok.stdout().strip() == 'stdout'
-    message(type + ' stdout ok.')
-  else
-    message(type + ' bad stdout.')
-  endif
+    if ok.stdout().strip() == 'stdout'
+      message(type + ' stdout ok.')
+    else
+      message(type + ' bad stdout.')
+    endif
 
-  if ok.stderr().strip() == 'stderr'
-    message(type + ' stderr ok.')
-  else
-    message(type + ' bad stderr.')
-  endif
+    if ok.stderr().strip() == 'stderr'
+      message(type + ' stderr ok.')
+    else
+      message(type + ' bad stderr.')
+    endif
+  endforeach
 endforeach
diff --git a/test cases/common/43 has function/meson.build b/test cases/common/43 has function/meson.build
--- a/test cases/common/43 has function/meson.build	
+++ b/test cases/common/43 has function/meson.build	
@@ -1,41 +1,43 @@
-project('has function', 'c')
+project('has function', 'c', 'cpp')
 
-cc = meson.get_compiler('c')
+compilers = [meson.get_compiler('c'), meson.get_compiler('cpp')]
 
-if not cc.has_function('printf', prefix : '#include<stdio.h>')
-  error('"printf" function not found (should always exist).')
-endif
+foreach cc : compilers
+  if not cc.has_function('printf', prefix : '#include<stdio.h>')
+    error('"printf" function not found (should always exist).')
+  endif
 
-# Should also be able to detect it without specifying the header
-# We check for a different function here to make sure the result is
-# not taken from a cache (ie. the check above)
-# On MSVC fprintf is defined as an inline function in the header, so it cannot
-# be found without the include.
-if cc.get_id() != 'msvc'
-  assert(cc.has_function('fprintf'), '"fprintf" function not found without include (on !msvc).')
-else
-  assert(cc.has_function('fprintf', prefix : '#include <stdio.h>'), '"fprintf" function not found with include (on msvc).')
-endif
+  # Should also be able to detect it without specifying the header
+  # We check for a different function here to make sure the result is
+  # not taken from a cache (ie. the check above)
+  # On MSVC fprintf is defined as an inline function in the header, so it cannot
+  # be found without the include.
+  if cc.get_id() != 'msvc'
+    assert(cc.has_function('fprintf'), '"fprintf" function not found without include (on !msvc).')
+  else
+    assert(cc.has_function('fprintf', prefix : '#include <stdio.h>'), '"fprintf" function not found with include (on msvc).')
+  endif
 
-if cc.has_function('hfkerhisadf', prefix : '#include<stdio.h>')
-  error('Found non-existent function "hfkerhisadf".')
-endif
+  if cc.has_function('hfkerhisadf', prefix : '#include<stdio.h>')
+    error('Found non-existent function "hfkerhisadf".')
+  endif
 
-# With glibc on Linux lchmod is a stub that will always return an error,
-# we want to detect that and declare that the function is not available.
-# We can't check for the C library used here of course, but if it's not
-# implemented in glibc it's probably not implemented in any other 'slimmer'
-# C library variants either, so the check should be safe either way hopefully.
-if host_machine.system() == 'linux' and cc.get_id() == 'gcc'
-  assert (cc.has_function('poll', prefix : '#include <poll.h>'), 'couldn\'t detect "poll" when defined by a header')
-  assert (not cc.has_function('lchmod', prefix : '''#include <sys/stat.h>
-                                                    #include <unistd.h>'''), '"lchmod" check should have failed')
-endif
+  # With glibc on Linux lchmod is a stub that will always return an error,
+  # we want to detect that and declare that the function is not available.
+  # We can't check for the C library used here of course, but if it's not
+  # implemented in glibc it's probably not implemented in any other 'slimmer'
+  # C library variants either, so the check should be safe either way hopefully.
+  if host_machine.system() == 'linux' and cc.get_id() == 'gcc'
+    assert (cc.has_function('poll', prefix : '#include <poll.h>'), 'couldn\'t detect "poll" when defined by a header')
+    assert (not cc.has_function('lchmod', prefix : '''#include <sys/stat.h>
+                                                      #include <unistd.h>'''), '"lchmod" check should have failed')
+  endif
 
-# For some functions one needs to define _GNU_SOURCE before including the
-# right headers to get them picked up. Make sure we can detect these functions
-# as well without any prefix
-if cc.has_header_symbol('sys/socket.h', 'recvmmsg', prefix : '#define _GNU_SOURCE')
-  # We assume that if recvmmsg exists sendmmsg does too
-  assert (cc.has_function('sendmmsg'), 'Failed to detect function "sendmmsg" (should always exist).')
-endif
+  # For some functions one needs to define _GNU_SOURCE before including the
+  # right headers to get them picked up. Make sure we can detect these functions
+  # as well without any prefix
+  if cc.has_header_symbol('sys/socket.h', 'recvmmsg', prefix : '#define _GNU_SOURCE')
+    # We assume that if recvmmsg exists sendmmsg does too
+    assert (cc.has_function('sendmmsg'), 'Failed to detect function "sendmmsg" (should always exist).')
+  endif
+endforeach
diff --git a/test cases/common/44 has member/meson.build b/test cases/common/44 has member/meson.build
--- a/test cases/common/44 has member/meson.build	
+++ b/test cases/common/44 has member/meson.build	
@@ -1,19 +1,21 @@
-project('has member', 'c')
+project('has member', 'c', 'cpp')
 
-cc = meson.get_compiler('c')
+compilers = [meson.get_compiler('c'), meson.get_compiler('cpp')]
 
-if not cc.has_member('struct tm', 'tm_sec', prefix : '#include<time.h>')
-  error('Did not detect member of "struct tm" that exists: "tm_sec"')
-endif
+foreach cc : compilers
+  if not cc.has_member('struct tm', 'tm_sec', prefix : '#include<time.h>')
+    error('Did not detect member of "struct tm" that exists: "tm_sec"')
+  endif
 
-if cc.has_member('struct tm', 'tm_nonexistent', prefix : '#include<time.h>')
-  error('Not existing member "tm_nonexistent" found.')
-endif
+  if cc.has_member('struct tm', 'tm_nonexistent', prefix : '#include<time.h>')
+    error('Not existing member "tm_nonexistent" found.')
+  endif
 
-if not cc.has_members('struct tm', 'tm_sec', 'tm_min', prefix : '#include<time.h>')
-  error('Did not detect members of "struct tm" that exist: "tm_sec" "tm_min"')
-endif
+  if not cc.has_members('struct tm', 'tm_sec', 'tm_min', prefix : '#include<time.h>')
+    error('Did not detect members of "struct tm" that exist: "tm_sec" "tm_min"')
+  endif
 
-if cc.has_members('struct tm', 'tm_sec', 'tm_nonexistent2', prefix : '#include<time.h>')
-  error('Not existing member "tm_nonexistent2" found.')
-endif
+  if cc.has_members('struct tm', 'tm_sec', 'tm_nonexistent2', prefix : '#include<time.h>')
+    error('Not existing member "tm_nonexistent2" found.')
+  endif
+endforeach
diff --git a/test cases/common/45 alignment/meson.build b/test cases/common/45 alignment/meson.build
--- a/test cases/common/45 alignment/meson.build	
+++ b/test cases/common/45 alignment/meson.build	
@@ -1,29 +1,31 @@
-project('alignment', 'c')
+project('alignment', 'c', 'cpp')
 
-cc = meson.get_compiler('c')
+compilers = [meson.get_compiler('c'), meson.get_compiler('cpp')]
 
-# These tests should return the same value on all
-# platforms. If (and when) they don't, fix 'em up.
-if cc.alignment('char') != 1
-  error('Alignment of char misdetected.')
-endif
+foreach cc : compilers
+  # These tests should return the same value on all
+  # platforms. If (and when) they don't, fix 'em up.
+  if cc.alignment('char') != 1
+    error('Alignment of char misdetected.')
+  endif
 
-ptr_size = cc.sizeof('void*')
-dbl_alignment = cc.alignment('double')
+  ptr_size = cc.sizeof('void*')
+  dbl_alignment = cc.alignment('double')
 
-# These tests are not thorough. Doing this properly
-# would take a lot of work because it is strongly
-# platform  and compiler dependent. So just check
-# that they produce something fairly sane.
+  # These tests are not thorough. Doing this properly
+  # would take a lot of work because it is strongly
+  # platform  and compiler dependent. So just check
+  # that they produce something fairly sane.
 
-if ptr_size == 8 or ptr_size == 4
-  message('Size of ptr ok.')
-else
-  error('Size of ptr misdetected.')
-endif
+  if ptr_size == 8 or ptr_size == 4
+    message('Size of ptr ok.')
+  else
+    error('Size of ptr misdetected.')
+  endif
 
-if dbl_alignment == 8 or dbl_alignment == 4
-  message('Alignment of double ok.')
-else
-  error('Alignment of double misdetected.')
-endif
+  if dbl_alignment == 8 or dbl_alignment == 4
+    message('Alignment of double ok.')
+  else
+    error('Alignment of double misdetected.')
+  endif
+endforeach
diff --git a/test cases/common/83 has type/meson.build b/test cases/common/83 has type/meson.build
--- a/test cases/common/83 has type/meson.build	
+++ b/test cases/common/83 has type/meson.build	
@@ -1,11 +1,13 @@
-project('has type', 'c')
+project('has type', 'c', 'cpp')
 
-cc = meson.get_compiler('c')
+compilers = [meson.get_compiler('c'), meson.get_compiler('cpp')]
 
-if not cc.has_type('time_t', prefix : '#include<time.h>')
-  error('Did not detect type that exists.')
-endif
+foreach cc : compilers
+  if not cc.has_type('time_t', prefix : '#include<time.h>')
+    error('Did not detect type that exists.')
+  endif
 
-if cc.has_type('no_time_t', prefix : '#include<time.h>')
-  error('Not existing type found.')
-endif
+  if cc.has_type('no_time_t', prefix : '#include<time.h>')
+    error('Not existing type found.')
+  endif
+endforeach