From fda060f030f57c52028d38985edc95a74d0243a5 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 7 Jun 2021 19:48:42 -0400 Subject: LexerParser: Do not leak Fortran parser tokens discarded due to errors --- Source/LexerParser/cmFortranParser.cxx | 134 +++++++++++++++++++-------------- Source/LexerParser/cmFortranParser.y | 2 + 2 files changed, 80 insertions(+), 56 deletions(-) diff --git a/Source/LexerParser/cmFortranParser.cxx b/Source/LexerParser/cmFortranParser.cxx index 0ea3d97..3f3ddde 100644 --- a/Source/LexerParser/cmFortranParser.cxx +++ b/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 */ diff --git a/Source/LexerParser/cmFortranParser.y b/Source/LexerParser/cmFortranParser.y index e461160..a3e1c24 100644 --- a/Source/LexerParser/cmFortranParser.y +++ b/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 */ %% -- cgit v0.12 From 19d831b03d2c3921c19f07a94fce4f7b678f0afa Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 7 Jun 2021 15:09:05 -0400 Subject: ci: add compiler-rt to Fedora base image This is needed for `clang -fsanitize=` flags. --- .gitlab/ci/docker/fedora34/install_deps.sh | 1 + .gitlab/os-linux.yml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitlab/ci/docker/fedora34/install_deps.sh b/.gitlab/ci/docker/fedora34/install_deps.sh index 7d099fe..146d51f 100755 --- a/.gitlab/ci/docker/fedora34/install_deps.sh +++ b/.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 diff --git a/.gitlab/os-linux.yml b/.gitlab/os-linux.yml index 015df4f..17f51cf 100644 --- a/.gitlab/os-linux.yml +++ b/.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" -- cgit v0.12 From 20bc209a0c61ec59912b0c2b082ed43a080905bc Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 7 Jun 2021 14:30:08 -0400 Subject: gitlab-ci: add clang asan job --- .gitlab-ci.yml | 25 +++++++++++++ .gitlab/ci/configure_fedora34_asan.cmake | 4 ++ .gitlab/ci/ctest_exclusions.cmake | 7 ++++ .gitlab/ci/ctest_memcheck.cmake | 45 +++++++++++++++++++++++ .gitlab/ci/ctest_memcheck_fedora34_asan.lsan.supp | 1 + .gitlab/ci/env_fedora34_asan.sh | 2 + .gitlab/os-linux.yml | 30 +++++++++++++++ 7 files changed, 114 insertions(+) create mode 100644 .gitlab/ci/configure_fedora34_asan.cmake create mode 100644 .gitlab/ci/ctest_memcheck.cmake create mode 100644 .gitlab/ci/ctest_memcheck_fedora34_asan.lsan.supp create mode 100644 .gitlab/ci/env_fedora34_asan.sh diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 236eac9..754b2a1 100644 --- a/.gitlab-ci.yml +++ b/.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: diff --git a/.gitlab/ci/configure_fedora34_asan.cmake b/.gitlab/ci/configure_fedora34_asan.cmake new file mode 100644 index 0000000..c22cdb7 --- /dev/null +++ b/.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") diff --git a/.gitlab/ci/ctest_exclusions.cmake b/.gitlab/ci/ctest_exclusions.cmake index b885a6a..3460d48 100644 --- a/.gitlab/ci/ctest_exclusions.cmake +++ b/.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})") diff --git a/.gitlab/ci/ctest_memcheck.cmake b/.gitlab/ci/ctest_memcheck.cmake new file mode 100644 index 0000000..dac907c --- /dev/null +++ b/.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 () diff --git a/.gitlab/ci/ctest_memcheck_fedora34_asan.lsan.supp b/.gitlab/ci/ctest_memcheck_fedora34_asan.lsan.supp new file mode 100644 index 0000000..8ec1a03 --- /dev/null +++ b/.gitlab/ci/ctest_memcheck_fedora34_asan.lsan.supp @@ -0,0 +1 @@ +# Add 'leak:' lines here to suppress known leaks. diff --git a/.gitlab/ci/env_fedora34_asan.sh b/.gitlab/ci/env_fedora34_asan.sh new file mode 100644 index 0000000..e976486 --- /dev/null +++ b/.gitlab/ci/env_fedora34_asan.sh @@ -0,0 +1,2 @@ +export CC=/usr/bin/clang +export CXX=/usr/bin/clang++ diff --git a/.gitlab/os-linux.yml b/.gitlab/os-linux.yml index 17f51cf..997beab 100644 --- a/.gitlab/os-linux.yml +++ b/.gitlab/os-linux.yml @@ -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 -- cgit v0.12