ソースを参照

Merge topic 'ci-asan'

20bc209a0c gitlab-ci: add clang asan job
19d831b03d ci: add compiler-rt to Fedora base image
fda060f030 LexerParser: Do not leak Fortran parser tokens discarded due to errors

Acked-by: Kitware Robot <[email protected]>
Acked-by: Ben Boeckel <[email protected]>
Merge-request: !6200
Brad King 4 年 前
コミット
1d225c5c0c

+ 25 - 0
.gitlab-ci.yml

@@ -498,6 +498,31 @@ upload:linux-aarch64-package:
     variables:
         RSYNC_DESTINATION: dev
 
+## Sanitizer builds
+
+build:fedora34-asan:
+    extends:
+        - .fedora34_asan
+        - .cmake_build_linux
+        - .cmake_build_artifacts
+        - .linux_builder_tags_qt
+        - .run_manually
+    variables:
+        CMAKE_CI_JOB_NIGHTLY: "true"
+
+test:fedora34-asan:
+    extends:
+        - .fedora34_asan
+        - .cmake_memcheck_linux
+        - .linux_builder_tags_qt
+        - .run_automatically
+    dependencies:
+        - build:fedora34-asan
+    needs:
+        - build:fedora34-asan
+    variables:
+        CMAKE_CI_JOB_NIGHTLY: "true"
+
 # macOS builds
 
 build:macos-x86_64-ninja:

+ 4 - 0
.gitlab/ci/configure_fedora34_asan.cmake

@@ -0,0 +1,4 @@
+set(CMAKE_C_FLAGS "-fsanitize=address" CACHE STRING "")
+set(CMAKE_CXX_FLAGS "-fsanitize=address" CACHE STRING "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora34_common.cmake")

+ 7 - 0
.gitlab/ci/ctest_exclusions.cmake

@@ -13,6 +13,13 @@ if (CTEST_CMAKE_GENERATOR MATCHES "Visual Studio")
     "^ExternalProjectUpdateSetup$")
 endif ()
 
+if ("$ENV{CMAKE_CONFIGURATION}" MATCHES "_asan")
+  list(APPEND test_exclusions
+    CTestTest2 # crashes on purpose
+    BootstrapTest # no need to cover this for asan
+    )
+endif()
+
 string(REPLACE ";" "|" test_exclusions "${test_exclusions}")
 if (test_exclusions)
   set(test_exclusions "(${test_exclusions})")

+ 45 - 0
.gitlab/ci/ctest_memcheck.cmake

@@ -0,0 +1,45 @@
+cmake_minimum_required(VERSION 3.8)
+
+include("${CMAKE_CURRENT_LIST_DIR}/gitlab_ci.cmake")
+
+# Read the files from the build directory.
+ctest_read_custom_files("${CTEST_BINARY_DIRECTORY}")
+
+# Pick up from where the configure left off.
+ctest_start(APPEND)
+
+include(ProcessorCount)
+ProcessorCount(nproc)
+if (NOT "$ENV{CTEST_MAX_PARALLELISM}" STREQUAL "")
+  if (nproc GREATER "$ENV{CTEST_MAX_PARALLELISM}")
+    set(nproc "$ENV{CTEST_MAX_PARALLELISM}")
+  endif ()
+endif ()
+
+set(CTEST_MEMORYCHECK_TYPE "$ENV{CTEST_MEMORYCHECK_TYPE}")
+set(CTEST_MEMORYCHECK_SANITIZER_OPTIONS "$ENV{CTEST_MEMORYCHECK_SANITIZER_OPTIONS}")
+
+set(lsan_suppressions "${CMAKE_CURRENT_LIST_DIR}/ctest_memcheck_$ENV{CMAKE_CONFIGURATION}.lsan.supp")
+if (EXISTS "${lsan_suppressions}")
+  set(ENV{LSAN_OPTIONS} "suppressions='${lsan_suppressions}'")
+endif ()
+
+include("${CMAKE_CURRENT_LIST_DIR}/ctest_exclusions.cmake")
+ctest_memcheck(
+  PARALLEL_LEVEL "${nproc}"
+  TEST_LOAD "${nproc}"
+  RETURN_VALUE test_result
+  EXCLUDE "${test_exclusions}"
+  DEFECT_COUNT defects)
+ctest_submit(PARTS Test)
+ctest_submit(PARTS Memcheck)
+
+if (test_result)
+  message(FATAL_ERROR
+    "Failed to test")
+endif ()
+
+if (defects)
+  message(FATAL_ERROR
+    "Found ${defects} memcheck defects")
+endif ()

+ 1 - 0
.gitlab/ci/ctest_memcheck_fedora34_asan.lsan.supp

@@ -0,0 +1 @@
+# Add 'leak:<pattern>' lines here to suppress known leaks.

+ 1 - 0
.gitlab/ci/docker/fedora34/install_deps.sh

@@ -12,6 +12,7 @@ dnf install --setopt=install_weak_deps=False -y \
 # Install development tools.
 dnf install --setopt=install_weak_deps=False -y \
     clang-tools-extra \
+    compiler-rt \
     gcc-c++ \
     git-core \
     make

+ 2 - 0
.gitlab/ci/env_fedora34_asan.sh

@@ -0,0 +1,2 @@
+export CC=/usr/bin/clang
+export CXX=/usr/bin/clang++

+ 31 - 1
.gitlab/os-linux.yml

@@ -69,7 +69,7 @@
 ### Fedora
 
 .fedora34:
-    image: "kitware/cmake:ci-fedora34-x86_64-2021-06-03"
+    image: "kitware/cmake:ci-fedora34-x86_64-2021-06-07"
 
     variables:
         GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci/long file name for testing purposes"
@@ -158,6 +158,27 @@
         CMAKE_CONFIGURATION: debian10_makefiles_clang
         CMAKE_GENERATOR: "Unix Makefiles"
 
+### Sanitizers
+
+.fedora_memcheck:
+    variables:
+        CMAKE_BUILD_TYPE: RelWithDebInfo
+
+.fedora_asan_addon:
+    extends: .fedora_memcheck
+
+    variables:
+        CTEST_MEMORYCHECK_TYPE: AddressSanitizer
+        CTEST_MEMORYCHECK_SANITIZER_OPTIONS: ""
+
+.fedora34_asan:
+    extends:
+        - .fedora34
+        - .fedora_asan_addon
+
+    variables:
+        CMAKE_CONFIGURATION: fedora34_asan
+
 ### Intel Compiler
 
 .intelcompiler:
@@ -306,6 +327,15 @@
 
     interruptible: true
 
+.cmake_memcheck_linux:
+    stage: test
+
+    script:
+        - *before_script_linux
+        - "$LAUNCHER ctest --output-on-failure -V -S .gitlab/ci/ctest_memcheck.cmake"
+
+    interruptible: true
+
 .cmake_build_linux_release:
     stage: build
 

+ 78 - 56
Source/LexerParser/cmFortranParser.cxx

@@ -599,13 +599,13 @@ static const yytype_int8 yytranslate[] =
   /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
 static const yytype_uint8 yyrline[] =
 {
-       0,    99,    99,    99,   102,   106,   111,   120,   126,   133,
-     138,   142,   147,   155,   160,   165,   170,   175,   180,   185,
-     190,   195,   199,   203,   207,   211,   212,   217,   217,   217,
-     218,   218,   219,   219,   220,   220,   221,   221,   222,   222,
-     223,   223,   224,   224,   225,   225,   226,   226,   229,   230,
-     231,   232,   233,   234,   235,   236,   237,   238,   239,   240,
-     241,   242,   243,   244,   245
+       0,   101,   101,   101,   104,   108,   113,   122,   128,   135,
+     140,   144,   149,   157,   162,   167,   172,   177,   182,   187,
+     192,   197,   201,   205,   209,   213,   214,   219,   219,   219,
+     220,   220,   221,   221,   222,   222,   223,   223,   224,   224,
+     225,   225,   226,   226,   227,   227,   228,   228,   231,   232,
+     233,   234,   235,   236,   237,   238,   239,   240,   241,   242,
+     243,   244,   245,   246,   247
 };
 #endif
 
@@ -1364,7 +1364,29 @@ yydestruct (const char *yymsg,
   YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp);
 
   YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
-  YY_USE (yykind);
+  switch (yykind)
+    {
+    case YYSYMBOL_STRING: /* STRING  */
+#line 95 "cmFortranParser.y"
+            { free(((*yyvaluep).string)); }
+#line 1373 "cmFortranParser.cxx"
+        break;
+
+    case YYSYMBOL_WORD: /* WORD  */
+#line 95 "cmFortranParser.y"
+            { free(((*yyvaluep).string)); }
+#line 1379 "cmFortranParser.cxx"
+        break;
+
+    case YYSYMBOL_CPP_INCLUDE_ANGLE: /* CPP_INCLUDE_ANGLE  */
+#line 95 "cmFortranParser.y"
+            { free(((*yyvaluep).string)); }
+#line 1385 "cmFortranParser.cxx"
+        break;
+
+      default:
+        break;
+    }
   YY_IGNORE_MAYBE_UNINITIALIZED_END
 }
 
@@ -1634,26 +1656,26 @@ yyreduce:
   switch (yyn)
     {
   case 4: /* stmt: INTERFACE EOSTMT  */
-#line 102 "cmFortranParser.y"
+#line 104 "cmFortranParser.y"
                    {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_SetInInterface(parser, true);
   }
-#line 1643 "cmFortranParser.cxx"
+#line 1665 "cmFortranParser.cxx"
     break;
 
   case 5: /* stmt: USE WORD other EOSTMT  */
-#line 106 "cmFortranParser.y"
+#line 108 "cmFortranParser.y"
                         {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleUse(parser, (yyvsp[-2].string));
     free((yyvsp[-2].string));
   }
-#line 1653 "cmFortranParser.cxx"
+#line 1675 "cmFortranParser.cxx"
     break;
 
   case 6: /* stmt: MODULE WORD other EOSTMT  */
-#line 111 "cmFortranParser.y"
+#line 113 "cmFortranParser.y"
                            {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     if (cmsysString_strcasecmp((yyvsp[-2].string), "function") != 0 &&
@@ -1663,22 +1685,22 @@ yyreduce:
     }
     free((yyvsp[-2].string));
   }
-#line 1667 "cmFortranParser.cxx"
+#line 1689 "cmFortranParser.cxx"
     break;
 
   case 7: /* stmt: SUBMODULE LPAREN WORD RPAREN WORD other EOSTMT  */
-#line 120 "cmFortranParser.y"
+#line 122 "cmFortranParser.y"
                                                  {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleSubmodule(parser, (yyvsp[-4].string), (yyvsp[-2].string));
     free((yyvsp[-4].string));
     free((yyvsp[-2].string));
   }
-#line 1678 "cmFortranParser.cxx"
+#line 1700 "cmFortranParser.cxx"
     break;
 
   case 8: /* stmt: SUBMODULE LPAREN WORD COLON WORD RPAREN WORD other EOSTMT  */
-#line 126 "cmFortranParser.y"
+#line 128 "cmFortranParser.y"
                                                             {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleSubmoduleNested(parser, (yyvsp[-6].string), (yyvsp[-4].string), (yyvsp[-2].string));
@@ -1686,40 +1708,40 @@ yyreduce:
     free((yyvsp[-4].string));
     free((yyvsp[-2].string));
   }
-#line 1690 "cmFortranParser.cxx"
+#line 1712 "cmFortranParser.cxx"
     break;
 
   case 9: /* stmt: INTERFACE WORD other EOSTMT  */
-#line 133 "cmFortranParser.y"
+#line 135 "cmFortranParser.y"
                               {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_SetInInterface(parser, true);
     free((yyvsp[-2].string));
   }
-#line 1700 "cmFortranParser.cxx"
+#line 1722 "cmFortranParser.cxx"
     break;
 
   case 10: /* stmt: END INTERFACE other EOSTMT  */
-#line 138 "cmFortranParser.y"
+#line 140 "cmFortranParser.y"
                              {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_SetInInterface(parser, false);
   }
-#line 1709 "cmFortranParser.cxx"
+#line 1731 "cmFortranParser.cxx"
     break;
 
   case 11: /* stmt: USE DCOLON WORD other EOSTMT  */
-#line 142 "cmFortranParser.y"
+#line 144 "cmFortranParser.y"
                                {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleUse(parser, (yyvsp[-2].string));
     free((yyvsp[-2].string));
   }
-#line 1719 "cmFortranParser.cxx"
+#line 1741 "cmFortranParser.cxx"
     break;
 
   case 12: /* stmt: USE COMMA WORD DCOLON WORD other EOSTMT  */
-#line 147 "cmFortranParser.y"
+#line 149 "cmFortranParser.y"
                                           {
     if (cmsysString_strcasecmp((yyvsp[-4].string), "non_intrinsic") == 0) {
       cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
@@ -1728,139 +1750,139 @@ yyreduce:
     free((yyvsp[-4].string));
     free((yyvsp[-2].string));
   }
-#line 1732 "cmFortranParser.cxx"
+#line 1754 "cmFortranParser.cxx"
     break;
 
   case 13: /* stmt: INCLUDE STRING other EOSTMT  */
-#line 155 "cmFortranParser.y"
+#line 157 "cmFortranParser.y"
                               {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
     free((yyvsp[-2].string));
   }
-#line 1742 "cmFortranParser.cxx"
+#line 1764 "cmFortranParser.cxx"
     break;
 
   case 14: /* stmt: CPP_LINE_DIRECTIVE STRING other EOSTMT  */
-#line 160 "cmFortranParser.y"
+#line 162 "cmFortranParser.y"
                                          {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleLineDirective(parser, (yyvsp[-2].string));
     free((yyvsp[-2].string));
   }
-#line 1752 "cmFortranParser.cxx"
+#line 1774 "cmFortranParser.cxx"
     break;
 
   case 15: /* stmt: CPP_INCLUDE_ANGLE other EOSTMT  */
-#line 165 "cmFortranParser.y"
+#line 167 "cmFortranParser.y"
                                  {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
     free((yyvsp[-2].string));
   }
-#line 1762 "cmFortranParser.cxx"
+#line 1784 "cmFortranParser.cxx"
     break;
 
   case 16: /* stmt: include STRING other EOSTMT  */
-#line 170 "cmFortranParser.y"
+#line 172 "cmFortranParser.y"
                               {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
     free((yyvsp[-2].string));
   }
-#line 1772 "cmFortranParser.cxx"
+#line 1794 "cmFortranParser.cxx"
     break;
 
   case 17: /* stmt: define WORD other EOSTMT  */
-#line 175 "cmFortranParser.y"
+#line 177 "cmFortranParser.y"
                            {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleDefine(parser, (yyvsp[-2].string));
     free((yyvsp[-2].string));
   }
-#line 1782 "cmFortranParser.cxx"
+#line 1804 "cmFortranParser.cxx"
     break;
 
   case 18: /* stmt: undef WORD other EOSTMT  */
-#line 180 "cmFortranParser.y"
+#line 182 "cmFortranParser.y"
                           {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleUndef(parser, (yyvsp[-2].string));
     free((yyvsp[-2].string));
   }
-#line 1792 "cmFortranParser.cxx"
+#line 1814 "cmFortranParser.cxx"
     break;
 
   case 19: /* stmt: ifdef WORD other EOSTMT  */
-#line 185 "cmFortranParser.y"
+#line 187 "cmFortranParser.y"
                           {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleIfdef(parser, (yyvsp[-2].string));
     free((yyvsp[-2].string));
   }
-#line 1802 "cmFortranParser.cxx"
+#line 1824 "cmFortranParser.cxx"
     break;
 
   case 20: /* stmt: ifndef WORD other EOSTMT  */
-#line 190 "cmFortranParser.y"
+#line 192 "cmFortranParser.y"
                            {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleIfndef(parser, (yyvsp[-2].string));
     free((yyvsp[-2].string));
   }
-#line 1812 "cmFortranParser.cxx"
+#line 1834 "cmFortranParser.cxx"
     break;
 
   case 21: /* stmt: if other EOSTMT  */
-#line 195 "cmFortranParser.y"
+#line 197 "cmFortranParser.y"
                   {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleIf(parser);
   }
-#line 1821 "cmFortranParser.cxx"
+#line 1843 "cmFortranParser.cxx"
     break;
 
   case 22: /* stmt: elif other EOSTMT  */
-#line 199 "cmFortranParser.y"
+#line 201 "cmFortranParser.y"
                     {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleElif(parser);
   }
-#line 1830 "cmFortranParser.cxx"
+#line 1852 "cmFortranParser.cxx"
     break;
 
   case 23: /* stmt: else other EOSTMT  */
-#line 203 "cmFortranParser.y"
+#line 205 "cmFortranParser.y"
                     {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleElse(parser);
   }
-#line 1839 "cmFortranParser.cxx"
+#line 1861 "cmFortranParser.cxx"
     break;
 
   case 24: /* stmt: endif other EOSTMT  */
-#line 207 "cmFortranParser.y"
+#line 209 "cmFortranParser.y"
                      {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleEndif(parser);
   }
-#line 1848 "cmFortranParser.cxx"
+#line 1870 "cmFortranParser.cxx"
     break;
 
   case 48: /* misc_code: WORD  */
-#line 229 "cmFortranParser.y"
+#line 231 "cmFortranParser.y"
                       { free ((yyvsp[0].string)); }
-#line 1854 "cmFortranParser.cxx"
+#line 1876 "cmFortranParser.cxx"
     break;
 
   case 55: /* misc_code: STRING  */
-#line 236 "cmFortranParser.y"
+#line 238 "cmFortranParser.y"
                       { free ((yyvsp[0].string)); }
-#line 1860 "cmFortranParser.cxx"
+#line 1882 "cmFortranParser.cxx"
     break;
 
 
-#line 1864 "cmFortranParser.cxx"
+#line 1886 "cmFortranParser.cxx"
 
       default: break;
     }
@@ -2085,6 +2107,6 @@ yyreturn:
   return yyresult;
 }
 
-#line 248 "cmFortranParser.y"
+#line 250 "cmFortranParser.y"
 
 /* End of grammar */

+ 2 - 0
Source/LexerParser/cmFortranParser.y

@@ -92,6 +92,8 @@ static void cmFortran_yyerror(yyscan_t yyscanner, const char* message)
 %token SUBMODULE
 %token USE
 
+%destructor { free($$); } WORD STRING CPP_INCLUDE_ANGLE
+
 /*-------------------------------------------------------------------------*/
 /* grammar */
 %%